#bevy_hanabi

1 messages ยท Page 3 of 1

mild bluff
#

Actually I'm not finding this field:

pub struct CompiledParticleEffect {
    /// Handle to the underlying asset.
    asset: Handle<EffectAsset>,
    /// Cached simulation condition, to avoid having to query the asset each
    /// time we need it.
    simulation_condition: SimulationCondition,
    /// A custom mesh for this effect, if specified.
    mesh: Option<Handle<Mesh>>,
    /// Handle to the effect shaders for his effect instance (one per group), if
    /// configured.
    effect_shaders: Vec<EffectShader>,
    /// Textures used by the effect, if any.
    textures: Vec<Handle<Image>>,
    /// 2D layer for the effect instance.
    #[cfg(feature = "2d")]
    z_layer_2d: FloatOrd,
    /// Layout flags.
    layout_flags: LayoutFlags,
    /// Alpha mode.
    alpha_mode: AlphaMode,
}
native elbow
#

Sorry it's on EffectSpawner my bad

#

Just make sure to overwrite after the TickSpawners or TickInitializers (depending on version) system set

mild bluff
#

Ah cool. I did a ctrl+f for it in the files I had open but didn't have the right one open

#

Whoa, so do I have to grab the EffectInitializers off my entity (which gets inserted onto it in tick_initializers)... then for each initializer that's a EffectSpawner, modify its spawn_count. And if I have to do it after TickInitializers, I have to put it in PostUpdate?

native elbow
#

Yes

weary abyss
still mirage
#

Does orient along velocity work for 2d particles?

still mirage
#

i ended up writing a custom render modifier

marsh walrus
#

Is there any way to write a modifier that applies a linear transformation to all the vertices in a particle?
It seems like the Attribute::POSITION is the position of the entire particle?

weary abyss
#

@native elbow are you working on 0.16 support? it's right around the corner. no rush, just curious ๐Ÿ™‚

marsh walrus
#

On the github README it claims that there is already support for stretching a particle alongside velocity, but I can't for the life of me find a modifier (or any other construct / function) that would let me do that.
Can anyone point me in the right direction?

weary abyss
native elbow
#

Just published 0.15 with all major changes since 0.14, still compatible with Bevy 0.15. This means now we can merge support for Bevy 0.16 to main

fluid brook
#

there a way to spawn particles in set positions?
I'd like to spawn them on the circumference of a circle, but not at random, more like equal distances apart

fluid brook
fluid brook
native elbow
native elbow
#

There's Attribute::ID but it's not necessarily contiguous so would be hard to distribute over the circle based on that.

#

Although conceptually it's pretty easy to get a "spawn ID" since it can be mapped 1:1 to the compute thread. So please do open some GitHub feature request @fluid brook ๐Ÿ™‚

native elbow
# weary abyss Thank you!

Didn't you have a 0.16 branch already? I thought I saw some notification, but can't find anything now

weary abyss
#

I don't

native elbow
#

Ok I'll try to have a look when I have time

native elbow
#

I have most build error fixed (not sure it's correct, but seems ok), except that all the render phase items again completely changed, so I'm going to need to dig into that and understand how to convert from 0.15 to 0.16.

weary abyss
fluid brook
# native elbow That's an interesting one. I'm not sure there's a way to identify a particle _wi...

it's not that I don't want them spawning in the same position, I do however want more control on where they spawn so I can have them evenly spread, and not look so random all the time.
Just being able to set the seed would be enough, since I could then go through the seeds one by one until I find one I like: and sounds like it would be an easier solution and in general just a nice thing to be able to do (if you can't already and I just don't know how)

native elbow
#

Maybe EffectAsset::prng_seed then?

fluid brook
#

even if that's not the case yeah, I set it, ran an effect a few times and got varying results so

weary abyss
#

@native elbow btw re your comment, I was thinking the Unity exporter might want to have a "compose" feature that detects the "spawn invisible particles that then trigger subemitters" pattern and then compiles them into a single Hanabi particle effect

#

this would be more work, but would be more efficient and would avoid the need for on-spawn emitters

#

My studio's VFX artists do make particles that are not invisible and create subemitters on spawn though. So we would have to have some other solution for that. I think maybe supplying a PRNG seed as a property would suffice to ensure that K particle groups spawn N particles at exactly the same place?

native elbow
#

I'm not sure

#

BTW I looked at the new binning code in the Bevy renderer in 0.16, this has increased about 10x in complexity. Initial estimate is many-weeks before Hanabi can be ported. I'm even considering rewriting an entire renderer as a workaround rather than trying to understand the Bevy code.

still mirage
native elbow
#

The render items have different fields and there's no docs. Trying to reverse engineer how things are supposed to be used, and it was already quite complex for 0.15, but it's even worse in 0.16

still mirage
#

dang, maybe you could request the 0.15 -> 0.16 migration guide ahead of time, assuming they're putting that together now

west hazel
graceful cape
#

After upgrade to version 0.15 warnings appear every time spawner is created "Updated metadata entry 3 for effect 3871v6#25769807647, this will reset it." . What can be done to correct these warnings?

tidal violet
native elbow
#

The render phase items like Transparent2d for example. They have multiple changes. I've looked at the PR and the code, I don't know what's going on. There's multiple levels of indirections with some new caching based on Ticks, for which I have no idea what I'm supposed to do because I don't want the renderer to cache anything, I doubt it makes any sense for Hanabi.

#

Release notes say to set the BatchSetKey to () so at least that's one of the info I didn't have.

#

There's also something about GPU culling being ON by default, I'm guessing this will have some effect and require a change because I doubt Hanabi effects can run through the GPU culling code, as they're not really mesh-based render items. But I don't know how to disable.

native elbow
#

List of issues:

  • Transparent2d has new extracted_index and indexed fields
  • Transparent3d has new indexed field
  • OpaqueNoLightmap3dBinKey lost all its field, instead has some asset_id (???)
  • BinnedRenderPhase<T>::add() has new arguments, in particular input_uniform_index and change_tick

There's a u/bevy16 branch with all the changes I could make, and the above issues unfixed, here : https://github.com/djeedai/bevy_hanabi/compare/u/bevy16?expand=1 if someone has time to have a look and understands the above?

quasi wharf
# native elbow List of issues: - `Transparent2d` has new `extracted_index` and `indexed` fields...

the required tick argument for the retained bins on the binned phase will probably the most difficult to work around in the case you don't want any caching (which makes sense i imagine for what you're doing) i think the simplest thing would just be to provide the current tick of the queueing system your in, which would effectively invalidate the bin each frame. i'll take a look at your branch later

native elbow
#

Thanks @quasi wharf! I assume this is the case indeed. I think one of the examples does something similar maybe? I saw some code fetching the system tick and overwriting each frame.

#

To be honest I'm not even sure whether I don't want caching because I don't know what's cached.

quasi wharf
# native elbow Thanks <@830984649668165633>! I assume this is the case indeed. I think one of t...

basically we use the last time an entity changed in a way that would invalidate the bin key as a quick check to avoid re-building the bins. so in the fast path, let's say for a totally static mesh/material, we no longer have to re-specialize the pipeline or queue the entity into the render phase at all, because if none of the entities in the bin have changed then the bin is up to date and we can just draw it. i think this might actually make sense for hanabi? because once an effect is spawned, it's "static" relative to things that would require a pipeline change over its duration, right?

native elbow
#

Yes, but wasn't the bin used to render back to front? I'm confused what they're sorting for?

weary abyss
#

Bins were never used to render back to front

#

The reason why we sort is to reduce state changes by putting objects with similar vertex buffers/etc together

#

Just re-extract everything every frame for now. I don't expect there will be enough particle effects around to warrant retention anytime soon

weary abyss
#

@native elbow If you need to sort particle effects back to front, you should probably use a SortedRenderPhase instead of a binned one. As an added bonus, SortedRenderPhase has barely changed since 0.15 so you won't have to update as much

native elbow
#

Transparent effects use SortedRenderPhase and opaque/alphamask ones use BinnedRenderPhase

weary abyss
#

Sounds good

weary abyss
#

e.g. BinnedPhaseItem and SortedPhaseItem now have docs for all their methods, as does every field on BatchSetKeys and BinKeys

native elbow
#

Most docs describe what the functions are doing, which is easy to guess from reading the code. Most docs do not describe why the functions are doing what they're doing nor how you're supposed to use them.

#

The specialized_mesh_pipeline.rs does help a bit though. Although it's still using the SpecializedMeshPipelines so doesn't show the truly generic case where you use your own pipeline. But I guess that's more rare.

proud basin
#

how can i get different usages of the same effect to spawn in different patterns? or do i have to create a new effect every time? SetPositionCircleModifier is producing the same positions always

weary abyss
#

@native elbow The new particle events system doesn't support spawning a particle every N frames, so worms isn't the same as before.

New proposal: Could I add a burst delay so that events are emitted at a fixed rate? I need this. If yes, and the initial delay was customizable, this would make the OnSpawn condition that you don't like unnecessary, as you could just set the initial delay to 0 and the burst delay to infinity. (Also our VFX artists are using OnSpawn for other things that can't be easily replicated in other ways so I do need something like OnSpawn)

Alternate proposal: Allow events to be tied to an Attribute so that an event is emitted when the Attribute is equal to some value. Then you could write whatever logic you want.

native elbow
#

Are you talking about GPU spawn events? Because the CPU spawner does support burst rate.

I suppose we can add some EmitCondition that does emit similar to the CPU spawner, at constant rate and possibly with bursts.

I like the idea of an expression for the event condition. But I'm afraid there's some missing casts or functions to handle an integral expression. I don't like the "equal an attribute" because most attributes are floating point and that means FP equality, which is a can of worms.

Also are you reallt asking for "every N frames" and not "every N seconds"?

weary abyss
#

If you think that having an expression is fine then I can implement that

weary abyss
#

@native elbow Aha, I looked up the way Unity suggests to do it: https://discussions.unity.com/t/gpuevent-trigger-once-at-birth/779939/2

It's quite simple. You just make the number of particles to be spawned in the event an ExprHandle instead of a constant. Then you can implement whatever you like.

I like this idea, it should be very simple to implement and then I won't have to bug you anymore ๐Ÿ™‚

weary abyss
native elbow
#

Looks good but it's a breaking change so for 0.16

weary abyss
weary abyss
#

@native elbow Would you like help with the 0.16 upgrade? If so, is the 0.16 branch up to date with your latest work?

native elbow
#

Yes and yes. The branch runs but there's no graphics, needs to be debugged. Thanks!

weary abyss
weary abyss
#

There seems to be an issue with init_fill_dispatch_args when you have more than 2 copies of an effect. I'm investigating

#

The coalescing code appears to be wrong

weary abyss
#

@native elbow I've found about 3 different bugs so far with the combination of multiple particle effects and events ๐Ÿ™‚ Working on patches for each of them

#

I think I know the cause in each case

weary abyss
#

@native elbow Submitted fixes for all of them: #447, #448, #449

native elbow
#

I don't understand, the ribbon.rs effect has 2 instances already and is fine. Are you saying it fails from 3 instances? ๐Ÿค”

weary abyss
#

Note that the particle system in question has 3 separate particle effects, one of which emits child events. Spawning 2/3/4 copies of the whole system is what caused the problem. So it's really 6/9/12 effects that triggered those bugs.

native elbow
#

๐Ÿ˜ตโ€๐Ÿ’ซ

weary abyss
#

@native elbow Also despawning a particle system is broken, multiple crashes. I'll investigate

weary abyss
#

The crash happens when you spawn instance 0 of an effect A, spawn another instance 1 of that effect A, then despawn instance 0

#

Hanabi could really use some stress testing, because just spawning and despawning 1 or 2 particle effects at once isn't enough to uncover bugs

#

actually using it in a game, though, with effects created by VFX artists, instantly uncovers these things

#

It only seems to happen with complex effects with multiple event emitters

#

This one is a combination of 11 different EffectAssets, which is not uncommon for things VFX artists make

weary abyss
#

The problem seems to be that the is_child_list_changed check that skips the update of CachedParentInfo is insufficient sometimes. Commenting it out makes the crash no longer happen. I suspect the problem occurs when you have parent -> child -> grandchild and despawn them in some order

weary abyss
weary abyss
#

Bad news, just hit another Hanabi crash bug ๐Ÿ™‚

weary abyss
#

There's also some kind of rare race between mesh loading and particle loading that causes a Hanabi crash on startup occasionally.

weary abyss
gilded fox
junior glen
#

@native elbow I've got probably very basic question after getting back into Hanabi. I've tried adding a basic effect by just copy-pasting the code from the readme into my 3D app and it looks like this:

#

As you can see, the big white particles work great, but for some reason, my crosshair is snowing ๐Ÿ˜… You can see the effect towards the end

#

I think this may be due to me having 3 cameras active in this level?

#

Oh, RenderLayers, got it

junior glen
#

Another thing: when creating a new effect, I get this warning, even on the examples:

#

2025-04-17T23:31:31.849161Z WARN bevy_hanabi::render: Updated metadata entry 0 for effect 13v1#4294967309, this will reset it.

#

That's not bad, right? Seems alright that the metadata for a new effect would be "updated" and "reset"

#

I just wonder whether I can do anything to not have a scary warning when starting my app

native elbow
junior glen
#

It's not a big deal, but I try to keep all warnings meaningful

native elbow
junior glen
#

thanks ๐Ÿ™‚

native elbow
#

I also hate this kind of warning, sorry. Being a bad citizen here ๐Ÿ˜•

native elbow
gilded fox
weary abyss
#

got two new effects from the VFX artists and both made Hanabi fall over

#

eventually we'll hopefully get to a point where I get an effect and Hanabi can actually render it without fixing bugs in Hanabi ๐Ÿ™‚

#

btw, one thing I've been unsure about is the ping/pong thing... I'm not sure why that's done. Is it just an optimization to avoid reading from and writing to the same GPU memory in the same shader? I'm not convinced that actually helps on modern GPUs, and it adds complexity

weary abyss
#

Fixed one race: if the asset doesnโ€™t load in one frame, then we can fail to load it at all in some circumstances. Iโ€™ll submit a PR once I fix the other bug

weary abyss
native elbow
#

I hate it but couldn't find a better way at the time. Maybe now there's a better way though, as things changed quite a bit since this was first written.

native elbow
#

Just FYI for everyone, the plan for the next week(s) is:

  • Merge the fix from Nico Zweifel (https://github.com/djeedai/bevy_hanabi/pull/457) about stale mesh references
  • Confirm with @weary abyss that the fix in merged in #458 indeed supersedes the open PRs #448 and #449, and discard those PRs.
  • Release 0.16.0 (still Bevy 0.15), because there's like 4 or 5 large bugs in 0.15 so it's a bit too rough, and I don't want to force people to upgrade Bevy just to get a working version. I had hoped to release a 0.15.1 patch, but unfortunately the change for the emit count as expression is a breaking change, so 0.16.0 it is.
  • Merge the u/bevy16 branch for Bevy 0.16 support, with the fix from #453
  • Release 0.17.0 with Bevy 0.16 support once that's available.
#

Alternatively I might revert #444 (GPU event count as expression) so we can do a patch release, and re-apply that change after. Not sure yet.

weary abyss
#

@native elbow Smoke test in my project suggests that #458 indeed works. Thanks!

native elbow
#

Superb, thanks for confirming!

native elbow
#

Released v0.15.1 with the accumulated fixes from the past few weeks.
#crates message

misty aurora
#

Hi,
I have some code that works on Hanabi 0.14 but fails on 0.15.1.

#

I am getting this error since the update

   WARN bevy_ecs::world: error[B0003]: /home/lyndonm/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bevy_hierarchy-0.15.3/src/hierarchy.rs:49:19: Could not despawn entity 263799v4#17180132983 because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003
    at /home/lyndonm/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bevy_ecs-0.15.3/src/world/mod.rs:1532

   WARN bevy_ecs::world: error[B0003]: /home/lyndonm/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bevy_hierarchy-0.15.3/src/hierarchy.rs:49:19: Could not despawn entity 263800v1#4295231096 because it doesn't exist in this World. See: https://bevyengine.org/learn/errors/b0003
    at /home/lyndonm/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bevy_ecs-0.15.3/src/world/mod.rs:1532

   WARN bevy_hanabi::render: Updated metadata entry 0 for effect 267754v86#369367455210, this will reset it.
    at /home/lyndonm/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bevy_hanabi-0.15.1/src/render/mod.rs:4078

   WARN bevy_hanabi::render: Updated metadata entry 1 for effect 267755v1#4295235051, this will reset it.
    at /home/lyndonm/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/bevy_hanabi-0.15.1/src/render/mod.rs:4078

Screenshot is the diff of my changes in making the update

native elbow
#

The error you pasted says you're (or Hanabi? Can't tell from the logs) trying to despawn an Entity that doesn't exist. Unless there's a callstack pointing to Hanabi, this looks like a user error unrelated to Hanabi.

#

And the code you pasted is about spawning so I don't see how it's related to the error, as that code shouldn't trigger any Entity despawning.

junior glen
native elbow
#

Well yes, kind of. It sure works around. But that doesn't change the fact the code pasted above spawns a new VFX, so I don't see how it's related to some despawning error? ๐Ÿค”

misty aurora
#

Is the metadata error unrelated to Hanabi?
I think I can figure out the despawn error but the metadata one seems to be for different entites.
I assume thats the one thats actually breaking my animation.

native elbow
#

Ignore the metadata warning. And it's a warning not an error.

#

It simply says the data for that effect was re-uploaded so that will reset the effect. That's perfectly normal on spawn. It can lead to artifacts if you get that later on an already spawned effect. Unfortunately this requires a bit of a design change to fix, so I left the warning for now.

misty aurora
#

Thanks knowing that metadata is not important is helpful

ember pumice
#

Popped in here just to check on that haha

gilded fox
#

How close is hanabi to having a bevy 0.16 version?

white siren
native elbow
#

I didn't publish to crates.io because after removing the bevy_egui dependency from examples (due to licensing question), and simplifying the examples to just depend on all Bevy, it appeared that there's a couple of artifacts in examples, I assume due to the fact depending on Bevy entirely changes the timings etc. in the frame. Now, I suspect those are the same issue(s) already logged for some time, so not really a regression, but I didn't have time to investigate I didn't want to add some approval seal by publishing when I know there's issues.

#

As said above, workaround is to depend on git branch main for now.

junior glen
native elbow
junior glen
junior glen
gilded fox
simple falcon
#

I'm new to playing with 3D particles. Does Hanabi let me calculate if a particle collides, or at least gets within a certain radius, of another entity? I've been recreating fps weapons, and am currently working on a flamethrower.

#

Never mind. I just saw that that's a feature that's still being worked on, according to the README.

#

In that case, anything I can do to help?

true kayak
#

I have a basic bevy_hanabi question: I want to spawn an effect everytime there is a collision. I can spawn a new effect with a handle, but it does not appear there is any kind of built-in "effect lifetime" to cleanup old effects. should I manually despawn the old entities? ( doesnt seem to be mentioned anywhere and seems important)

#

There is a sample spawn_on_commands.rs, this seems to reset effect_spawner ... not sure is this effect specific or some kind of global effect spawner. Thanks for any insight

#

I think this is resetting that specific effect entity - which should work for my needs - will give that a try ๐Ÿ™‚

native elbow
# simple falcon Never mind. I just saw that that's a feature that's still being worked on, accor...

Efficient particle collision is a complex topic. The two most common solutions are simple analytical geometry only (e.g. a box) which is quite limited, and depth-buffer based solutions, which also have issues. Iโ€™d like to try the later but I donโ€™t even know at the minute where/how to grab that depth buffer from Bevy, and it might require changing the order of some Hanabi passes etc. which is a bunch of work unfortunately.

native elbow
#

The reason itโ€™s optimal is that the effect instances in the pool retain their GPU allocations, pipelines, shaders, etc. So thereโ€™s close to 0 cost just in-hiding one. As opposed to spawning a new entity and component, where Hanabi has to redo all the work of allocating various caches etc. for that instance.

fluid brook
#

how can I get a new particle effect to spawn particles randomly?
Right now every time I fire a bullet, a spawn an entity with ParticleEffect::new(effect_asset_handle.clone())
the effect itself then spawns 10 particles once with SetPositionCircleModifier, but they're always in the same position.
is there a way to get them to spawn randomly each time?
I'm pretty sure I had another project where they did but I was reusing the same ParticleEffect with reset() - is making a new ParticleEffect each time just a bad idea orrr

fluid brook
#

okay yeah spawning a new particleeffect each time lags the game pretty fast

native elbow
#

There were changes to the PRNG recently. If I recall correctly thereโ€™s a seed field on the effect? Set that to a random value

fluid brook
native elbow
#

CompiledParticleEffect::prng_seed

#

The component is on the same entity as the ParticleEffect

fluid brook
#

oh I checked that but couldn't find a way to set it

native elbow
#

Yes, the asset field is copied to the CompiledParticleEffect by default

#

Oh sorry itโ€™s private indeed. We shoudl fix this

fluid brook
#

it's not a big deal anymore since I've added multiple particle effects so it's harder to tell now
I also stopped spawning a branch new entity with ParticleSpawner on it, and instead added some child entities with the spawners on them and it's no longer lagging surprise surprise xD

#

less laggy susge we'll see

native elbow
gilded fox
#

What could cause a specified lifetime to... not work at all?

#

Here's a gist of my function:
https://gist.github.com/Rabbival/8d66f356db98c9b05a7eb3ee1f77a903

I can't for the life of me figure out what's wrong with it (been trying to figure that out for the last 5 hours or so)
The consts:

pub const GOLDEN_WASTE_PARTICLES_SPAWN_RADIUS: f32 = 12.0;
pub const GOLDEN_WASTE_PARTICLES_PER_CARD: f32 = 16.0;
pub const GOLDEN_WASTE_PARTICLE_SIZE: f32 = 8.0;
pub const GOLDEN_WASTE_BURST_DURATION: f32 = 0.2;
pub const GOLDEN_WASTE_PARTICLES_LIFETIME: f32 = 0.4;

(I don't think it matters really but maybe I did something illegal and didn't realize?)

Gist

GitHub Gist: instantly share code, notes, and snippets.

gilded fox
#

๐Ÿ˜…

#

They won't despawn

#

Like, the lifetime feature doesn't work

fluid brook
gilded fox
#

1024

#

I didn't think I should set it because it worked for other particle effects by just setting the lifetime

#

This is a valid solution though I guess

#

Thanks

fluid brook
#

wait what, what solved it

#

what just happened xD

gilded fox
#

lmao

#

I don't know if it would solve it because it's still compiling but I assume if the max particles is set to the number of particles in the burst then

#

oh nvm that wouldn't help at all

#

sorry my brain is tired

#

been working on it for a few hours now

fluid brook
#

if that does fix it and in case it's not been reported already - @native elbow

gilded fox
#

Compiling now, it'll take a few minutes
If it works that would make sense, I think the only difference between these particles and the others is that this is the only time I didn't change their colors

#

That did it! Thanks a lot!
@fluid brook

native elbow
#

lifetime doesn't work without age. if nothing adds the Attribute::AGE, then there's nothing to compare the Attribute::LIFETIME to.

gilded fox
#

So I should add an age attribute manually

native elbow
#

Normally it's added by default I think but it's possible to not have it. Look at trace-level logs there's a line showing the layout of your particle effect, something like (+0) age, (+4) position, etc.

native elbow
gilded fox
#

Alright
Thanks!

#

That did it!

native elbow
#

Yeah, I think I've hit that one in the past.

gilded fox
#

One of the problems of the support channel being under ecosystem-crates is that there's no way to search things specifically for hanabi
At least I didn't find one

native elbow
#

It's a bit annoying because AGE without LIFETIME can be useful, but LIFETIME without AGE rarely, and in both cases for other things than just particle death. But for particle death itself, you need both, or at least ideally we'd need AGE alone (with a fixed lifetime shared by all particles; not implemented). But in all cases LIFETIME alone won't do anything for particle death.

gilded fox
#

I did try looking for related past issues and didn't find any

native elbow
#

I don't think there is.

#

I hit that myself on an example I think while developping.

#

There's probably an example comment somewhere mentioning this, but that's not super clear I agree

gilded fox
#

I should take this opportunity to thank you both for making and maintaining the crare and providing constant support on this channel

#

Like

#

Honestly my game wouldn't look as good without it

native elbow
#

Thanks!

gilded fox
#

look at em go

gilded fox
#

I'm trying to make it add an age attribute when lifetime is added but age not
However
Whenever I cargo test the IDE crashes

gilded fox
native elbow
#

I'm not convinced that we should do that

fluid brook
fluid brook
gilded fox
#

It still lets you have age without lifetime

#

I tried to make it like a required component, added automatically but not coupled

gilded fox
native elbow
#

Because (at least I thought) there's already a way to enable/disable aging (AGE += dt) and reaping (alive = AGE < LIFETIME), similar to what Unity is doing : https://docs.unity3d.com/Packages/[email protected]/manual/Reference-Attributes.html#age-lifetime-and-alive
And so the attributes themselves shouldn't depend on each other and control those things, otherwise it's confusing there's 2 sources of truth for the same thing. And if you disable reaping, then LIFETIME adds AGE for nothing, and you waste GPU RAM.

gilded fox
#

I'm not sure what reaping is, but if you don't need age then you don't need lifetime either

#

Anyway, I thought it might be good to prevent future bugs but in the end of the day it's your crate- do what you feel is right

fluid brook
#

if there's a way to use lifetime without age (like an actual use case) then yeah sure I get it, I just didn't know that existed

native elbow
#

The real issue is that now the aging and reaping are auto-decided based on the presence of attributes or not. This is highly confusing because e.g. removing a ColorOverLifetimeModifier attribute, which is supposed to only change the rendering, now suddenly breaks the effect or not depending on whether another modifier has added the AGE and LIFETIME. This kind of random side-effect changes are very hard to understand. Instead the Unity approach makes more sense: if you want aging/reaping, just configure your effect for it. And then, that in turn will add the required attribute(s).

gilded fox
#

I'm trying to figure out how to make a "slow motion" effect for the particles. Since I couldn't find a way to manipulate delta_time, I figured I should use AccelModifier::via_property() but couldn't find an example as to how it should be used. I did see in the examples that properties can be set by their name, but I'm missing this one last step to connect these two ends (meaning, enabling setting the accel modifier after the effect has been created and spawned)

gilded fox
#

I just realized I'll also have to change the AGE report
So I probably have no way around changing delta_time, if that's even possible

native elbow
#

Do you slow-mo only particles or all game?

#

I never tried, but whoever contributed the latest time changed added some Time<EffectSimulation> so if you mess with that clock, and in particular its relative speed, I think this should work

#

There's a set_relative_speed() impl from the EffectSimulationTime helper trait which allows changing it

#

So something like time: ResMut<Time<EffectSimulation>> and time.set_relative_speed(0.2) for 20% speed

gilded fox
native elbow
#

This is a bit unexpected because Time<EffectSimulation> is based on VirtualTime so should slow down with it

native elbow
#

Unless you're not slowing down VirtualTime? But you probably should impl slow-mo that way

gilded fox
gilded fox
#

I couldn't find a way to scale the time for a single particle effect (it seems that the one you linked slows them all down)

#

(That's still better than nothing
Thanks)

snow cedar
#

hi, is there a way to change the particle from a square to a circle?

#

nvm i figured out with the round modifier

snow cedar
#

i tried the following:

    let color = SetAttributeModifier::new(
        Attribute::COLOR,
        writer
            .prop(color)
            .cast(VectorType::VEC3F)
            .vec4_xyz_w(
                writer.prop(color).w()
                    * (writer.lit(1.)
                        - (writer.attr(Attribute::AGE) / writer.attr(Attribute::LIFETIME))),
            )
            .pack4x8unorm()
            .expr(),
    );
snow cedar
#

i found an ugly solution:

let color = SetAttributeModifier::new(
        Attribute::COLOR,
        writer
            .prop(color)
            .x()
            .vec3(writer.prop(color).y(), writer.prop(color).z())
            .vec4_xyz_w(
...
``` But I think there should be those swizzle functions that wgsl offers, like writer.prop(color).xyz()
native elbow
#

Yes feel free to open a GiHub issue. Swizzle are annoying to implement because of the large number of combinations to support, but I appreciate theyโ€™re quite useful.

waxen kettle
#

So I have found that the wasm target disclaimer here is not entirely accurate, it's not that the serde library itself does not work in wasm, but rather that the Hanabi + Serde libraries together cause problems.

I mention this because I use the serde library to load my levels at runtime on web and I had never noticed issues before.

I am building using target wasm32-unknown-unkown and I only run into issues later when running wasm-bindgen

native elbow
waxen kettle
#

Hmm maybe I will try to mess around a bit more with it then, the compilation step seemed to work well only the wasm-bindgen command would actually fail with something within Hanabi

native elbow
#

bindgen usually fails on mismatching version. Bevy itself requires a very specific version, itโ€™s possible it changed in 0.16 and I didnโ€™t update Hanabi for it

junior glen
#

@native elbow nightly is telling me this

#

looks like something just became a new warning

lament basalt
#

hello! I'm not in the loop atm, but I don't see an issue, so hopefully it's my fault. I cannot get bevy_hanabi to run with webgl:

thread 'main' panicked at /home/main/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasm-bindgen-wasm-interpreter-0.2.100/src/lib.rs:245:21:
bevy_hanabi::modifier::accel::_::__ctor::hfb9b1f61ac6430ce: Read a negative address value from the stack. Did we run out of memory?

I've only cloned the bevy_new_2d template, enabled bevy/webgpu, and added the plugin to App. Let me see if I can publish this rq

waxen kettle
lament basalt
#

ah, ok..this might be a quick fix

#

ill check it out

#

immediately seems they depend on the semver minor

lament basalt
#

hasn't been updated in 5 months

waxen kettle
#

I could get it to work without my toml plugin enabled, which includes serde and serde_toml. Separately they both work but together I get the same error as you. Didn't have much time to look other than that, just disabled particle effects on web builds.

lament basalt
#

yeah, prolly will do that as well

gilded urchin
#

Hello!
I'm encountering an issue where for the very first particle effect I spawn after game startup as an entity, it doesn't have any visuals.
From the 2nd one it works as expected then. It's always just the very first entity, even if I use a different EffectAsset.

Does that sound familiar to anybody? (on bevy 0.15)

junior glen
#

On Bevy 0.16

main wagon
#

Maybe we could do a hack where we just spawn the effect at startup offscreen somewhere lol

gilded urchin
#

Ah interesting ๐Ÿ˜„ yeah I was considering that as a workaround actually. But wanted to check if I'm maybe missing some loading or init call somewhere ๐Ÿค”

junior glen
remote ice
junior glen
#

FYI @lament basalt I got bevy_hanabi working on Chrome + WebGPU

#

If you tell me your error I may be able to help

lament basalt
#

that's really great news

junior glen
#

Did you make sure you're not pulling in serde?

#

cargo tree -i serde

lament basalt
#

but ive disabled so many features

junior glen
lament basalt
#

really bare to the bone yknow

#

im gonna see what your features are rq

junior glen
#

We don't even disable anything

lament basalt
#

oh

#

wait fr

junior glen
#

Welp

lament basalt
#

like, just for reference, bevy_hanabi's own wasm examples

#

do not compile

#

the whole .sh in the root

#

not one of them generates js bindings

#

I tried on both mac and linux

junior glen
#

The repo has deny(warnings) and nightly introduces some new ones FYI

#

Did you run into that?

junior glen
lament basalt
#

no, just the same error. it compiles but no bindings

#

sorry, the whole time i meant

#

compiles fine. bindgen panics

junior glen
#

that's so weird

junior glen
#

Maybe you can get the CI to run bindgen?

lament basalt
#

but i wouldn't be surprised if like, it runs

#

I see it fails in the browser, and you see the same test succeeds

junior glen
#

Hmm I see

lament basalt
#

๐Ÿ˜† i wouldn't be surprised

#

but since you can get it to work...

#

I know it's possible

junior glen
#

We are still trying to get our thingy to get deployed, so we are in this together ๐Ÿคž

lament basalt
#

you can get it to work right

junior glen
lament basalt
#

just wanna make sure

#

ok awesome

#

thanks

junior glen
#

on my Fedora, WebGPU only uses the CPU and not the GPU

#

Dur to a known bug

#

So idk if it actually actually runs when using a GPU ๐Ÿ˜ฌ

lament basalt
#

that's a W nonetheless

junior glen
lament basalt
#

@junior glen I think I might have to move forward and figure out this hanabi deal ๐Ÿ˜†

#

these gibs and ConvexDecompositionFromMesh fail the stress test

or...i could write a queue and kick out gib pieces early

junior glen
#

FYI, colliders made from meshes are cached on Avian main

junior glen
lament basalt
#

and the despawn time is 3s

#

I'm not exactly sure what's killing the performance here, need to investigate

#

๐Ÿค”

junior glen
#

we just spawn and despawn them

junior glen
#

Let's switch to #1124043933886976171 ๐Ÿ˜‰

lament basalt
#

didn't realize serde was in the list of default features, can't beliee I fked that

junior glen
weary abyss
#

I'm running into some performance problems, even ~250 concurrent particle systems are enough to bring my 4070 to its knees and that shouldn't happen

#

250 drawcalls isn't much

#

I could start aggressively trying to reuse particle systems but that's a pain and I'm going to see if anything jumps out in the profile.

#

I mean, I guess it'd be better to implement batching in Hanabi, but I'm really suspicious because a 4070 should be able to handle 250 drawcalls no problem.

weary abyss
#

It seems to be what I was afraid of: the lack of batching results in overhead that's just too high. We need to batch dispatches and use multidraw in the render phase.

weary abyss
#

@native elbow (no rush in responding) Looks like the first step is going to be to use the Bevy offset allocator to pack the data for copies of a single particle effect asset into a single buffer. Does that make sense to you?

#

Just wanted to get your sign off before I start implementing

native elbow
#

Yes, itโ€™s the batcher that you removed with particle groups essentially ๐Ÿ˜‰

native elbow
# remote ice Does it sound familiar? Yea, I had pretty much the same bug in my game which I l...

We did, 99% sure itโ€™s the various GPU resources, notably pipelines, which take multiple frames to compile, and so for burst effects the burst has already passed by the time the pipeline is ready. I talked with the Bevy rendering team, they have the same issue with various resources like meshes. Itโ€™s quite hard to solve. Plan is to start exposing the state of the pipeline at least so we can tell the user when the effect is ready. But really this is just a more robust version of โ€œspawn in the background in advanceโ€, which is the recommended workaround for now.

weary abyss
native elbow
#

Yes. Which makes it harder to surface the status of an effect because thereโ€™s not a 1:1 direct match between effect instance and pipeline, due to this layer of abstraction intended for batching.

weary abyss
#

@native elbow On a positive note, aside from the performance issues from lack of batching, Hanabi's feature set has definitely been suitable for production quality VFX at my studio

#

I probably have a good 2/3 of Unity's legacy particles engine replicated in Hanabi at this point

weary abyss
#

Looks like I've got that code fixed modulo a few edge cases. Wasn't too hard.

#

I think there will be 3 PRs:

  1. Multiple effects per buffer (hopefully today)
  2. Batching for init & update, via binary search to find the spawner and effect metadata for the current instance
  3. Batching for render via multi-draw indirect
weary abyss
#

@native elbow Working on moving sorting before batching as your comment suggests.

weary abyss
bright parrot
#

#showcase message

weary abyss
#

@native elbow no rush, but do you know when you'll get a chance to look at the that PR?

native elbow
#

I had a look but it's so easy to break everything that I will need to pull it and run and debug carefully, I can't just look at the code in the PR.

weary abyss
#

OK

weary abyss
#

@native elbow The ribbon example works for me, oddly enough.

native elbow
#

It looks like it works most of the time, just because you're lucky. See the review, there's at least 2 different bugs in the sorter.

#

More generally I'd rather:

  1. we add more tests rather than remove the existing ones
  2. we split individual changes; the PR is 1) adding metadata to render pass, 2) adding a new sorter, and 3) merging effects into a same buffer. Those things can be reviewed separately (I believe 1) is OK to merge, but 2) is broken, and therefore 3) can't be merged)
weary abyss
#

@native elbow can I add proptest?

native elbow
#

I don't know what's "proptest"

weary abyss
#

Also, do you want me to split up the PR, or keep it as it is and just fix the bugs since you already reviewed it?

native elbow
#

It's fine as it is now

weary abyss
#

OK. I'll fix the topological level assignment (it needs a separate pass to assign the levels, trying to assign the levels as it goes was too ambitious), flip the ordering, re-add the tests, and smoke test all the examples

#

on macOS and Windows

native elbow
#

I'm not sure about proptest, I don't like adding dependencies I don't know, it's random external code compiling inside everyone's own code. I don't think it's necessary for that single example. Most missing tests are not around algorithms they're GPU things. In fact the issue here is that there's no GPU test to catch this (same for the property layout bug I'm working on).

weary abyss
#

OK, I'll leave it out

bright parrot
#

You should check out proptest just for future reference though, it's an invaluable testing strategy! It's quite similar to fuzzing in a lot of ways:
https://crates.io/crates/proptest

errant crane
#

Is there a way for repulsor/attractor to use a relative coordinate frame and not global? Eg I have an effect that is childed to my character, but I want the attractor/repulsor to also follow the character.

native elbow
#

You can use local space simulation or move the attractor location with a property

errant crane
#

What is the status of the Node + Graph implementation (any eta or list of work to be done there)? Editing effects by hand and recompiling is a pain, i was thinking about making an editor and saw the Node API stuff, but it seems incomplete.

junior glen
#

@errant crane fyi

errant crane
#

Yea I saw it, from what I can tell in the video, you can't actually edit or build anything yet, and it's yet to be shared, but I am hoping!!! Or wishing to contribute. Also I think it's 2D, i'm after 3D, but I assume that bit will be easy to add.

wide cloud
errant crane
#

Gotcha, I recently just myself moved my project to 0.16. Let me know when you have something! I'd be happy to help port it forward and test and contribute

errant crane
#

I am a bit lost on how I could make something like lightning. My thought is a low spawn rate with small init position variance and ribbons between each particle while the entity moves forward at a high rate. But as far as I can tell it looks like ribbons are a second particle system that just tracks another one. Is there a way to have ribbons between each particle in 1 system?

weary abyss
#

@native elbow Got another PR ready for you when you get a chance. This one builds on my other one and knocks another roadblock that was blocking reenabling batching out of the way https://github.com/djeedai/bevy_hanabi/pull/487

GitHub

Currently, we use a dynamic offset to point to the Spawner. This prevents batching, so this PR changes the shaders so that the effect metadata contains an index to the spawner, and the shader picks...

#

I think I'll need another PR after this one for properties before I can reenable batching.

wide cloud
remote ice
#

Is there a recommended way of working with bevy_hanabi now that's not writing code? The effects have gotten even worse to write as code compared to my old bevy 0.14 code ๐Ÿ˜…

wide cloud
tidal violet
#

It looks pretty good

#

How is using it?

rich niche
wide cloud
# tidal violet How is using it?

Mostly pretty straightforward, although there was some initial cost of building basic components like text input, button etc. The only problem I didnโ€™t figure out is how to embed bevy window into parent gpui window.

wide cloud
rich niche
#

Why placing a SetVelocityCircleModifier in the update section produces a problematic wgsl code, where transform is not defined? And I wonder if there are any ways to solve this problem.๐Ÿ™ (Notice the function set_velocity_circle_xxx)

remote ice
#

So I seem to have two "fun" issues:

  1. Sometimes vfx will just play completely random effects instead (only on main)
  2. Whenever I set a texture on a vfx, the particles disappear, if the texture is gone they show up as squares as expected (latest release and main when it doesn't do 1)
#

I also had another issue but that seems to have been fixed on main already, where you can reference attributes that then get optimized out as unused and thus give shader compile errors

#

As for 1, it feels like it is just mixing the effect it should play with whatever the first registered effect was

remote ice
#

Okay update on 1, this only seems to happen on effects where I had commented all render modifiers out (which also causes fun issues like setting a lifetime, but age never being used, and thus the effect never actually expires)

native elbow
#

Isn't 2. the usual "the texture asset was not loaded in time"?

remote ice
#

The texture handle never gets unloaded so I doubt it ๐Ÿค”

native elbow
native elbow
#

I'd check the logs, in Debug at least, see if there's anything related there

remote ice
#

Hmmmm, I guess I could check the failed loading thing, they aren't the usual RGBA images at least ๐Ÿค”

native elbow
#

Try another image that works, and check if there's any log about asset not being ready.

#

That "asset not ready" thing has been plaguing Hanabi for many versions but I don't (and neither does the rendering team) have a good solution for it quite yet.

remote ice
#

Is it hanabi that prints the debug output or bevy_render or something?

native elbow
#

It should be Hanabi but I donโ€™t remember if it prints only for pipelines not ready or also for textures

remote ice
#

Ah, it appears I messed up adding the slots somewhere along trying to get it to work, and hanabi just silently replaces the load with using a 0 vec ๐Ÿ™ƒ

#

But yes, also the particles don't seem to like getting loaded, but at least it works now!

native elbow
remote ice
#

So pretty much just what the examples do with textures, but forgete to add the m.add_texture_slot("color");

mint star
#

What would be the best strategy to get particle effects to glow, without having bloom on other parts / layers of a scene?

remote ice
mint star
near zealot
#

is it possible to have different velocities for different instances of the same effect? Is that something I can do with EffectProperties?

I'm trying to make an effect like a spray that goes in a specific direction but didn't want to dynamically compile new effects every time

native elbow
native elbow
mint star
#

Re: bevy-hanabi editors, I wrote OMAGARI so I can make spell effects for HEXROLL. Works pretty well and supports most of what I need, including EffectParent relations, copy/pasting expressions and using 0.16.1 but 3D only.

near zealot
mint star
# near zealot is this available for use ๐Ÿ‘€

If you don't mind the blender1.0 vibe and some ugly code then I can push this to github (I'll have to file a release request on my day job before I can do so - but that shouldn't take more than a week to clear out)

near zealot
mint star
near zealot
#

how would I do something like the puffs example but have it be relative to a moving entity's position and rotation? If I'm understanding the example right, it seems like it would just always spawn at world origin and fly in that specific direction

mint star
near zealot
mint star
near zealot
#

hmm, I was trying to incorporate the property stuff and added the AccelModifier, the my_accel expression, .update(update_accel3) and a system for updating the property with DynamicRuntimeAccel...

and now when I trigger the effect my game just locks up. what could be causing that?

#

ah, I figured it out. I was missing the EffectProperties component. I guess if you add a property but don't add the EffectProperties component, it crashes

near zealot
#

hmm actually... it's like if I spawn multiple at once it freezes but if they aren't using a property then it works ๐Ÿค”

errant crane
simple notch
#

My game freezes on MacOS only when a lot of ParticleEffects are added. I've narrowed it down to this:

pub fn reserve(&mut self, capacity: usize, device: &RenderDevice) -> bool {
ย ย ย ย ย ย ย ย if capacity > self.capacity {
ย ย ย ย ย ย ย ย ย ย ย ย trace!(
ย ย ย ย ย ย ย ย ย ย ย ย "reserve: increase capacity from {} to {} bytes",
ย ย ย ย ย ย ย ย ย ย ย ย self.capacity,
ย ย ย ย ย ย ย ย ย ย ย ย capacity,
ย ย ย ย ย ย ย ย ย ย ย ย );
ย ย ย ย ย ย ย ย ย ย ย ย self.capacity = capacity;
ย ย ย ย ย ย ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย ย ย ย ย if self.buffer.is_some() {
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย trace!("reserve(): existing buffer will be destroyed");
ย ย ย ย ย ย ย ย ย ย ย ย } else {
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย trace!("reserve(): no existing buffer to destroy");
ย ย ย ย ย ย ย ย ย ย ย ย }
ย ย ย ย ย ย ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย ย ย ย ย if let Some(buffer) = self.buffer.take() {
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย trace!("reserve(): destroying old buffer...");
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย buffer.destroy();
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย trace!("reserve(): old buffer destroyed");
ย ย ย ย ย ย ย ย ย ย ย ย }
ย ย ย ย ย ย ย ย ย ย ย ย trace!("reserve(): creating new buffer with {} bytes", capacity);
ย ย ย ย ย ย ย ย ย ย ย ย self.buffer = Some(device.create_buffer(&BufferDescriptor {
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย label: self.label.as_ref().map(|s| &s[..]),
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย size: capacity as BufferAddress,
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย usage: BufferUsages::COPY_DST | self.buffer_usage,
ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย ย mapped_at_creation: false,
ย ย ย ย ย ย ย ย ย ย ย ย }));
ย ย ย ย ย ย ย ย ย ย ย ย trace!("reserve(): new buffer created");
ย ย ย ย ย ย ย ย ย ย ย ย 
ย ย ย ย ย ย ย ย ย ย ย ย self.is_stale = !self.values.is_empty();
ย ย ย ย ย ย ย ย ย ย ย ย // FIXME - this discards the old content if any!!!
ย ย ย ย ย ย ย ย ย ย ย ย true
ย ย ย ย ย ย ย ย } else {
ย ย ย ย ย ย ย ย ย ย ย ย false
ย ย ย ย ย ย ย ย }
ย ย }
2025-07-31T22:21:37.227957Z TRACE bevy_hanabi::render::aligned_buffer_vec: hybrid abv: write_buffer: size=800B item_align=256B
2025-07-31T22:21:37.227976Z TRACE bevy_hanabi::render::aligned_buffer_vec: reserve: increase capacity from 544 to 800 bytes
2025-07-31T22:21:37.227980Z TRACE bevy_hanabi::render::aligned_buffer_vec: reserve(): existing buffer will be destroyed
2025-07-31T22:21:37.227985Z TRACE bevy_hanabi::render::aligned_buffer_vec: reserve(): destroying old buffer...
#

I suspect the issue is related to Metal's lifetime management, where destroying a buffer while it's referenced by in-flight command buffers causes a hang.

#

seems to be same issue

native elbow
#

That sounds like a wgpu bug rather, because I thought wgpu was handling that. I specifically added those destroy calls from a recommendation of some wgpu contributor, to try and catch uses of old buffers. You can try and remove them see if that helps?

near zealot
#

yeah, actually, with the thing I ran into above.. there's no panic or stacktrace or anything.. the game just freezes.. it's difficult to know what's going on ๐Ÿค”

native elbow
#

It sounds like your analysis is correct, the buffer is still in use and so wgpu blocks the destroy call. Technically those calls are not necessary for Hanabi to work. Itโ€™s a debugging feature. So you can try removing them and see if the game still freezes?

#

Iโ€™m actually not 100% sure that itโ€™s correct to destroy the buffer there.

timid storm
#

hi im looking to know if bevy hanabi might finish the missing collisions feature and the position over shape for cube & plane feature by the time we get 0.18 of bevy

native elbow
#

No idea

weary abyss
#

I'm currently working on doing the remaining of the work for batching because it's blocking my project. I'm going to fork Hanabi for now because we can't afford to wait longer and plan to land the changes upstream at whatever pace you want.

native elbow
#

Thanks @weary abyss, sorry I donโ€™t have any time for this at the minute.

wise plinth
#

For one of my vfx I hit https://github.com/djeedai/bevy_hanabi/issues/420 a while ago at bevy 0.14. Prespawning it did fix the issue for the time being, but now I'm updating to 0.16 and now it errors with Failed to find material bind group layout for buffer #0 during prespawn and prespawn only. Seems noncritical as it works afterwards, but I was wondering why it suddenly log errors and whether I can easily fix it or not ?

GitHub

Trying to make explosion by spawning explosion entity with effect, but starts_immediately doesnt work, and nothing happens. // on_add component hook fn explode(mut world: DeferredWorld<'_&gt...

weary abyss
#

I currently have batched rendering working with MDI in simple examples. Some examples crash but it shouldn't be too tough to fix.

#

This is only 1/4 of the solution though: init, update, and sort will also need to be batched and the techniques are different for each one.

#

This is about a 1k line patch, so I would imagine that the full set of batching patches will be about 4,000 lines or so, plus the two PRs I already have open.

junior glen
weary abyss
remote ice
#

Did we have batching in the past?

#

I remember once running with millions of bugged particles ๐Ÿคฃ

#

-# The despawn condition on emiters was wrong and the effects were in world space, so the playtesters decided to have a bit too much fun

gilded fox
#

This is going to save me so much time haha

#

What does it mean that it uses 3D only?

mint star
gilded fox
mint star
gilded fox
#

I'll make another effect, one sec

gilded fox
mint star
weary abyss
# remote ice Did we have batching in the past?

We always batched, but not across multiple instances of the same effect.

Spawning many instances of a small effect is a thing that games tend to do a lot and right now Hanabi's performance drops dramatically with this. It's even worse when the effect is composed of many smaller effects, which is very common in real world VFX that artists author. For example, one of our common VFX instances has 7 sub-effects. If you put just 15 of them on the screen then the app starts lagging horribly due to wgpu overhead. We can't really ship with this as 15 instances of an effect is something most games will do.

#

My code makes us batch across multiple instances of the same effect. I've already got vfx_render batching using multi draw indirect and vfx_init batching in the CPU spawner mode. This batching not only reduces dispatches, but also increases GPU thread occupancy, because multiple threads within a single workgroup can now be assigned to different effect instances.

For example, with the instancing example, we go from 40+ workgroups in the init phase to just 2, one for each effect asset.

#

Next up will be batching vfx_update, which should, along with the rest of my patches, result in dramatic performance increases in many Hanabi workloads, dropping the number of dispatches/drawcalls from O(number of effect instances) to O(number of separate effect assets). I will still want to batch vfx_sort and GPU spawning with vfx_init, as our artists are using those features quite a bit.

gilded fox
#

I noticed that rotating the effect's transform doesn't rotate the effect itself (unless I'm doing something wrong)
Is there a way to rotate an effect's preset dynamically?

#

nevermind my calcualtion was wrong

gilded fox
#

I don't understand how to set up the texture slots in effects

#

But I don't see anything

#

( I can see the effect when I don't use EffectMaterial )

hidden scarab
#

Is there a delay in spawning a ParticleEffect and the effect displaying? The ribbon entity I have following projectiles start the trail further away from the player the faster the projectile is, even though spawn position is on the player

weary abyss
#

Ok, vfx_update now uses batches. instancing goes from 40+ compute dispatches down to 2, the first one with 110 workgroups and the second one with 7 workgroups. This also should improve shader occupancy a lot.

weary abyss
hidden scarab
remote ice
#

Just load the effects once somewhere so they load. No need to object pooling, pooling in an ECS sounds like madness

hidden scarab
#

lol yeah thats why I hadnt thought to try it

#

when the game starts I initialise a resource that holds a reference to EffectAsset.add(ribbot_effect)

#

I thought that loads it, each time I spawn a projectile I would clone the effect handle from the resource

remote ice
#

You'd need to spawn the effect once for the shader to get compiled I think. I'd imagine in the future bevy will get so mechanism to make this work nicer though

hidden scarab
#

Even if I shoot the same projectile type multiple times the trail starts late for all of them

gilded fox
#

I thought it would pick one randomly

junior glen
#

For prior art, see Foxtrot or Chainboom

hidden scarab
# junior glen You typically spawn a dedicated scene containing all materials and VFX behind UI...

I haven't touched shaders much so im not sure I understand, bare with me. If spawning the effect in advance begins the shader compilation, then shouldn't firing a projectile for the first time begin shader compilation? If so then after some amount of time I would expect ribbons to start at the expected position when firing, but they don't (At least not within a few minutes for one minimal effect)

Am looking through Foxtrot & Chainboom and noticed you use world.add_asset(EffectAsset), where I use Assets<EffectAsset>.add(EffectAsset) for keeping a reference in a resource to be cloned, could that be a culprit?

junior glen
hidden scarab
#

I would have thought adding assets either way would be functionality comparable, I'll try and put a minimal recreation of it together when I get time at my computer later

hidden scarab
weary abyss
#

Everything is now batched in my branch except for spawn events. Remaining tasks:

  • Batch spawn events (needs a new shader to create batched indirect dispatch args).
  • Batch properties (I never actually did this)
  • Reenable culling as I broke it
#

3500 line patch so far

weary abyss
#

OK, all effects are now batched. Just need to fix properties and culling.

#

One annoyance is that with batching there's no longer any attempt whatsoever to render transparent particles in the right order. Hanabi never did this properly anyway, but now it's kind of hopeless. Just use alpha mask or OIT

#

Batching does add an overhead of 3 compute invocations per frame, but this is a fixed overhead and doesn't increase with the amount of effect types you have. The number of compute invocations and drawcalls should now be O(number of effect assets), not O(number of effect instances).

#

Given how slow wgpu is, this is the difference between Hanabi being unusable for lots of games and Hanabi being usable for them (including for my project)

junior glen
#

Thanks a bunch!

#

Is there a branch one can try out?

weary abyss
weary abyss
#

(For example EffectBatch is no longer a batch and needs to be renamed to EffectInstance and RenderBatch needs to be renamed to EffectBatch)

weary abyss
#

You know, I wonder if the failure in the ribbon example is one effect loading before the other? That would explain why running it "cold" fails and rerunning the example succeeds -- when the shaders are in the OS disk cache they load at the same time, avoiding the problem

timid storm
#

can u add the missing collisions as well as position over cube and plane in bevy_hanabi?

weary abyss
#

ok, this is what the profile looks like with a few hundred effects
The performance problems are fixed, it's basically just lack of using the retained render world

weary abyss
#

OK, in my project I can now get over 500 different particle effects on screen and still hit 120 FPS.

silver veldt
#

has anyone made rain in hanabi?

silver veldt
#

i can't figure out how to make a particle bigger...

silver veldt
#

is there a way to tie everything to the camera?

#

@weary abyss i'm trying to add rain to my game, how should i make it cover the whole map? obviously you could just set it to create particles everywhere but i can't imagine the performance would be very good lol. is it possible to make the particles stay inside the game world (not moving with the camera because that would look weird), but appear everywhere?

junior glen
weary abyss
silver veldt
#

thanks

weary abyss
#

I have a suspicion that Hanabi bind groups aren't being invalidated properly or something. When spawning and despawning complex effects the effects can sometimes end up in the wrong place (often an existing effect teleports to a new location unexpectedly). This isn't specific to my batching changes as this happened before.

#

On a positive note, none of our testers are reporting any VFX performance problems anymore with Hanabi post batching.

remote ice
weary abyss
#

I can definitely repro it, though it's quite random. I'll try to fix it when I get time

weary abyss
#

The problem seems to go away if I hammer in global simulation space. Which indicates to me that it's likely an issue with how we allocate and/or pass in spawners to the vfx_render shader

weary abyss
#

Looks like the spawner data is getting corrupted. Strange.

weary abyss
#

OK, that's fixed; there were multiple bugs, including one in my code and one whereby Hanabi wasn't invalidating bind groups when the spawner buffer resized. There's still an issue whereby some effects with single bursts just don't emit their bursts (and it's not that they aren't loaded; this is after loading).

weary abyss
#

Oh, this is fun. If you specify you want to spawn 1 particle per cycle, sometimes Hanabi fails to spawn any, because it accumulates fractional particles via floating point math, uses floor on that value to determine how many particles to spawn, and sometimes you end up with 0.99999 at the end of the cycle, which rounds to 0.

#

I think the solution may be to keep track of the integer number of particles spawned this cycle and if there are any remaining at the end of the spawn duration spawn them then.

native elbow
#

The user specifies a rate in float. I donโ€™t see how your proposal avoids any imprecision

remote ice
#

Can't we just emit an extra particle by rounding up slightly at the end?

#

(Like floor(n + 0.1))

weary abyss
#

I fixed the issue. Kinda hard to explain here

#

I keep track of the integer number of particles spawned and also recalculate the number of particles spawned in absolute terms every frame instead of accumulating, so that floating point error doesn't accumulate. This requires a little bit of trickery when multiple cycles happen per frame but I believe my code is correct, and it avoids the problem.

weary abyss
#

Just fixed another bug with batching whereby child event offsets weren't being taken into account. Will push to my batching-2 branch soon

native elbow
# remote ice Can't we just emit an extra particle by rounding up slightly at the end?

No. Where do you put the limit? There's always an epsilon where someone will complain that a particle "should" or "should not" have been spawned but wasn't/was. Just because the example is 0.99999 doesn't mean we should spawn; there may be a legitimate case where you have "close to" 1 particle but not yet accumulated enough. If you start rounding you'll get random oscillations in spawning. The issue is not the rounding it's the error accumulation.

#

That may not matter in common cases where the effect spawns forever at a given rate, and is the only effect. But as soon as you try to synchronize multiple effects, if they spawn a few frames too early or late you break the overall visuals, even if "on average" you spawned the correct amount. So you just moved the problem compared to now.

remote ice
#

Ah, yea, then you start needing funny solutions like what I do for DPS status effects in my game ... Which is basically what pcwalton did. Calculate how many particles you should've emitted, subtract how many you did emit, then emit that number

#

I have the benefit of doing it with integer per-second numbers there so I can always look at the past second and thus never have issues even with infinite effects

weary abyss
#

Pushed another bug fix that could cause child events not to be emitted when you have 3+ separate effect assets (not instances), two of which are children of the other one.

weary abyss
#

I'm out of F32XN attributes in my Unity particle system loader, can I add a couple more?

weary abyss
#

OK, I've had a grand old time casting booleans to floats and using mix() to perform if/then in Hanabi expressions, but I think it's about time I submit a PR to add select to TernaryOperator ๐Ÿ™‚

native elbow
#

I've run it again, the instancing example clearly has issues

#

Like, some particles have a velocity 2x or 3x occasionally, for no apparent reason

weary abyss
#

Well, almost all

#

That PR is old and has issues, I'm pretty sure

#

I've basically just forked Hanabi

#

There are some bugs in upstream Hanabi that are only fixed in my batching-2 branch

#

Right now I suspect that there's a cache invalidation problem with render bind groups (absolute nightmare to debug)

weary abyss
#

I think it'd be best for me to iterate on my fork right now to get all the bugs out before upstreaming. That way I'm not upstreaming broken stuff. Batching adds a lot more indirection so it's easy to get things wrong.

weary abyss
#

I need transmissive materials for Hanabi (useful for e.g. soap bubbles). Unity supports this. I'm currently adding them to my fork. Is this something upstream is interested in?

lament basalt
#

I am at least interested in this

lament basalt
weary abyss
#

I just pushed a bunch of ad hoc fixes for various ways in which buffers could leak via bind group caches when resizing them. I think we need a more holistic way to solve this: making cached bind groups weak somehow so that when the buffers go away we automatically drop the bind groups.

weary abyss
#

I don't think this is feasible when looking at it more, but I'm going to at least try making a unified BindGroupCache that tracks things like total number of bind groups and total allocated buffer size so we can more easily detect leaks.

native elbow
#

Disclaimer, I know this is not nice at all, but because the current code is so complex to maintain and debug, I've started actually looking at cleaning it up. This means conflicts ahead with your fork @weary abyss. Unfortunately I've looked at your PR and it's just unreviewable, less because of the change itself, mostly because the bits it touches are so complex and easy to break that even checking the code locally I've little confidence I can catch bugs. So instead I'm looking at fixing the core maintenance issue and making the code more readable and testable.

I've started by moving the indirect draw args out of EffectMetadata, because the former is almost pure GPU access (except if you change the mesh completely, which is rare; basically it's a different effect), while the latter contains data that may change frame-to-frame (mesh location notably, which is dictated by Bevy, and I have to assume can change at any point) and is dictated by CPU only (and read back by GPU). This basically addresses the warning of #471. I'd like also to look at cleanly separating management of bind groups and layouts from GPU buffers, instead of shoving some in the EffectsMeta resource and some in other places. That should help identify bugs around bind groups, and also make it easier to add new ones (which currently is a brake to adding features).

weary abyss
weary abyss
# native elbow Disclaimer, I know this is not nice at all, but because the current code is so c...

So the main thing that my branch does is to add batching across effect instances. There are other things, but those are fairly localized and can be submitted as individual PRs relatively easily. What I'm hearing is that you might want to just do batching in some other way. I think this is actually fine: if you want to do batching yourself, I can go ahead and submit PRs for my non-batching things (e.g. transmission, more expressions, insertion sort -> heapsort), and you can do batching however you'd like to do it, and then when we're ready I can just ditch my fork and go back to upstream.

native elbow
#

No not really, I think I'll grab your sorter for example, and for batching I'm not sure yet. What I'm saying is that I'm moving a bunch of code around and doing renames etc. to clarify the code, which will cause git conflicts with both your PR and your branch.

#

But I just got interrupted because I think I have a RenderDoc capture of the ribbon artifacts we saw in the PR ๐Ÿ™‚

weary abyss
weary abyss
#

I'll eventually just abandon my branch once I can use upstream (right now lack of batching makes it unusable)

#

But feel free to cherry-pick things over, and I can also send PRs of small things like the sorter

weary abyss
# native elbow No not really, I think I'll grab your sorter for example, and for batching I'm n...

I have a feeling you won't like what I did with batching anyways. I introduced a new batching type on top of EffectBatch called EffectRenderBatch, ported everything over, and then renamed EffectBatch to EffectInstance and EffectRenderBatch to EffectBatch. This allowed me to proceed incrementally. Currently most shaders use linear search to find the effect instance, which is obviously slow (I'll change it to binary search if it starts causing performance problems). Also I use multi-draw indirect which isn't really necessary as the meshes within a batch are always the same mesh, and I have a feeling you won't like that either because it sacrifices compatibility with WebGPU right now.

#

tl;dr there's a good chance you might want to rewrite my batching code anyways.

native elbow
#

Noted, thanks for the details

#

I have a RenderDoc capture that randomly exhibits the ribbon bug. That is, switching back and forth between 2 render calls, I see different render results on screen. I had that once in the past, opened a RenderDoc bug, and the explanation was that the shader code was non-deterministic. So I'm getting slowly convinced that there's a non-deterministic bug (so, around atomics) and that's why it's so hard to repro. Running the ribbon example again and again I have ~15% repro rate (once every 6-7 runs or so only).

native elbow
#

I found the main part of the bug:

  • The vfx_indirect always runs, unconditionally swaps the read/write buffers for indirect indices.
  • Sometimes, presumably because some GPU resources are not ready, the vfx_update doesn't run. In that case, it doesn't copy the indices from one buffer to the other, which it would have done if it had run to indicate which particles are still alive after the update.
    After that, the buffer instead of containing the list of alive particles contains a bunch of undefined values (generally, 0) at the place where the previous frame particle indices should have been. This continues to propagate inside the indirect index buffer after that.
#

Yay for GPU debug markers. The pipeline resource is not finished creating.

#

This delayed background creation of pipelines randomly stalling for several frames is the gift that keeps on giving really.

weary abyss
# native elbow

Called it ๐Ÿ™‚ I suspected it was something like that after tearing my hair out trying to figure out what it was.

native elbow
#

Yeah but I didn't foresee the interaction with sorting and the indirect dispatch to be honest, that was pretty tricky

#

It's annoying because that ties straight into the issue of trying to delay non-ready effects and/or warn the user which is a non-trivial one, so I'm not sure how best to fix.

#

I think I'm going to try at least to skip during prepare the effects which don't have a PSO ready

junior glen
#

No rush, just asking to plan ahead: it will probably take a while until hanabi is updated to the RC, right?

weary abyss
junior glen
#

So I take it it won't participate in the RC?

weary abyss
#

I do plan to move to 0.17 though.

junior glen
weary abyss
#

I still intend for it to be temporary and to deprecate it once upstream has comparable performance

weary abyss
#

I think I'm going to add a debug option that dumps the data for each particle every frame to CSV. Cross-referencing in RenderDoc when batching is enabled is very time consuming.

native elbow
weary abyss
#

I also realized we can try to add collisions against the depth buffer. As I suspected, I'm not the first to invent this technique, and this is a thing that Unity VFX Graph can do

near zealot
#

does bevy_hanabi make a mesh for each particle? (I'm using 3d and doing things like the billboard particle example)

weary abyss
near zealot
# weary abyss Can you elaborate as to what you mean?

hah sure. I have a particle effect and I was wondering if there was a way to add a component to the particles.. but I'll be honest, I haven't finished my coffee yet and now I'm realizing that probably doesn't make sense since the particles are shaders, right?

weary abyss
#

each particle can be any mesh you want

near zealot
weary abyss
#

I'm not sure what you mean by "a component". Which component?

#

Individual particles aren't entities

near zealot
#

I think that's somewhat what I was wondering. which makes sense

#

the coffee is hitting ๐Ÿ‘

weary abyss
#

It's interesting to think of Attributes as components and Modifiers as systems

native elbow
#

Hanabi is a GPU-based particle system. Particles are stored in a GPU buffer, spawned and initialized from GPU, updated each frame from GPU, and obviously rendered there. There's no representation of the particles on CPU, even less so in the ECS, so there's no way to attach a component.

#

As @weary abyss mentioned you can attach some data with particles, which are called attributes. And in fact a particle is just a collection of attributes. Note however that all particles in a given effect have the same set of attributes, it's not like an ECS entity which can have different components from another entity.

#

The set of attributes is called the particle layout (ParticleLayout in code)

near zealot
#

I'm trying to add property-driven acceleration like in the spawn example. When I run the example, I can see it works but when I try it in my game it just locks it up.. what could be causing that?

native elbow
#

"locks up"?

near zealot
#

the game freezes. it stops rendering new frames, I have to kill the terminal to exit the game

#

oh it's.. if I have more than one instance of the effect running at a time ๐Ÿค”

native elbow
#

ok well it obviously shouldn't, but it's hard to tell if it's related to properties or anything else. does it work without properties?

near zealot
# native elbow ok well it obviously shouldn't, but it's hard to tell if it's related to propert...

I can trigger the particle multiple times and have them overlap without a problem but once I have the writer do this

let my_accel = writer.add_property(PARTICLE_VELOCITY, Vec3::new(0., -3., 0.).into());
let accel3 = writer.prop(my_accel).expr();
let update_accel3 = AccelModifier::new(accel3);

it freezes if two of that particle exist at the same time. With and without the .update(update_accel3) in the EffectAsset

native elbow
#

when you talk about "particle" here you mean ParticleEffect right?

near zealot
#

I have an update_accel system similar to the one in the spawn example (except it iterates over the query rather than doing single_mut) and adding it on Update, FixedUpdate or not at all doesn't seem to have an effect

native elbow
#

You have added the EffectProperties component? You're sure the iteration works?

near zealot
# native elbow when you talk about "particle" here you mean `ParticleEffect` right?

yeah, I have a spawn system that does

    commands
        .spawn((
            ParticleEffect::new(particle.clone()),
            input.transform,
            ChildOf(game_root.vfx),
            EffectProperties::default(),
            DynamicRuntimeVelocity,
            EffectMaterial {
                images: vec![input.image],
            },
            Name::new("Particle"),
        ))
        .insert_if(
            DespawnAfter(Timer::from_seconds(config.despawn_after, TimerMode::Once)),
            || config.despawn_after > 0.0,
        );
near zealot
#
fn update_accel(
    time: Res<Time>,
    mut query: Query<(Entity, &mut EffectProperties), With<DynamicRuntimeVelocity>>,
) {
    for (entity, mut properties) in &mut query {
        let accel0 = 10.;
        let (s, c) = (time.elapsed_secs() * 0.3).sin_cos();
        let accel = Vec3::new(c * accel0, s * accel0, 0.);
        println!("Setting {} {}", entity, accel);
        properties.set(PARTICLE_VELOCITY, accel.into());
    }
}
native elbow
#

How do you create your effect? Are you sure the particle has the Attribute::VELOCITY? (unlikely it doesn't, but just checking)

#

The spawn.rs example explicitly adds init_vel3 which will force the particle to have a velocity attribute.

#

You can add InitAttributeModifier::new(Attribute::VELOCITY, Vec3::ZERO) or something like this, that will force the particle to have a velocity attribute

#

Normally it should have one, but I can't recall the details on top of my head, and I'm not sure Hanabi correctly propagates the dependency from "properties using an attribute" to "particle needs that attribute"

#

You can print the ParticleLayout from the effect and see what attributes are there

#

EffectAsset::particle_layout()

near zealot
#

I have...

let center = writer.attr(Attribute::POSITION);
let speed = writer
    .lit(config.min_speed)
    .uniform(writer.lit(config.max_speed));
let dir = writer
    .rand(VectorType::VEC3F)
    .mul(writer.lit(2.0))
    .sub(writer.lit(1.0))
    .normalized();
let init_vel = SetAttributeModifier::new(Attribute::VELOCITY, (center + dir * speed).expr());

and then later
    .init(init_vel)
native elbow
#

Ok it's not that then

#

It all looks OK to me, not sure what's going on

#

Any chance you can break in a debugger see why the app freezes?

#

Crashing/panicking I would understand, but flat out freeze it's a bit less common.

near zealot
native elbow
#

Looks all OK

near zealot
#

let me setup a debugger.. I haven't done this with a bevy game in years ๐Ÿ˜…

native elbow
#

๐Ÿ™‚

near zealot
#

lol ok, it doesn't freeze when I have a debugger attached.

near zealot
#

yeah actually.. running in release doesn't freeze but running in debug does freeze.. quite peculiar ๐Ÿค”

for the record, I can run the example spawn in debug and release with multiple instances of the property-driven effect just fine. there must be something altering my rendering pipeline in debug or something

native elbow
#

hum.. I wonder if it's some bug with the forced destroy() on the bind groups. It vaguely rings a bell of someone complaining that those destroy() calls sometimes occur when the buffer is still in use by the GPU and that causes issues (can't recall if that was a freeze or something else).

#

Are you by any chance on a Mac?

near zealot
weary abyss
#

Oh yikes, has_side_effect is broken for binary expressions like UniformRand (it's never checked) which cost me hours of debugging

#

I'll make a PR

weary abyss
bold ocean
#

Just wanted to say I've been following Hanabi's progress and I really like reading all the updates. Thanks for all you guys do

weary abyss
#

@native elbow When you get a chance let me know how you'd like to proceed with the failing test. By the way, my inclination is to actually err on the side of generating more temporaries -- otherwise you're relying on the shader compiler's GVN to perform aggressive common subexpression elimination everywhere which is probably a safe assumption for popular GPUs but it feels messy.

weary abyss
tranquil spade
#

Hello everyone. I started experimenting with bevy_hanabi not long ago and stuck trying to construct expression for generating randomly angled velocity vector in range for particles (for example between -30 and 30 deg).
Here is a gist with my setup function for the effect: https://gist.github.com/alcron/3a6d0cad47eba4fc2e2d865b3292ce3e
It would be great if someone could point me in the right direction.

Gist

particle setup function. GitHub Gist: instantly share code, notes, and snippets.

weary abyss
native elbow
#

Itโ€™s annoying to do. In fact the formula in the existing position modifier is wrong, in the sense that it doesnโ€™t generate some uniform distribution across the cone. But if you donโ€™t care about statistical uniformity you can use that formula.

#

The correct formula, I have yet to see it or manage to derive it myself. The complexity comes in part from the fact we want to handle a truncated cone. I think for a half-cone itโ€™s a bit easier.

weary abyss
# tranquil spade In a cone.
let (zero, max_azimuth) = (module.lit(0.0f32), module.lit(2.0f32 * PI));
let max_inclination = module.lit(30.0f32 / 180.0f32 * PI);
let azimuth = module.uniform(zero, max_azimuth);
let inclination = module.uniform(zero, max_inclination);
let (sin_phi, cos_phi) = (module.sin(azimuth), module.cos(azimuth));
let (sin_theta, cos_theta) = (module.sin(theta), module.cos(theta));
let x = module.mul(sin_theta, cos_phi);
let y = cos_theta;
let z = module.mul(sin_theta, sin_phi);
let direction = module.vec3(x, y, z);
let init_vel = SetAttributeModifier::new(Attribute::VELOCITY, direction);

untested.

See https://en.wikipedia.org/wiki/Spherical_coordinate_system#Cartesian_coordinates.

Make sure you're using main, not the version on crates.io or https://github.com/djeedai/bevy_hanabi/pull/497 will ruin your day.

GitHub

Currently, if the output of UniformRand is used in multiple dependent expressions, a new random number will be generated every time. This is at odds with the behavior of BuiltInOperator::Rand. The ...

In mathematics, a spherical coordinate system specifies a given point in three-dimensional space by using a distance and two angles as its three coordinates. These are

the radial distance r along the line connecting the point to a fixed point called the origin;
the polar angle ฮธ between this radial line and a given polar axis; and
the azimutha...

tranquil spade
weary abyss
native elbow
#

NB: Your code sample a random direction. That should work. However that produces velocities all equal (in speed/amplitude). And if you rand() the length to get a true random velocity, you will end up with a non-uniform distribution. Just FYI.

native elbow
#

This decouples "add an effect, start allocating all GPU things" from "can we simulate this frame if everything is ready and the effect is visible"

silver veldt
#

hanabi doesn't work well with wasm right? any way to fix that? if not would it be possible to automatically disable particle systems (or have some sort of run_if condition) when compiling for web?

lyric flume
silver veldt
#

maybe i just did something wrong

lyric flume
#

it should be enabling the feature

silver veldt
#

alright i'll build the project with web enabled and see what happens

lyric flume
#

there's a whole wasm examples directory in the hanabi repo, so if it didn't work that would be surprising

silver veldt
#

oh hey it worked lol not sure what happened last time

native elbow
#

Yes webgl2 doesn't work because it doesn't support compute shaders. It's not "doesn't work well", it's "doesn't work at all" ๐Ÿ™‚

weary abyss
native elbow
#

Hanabi already released yesterday

weary abyss
#

Oh that it did, sorry for the confusion ๐Ÿ™‚

#

I should mention that the new RenderTarget::None that I added for cameras in 0.17 is useful for prewarming effects during loading screens in Hanabi. Just spawn a Camera3d, set its Camera::target to RenderTarget::None, aim it at the origin, and then spawn all your VFX during your loading screen. This will trigger a shader compile.

junior glen
#

so it's neat seeing some better support for the pattern!

junior glen
#

but it renders correctly

#

I'll try WebGPU now

#

oh, looks like you're on an older getrandom :/

#

mind upgrading that to 0.3?

#

Otherwise I get this

#

note that I cannot activate the wasm_js feature of [email protected] since I already depend on 0.3

#

let's try the official Hanabi now

#

Can confirm official Hanabi works on WebGPU ๐ŸŽ‰

#

and doesn't produce the warning above

weary abyss
#

Need to fix it, whatever it is

#

It seems harmless

weary abyss
#

mmm, Unity's "Freeform Stretching". The artists love it. I do not.
Wasted nearly a week reverse engineering how it works and interacts with all the other features to implement it in Hanabi. Almost done...

iron turtle
#

Hi, I'm having a weird crash after upgrading. I've a bullet tracer that I spawn
like


        let mut effect_properties = EffectProperties::default();

        let ribbon = match event.bullet_source {
            BulletSource::Player => &particles.on_shoot_ribbon_blue,
            BulletSource::PlayerHelper => &particles.on_shoot_ribbon_blue,
            BulletSource::Enemy => &particles.on_shoot_ribbon_red,
            BulletSource::Other => &particles.on_shoot_ribbon_red,
        }
        .clone();

        commands.spawn((
            transform,
            ParticleEffect::new(ribbon),
            effect_properties,
            Follow {
                entity: bullet_entity,
                offset: Vec3::ZERO,
            },
        ));

It works, until I spawn some other. If I wait to particle to despawn I can spawn it again but not two at the same time.

I get two errors

thread '<unnamed>' (33324) panicked at C:\Users\stan\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\wgpu-26.0.1\src\backend\wgpu_core.rs:2391:18:
wgpu error: Validation Error

Caused by:
  In a CommandEncoder
    In a pass parameter
      Encoder is invalid
thread '<unnamed>' (33324) panicked at C:\Users\stan\.cargo\registry\src\index.crates.io-1949cf8c6b5b557f\wgpu-hal-26.0.4\src\vulkan\instance.rs:192:58:
Trying to destroy a SurfaceAcquireSemaphores that is still in use by a SurfaceTexture
stack backtrace:

Any idea where should I look?

native elbow
native elbow
native elbow
neon trail
#

I'm getting the same Encoder error in bevy 0.17.2 when spawning more than one ParticleEffect that uses ribbons

native elbow
#

Do you get the error with the ribbon.rs example?

neon trail
#

let me check

#

hmmm no I don't, I wonder why

#

OK, if I change the ribbon.rs example to spawn more particles on update I can reproduce the panic

#

I'm on MacOS (so using the metal renderer) if that's relevant

#

I also get a nasty pink screen flash when running any example or my game if I have the hanabi plugin enabled btw

native elbow
#

Pink sounds like the fallback Bevy texture when not loaded

neon trail
#

Pink sounds like the fallback Bevy texture when not loaded
Right, but this issue happens on all the hanabi examples even those that don't use any textures, so I wonder what's up with that

native elbow
#

I investigated a bit:

  • Repro on macOS, doesn't on Windows
  • Repro on all Hanabi examples, didn't on the one Bevy example I tried
  • Managed to get a Metal capture, I see weird things: I can't see a full-pink screen, but I see the text UI of the demo rendered in pink. And the UI pass definitely binds an all-pink texture.
  • I couldn't find a single source of pink texture in Hanabi.

My (partial) conclusion is that it's coming from Bevy itself, and more specifically bevy_ui and its font atlases I suspect, but I don't know why it doesn't repro on some Bevy examples.

neon trail
#

Interesting. Thanks for checking it out.
I do not see it in my Bevy game, only when I enable the hanabi plugin.

Let me try to get Metal capture working

neon trail
#

Hmm... I tried setting debug_settings.start_capture_this_frame = true; on the very first frame. I do see a pink flash but it's gone by the time the capture starts, which is weird. There's definitely an all-pink texture binded.

#

Unfortunately I don't have enough GPU experience to be of any more help, but do let me know if there's anything I can do on my end

#

Did you manage to reproduce the ribbons panic?

native elbow
#

No I can't reproduce the ribbon panic.

#

I found while debugging that start_capture_this_frame is kind of broken, or at least it's a footgun : you have to make sure to turn it back to false immediately on the next frame, otherwise it'll stop and start again every frame.

#

My capture also didn't have a pink frame. But I couldn't tell if it's because it was missing the first frame, or something else.

#

I did reproduce the error "GPU fill dispatch buffer operation bind group not found" but that was when some shader was wrong, so the error is not meaningful (it's just we're trying to submit a compute dispatch but the bind group was not created because the shader never compiled correctly). But at least with the fix we're not showing that error, only the original one.

neon trail
neon trail
#

i think pink flash might be related to this so I guess there's nothing to do on your side, sorry

neon trail
#

I used the debugger and found the real cause, it seems like it's a DynamicBindingOutOfBounds error

native elbow
#

Any chance you can repro with an example?

neon trail
#

Thanks for looking into it

neon trail
#

This also crashes for me on Windows with Vulkan, just tested

weary abyss
#

@native elbow It turns out that in practice VFX artists love making particle systems that have 1-5 particles in them, for the simple reason that they don't want to have two incompatible systems, one for "small-scale" particle effects and one for "large-scale" particle effects. Hanabi's not very efficient at this, though it's not causing problems for us yet. In such cases the CPU-side driver/wgpu overhead of just submitting the compute invocations is more computation than just doing init/update on CPU would be, and that's before you get to all the wasted GPU threads.
I wonder what the best solution is. Things I can think of:

  1. Run small particle systems on CPU.
  2. Ubershaders?
  3. Doom Eternal's VM approach? (Basically a variant of ubershaders)
  4. Something else?
    Nothing I can think of is simple, unfortunately.
    Again this isn't causing me any problems right now, but it's food for thought. I wonder if you've given any thought to this.
native elbow
#

If all systems have different shaders, there's no way around ubershader/VM.

#

If they're the same, then batching.

#

I don't think there's much more alternatives? I'm definitely lacking first-hand practical experience though, so happy to hear about usages I might be missing.

#

To be honest if the particles have roughly the same set of attributes, for some definition of roughly, then you could abuse a single Hanabi effect and expressions/modifiers to write the equivalent of a ubershader

#

We could even imagine going completely crazy and have dynamic layouts per effect, and have the shader byte-read them, although reading bytes instead of structs is very not nice in WGSL

#

(as you've seen in vfx_indirect.wgsl)

#

Another thing I think Unity does is split attributes. I think they do it for POSITION only to optimize things like depth pre-pass or any other pass where you only need the position (and so it's faster to have a compact position array without gaps). But we could generalize that. That's a LOT of complexity though.

#

Unrelated, I've tagged you on the wgpu bug I opened, I didn't know you had opened one too.

#

@neon trail I made a local change and reproduced the Encoder error. Indeed it's a completely unrelated error which triggers that one, although in my case I can't tell what's the error (it's probably due to my local change).

weary abyss
#

I do have to say, testers lately have been really impressed by Hanabi's effects in the hands of skilled VFX artists, so great job ๐Ÿ™‚

neon trail
native elbow
wise plinth
#

Hmm so as far as I understand, the only real way to bundle effects together is to do them as a single hierarchy, but I don't quite get how to do the root effect for the oneshot effects ?

Currently I have zero age almost zero lifetime effect that emit events on death, but it has a bizarre side effect: exactly on the 15th reset it changes from OnDie events to Always events (or maybe it's something else, but it looks like nested spawners freak out a lot on the 15th parent spawner reset).

Am I doing something cursed ? I tried to hack a new emit event OnInit, but it's not that simple due to init phase not being able to emit any events (it only consumes events atm, I'm not even sure if will conflict ?)

native elbow
#

I've seen that the firework event, which is supposed to create the explosion OnDie, sometimes creates multiple explosions. I didn't have time to look into it, but that smells like a bug.

#

I think unfortunately the next one will be "at 2200 particles in worms.rs it takes 265ms to sort" ๐Ÿ™„

#

Gosh I really don't want to implement a GPU sort

#

By the way #508 is heavily inspired by your PRs and branch, thanks for that! I also merged your sorter in an earlier PR.

mortal falcon
weary abyss
#

@native elbow My thought was maybe to do a "double mergesort" where instead of merging 2 sublists, each step merges 4 sublists. This would make the number of dispatches log4(n) instead of log2(n). For example:

  • 100 particles: 4 dispatches
  • 1k particles: 5 dispatches
  • 10k particles: 7 dispatches
  • 100k particles: 9 dispatches
  • 1M particles: 10 dispatches
    This seems reasonable?
native elbow
#

I mean, I have no idea which is best, https://linebender.org/wiki/gpu/sorting/ seems to say on wgpu anyway things are not ideal. My issue is, I don't even want a fast one, even a bad one is so much work to implement.

native elbow
#

But probably the log2(N) default is too naive. I mean, you obviously can pack a lot more passes in a single dispatch. You can do "block sort" of e.g. (wild guess) 256~1024 particles locally in a single dispatch, then use multiple passes to scale to 1M. But doing a single mergesort pass per dispatch sounds like using 3 ALU per thread to read/compare/store 2 keys, and paying the cost of an entire dispatch just for that, so unless I'm missing something fundamental there's no way this is efficient.

native elbow
#

Also for the case of ribbons, normally most particles are already sorted from the previous frame. I think we can probably use that somehow to accelerate the sort.

weary abyss
#

So it's actually significantly fewer dispatches than I wrote there.

#

You only need multiple passes when you start needing to look beyond the current workgroup.

weary abyss
#

I would not recommend it here though ๐Ÿ™‚

weary abyss
#

If workgroup size is 256 then doing a double mergesort makes it ceil(log4(ceil(N/256))) + 1 passes I think. So:

  • <=256 particles: 1 dispatch
  • 1k particles: 2 dispatches
  • 10k particles: 4 dispatches
  • 100k particles: 6 dispatches
  • 1M particles: 7 dispatches
  • 10M particles: 9 dispatches
    This seems quite reasonable.
#

Though because every pass has to be indirect (as CPU doesn't know how many living particles there are) you'll probably be in the upper part of the range as far as CPU overhead. And of course double that if you haven't disabled wgpu compute validation.

By comparison, FidelityFX radix sort needs 1 dispatch per 4 bits of the key no matter what. So you're looking at 16 dispatches. Double that if you haven't disabled wgpu compute validation. 32 dispatches feels like it starts to hurt with how slow wgpu is.

native elbow
#

Iโ€™ve started looking seriously at GPU sorting. At the minute we have 64 bit keys, Iโ€™d like to reduce that but thatโ€™s a large piece of disruptive work so Iโ€™ll stick with that for now. And so as you said radix sort is out, especially FidelityFX, but even OneSweep (8 bits) is quite a lot of dispatches. So Iโ€™m looking at some merge sort from ModernGPU.

#

The merge path paper for parallel merging of large (> shared workgroup memory) sizes is super interesting. That should produce a decently fast
merge sort.

#

I already have a simple odd-even merge sort for smaller sizes working.

#

And, I wrote GPU tests this time ๐Ÿซก

weary abyss
#

Yep, I think mergesort is the way to go

near urchin
#

Upgraded to bevy 0.17 and noticed a pink flash as soon as I add the bevy_hanabi plugin at the start of the game.

Has anyone else experienced this?

#

(I use more than one camera, not sure if that might contribute to the issue?)

near urchin
# junior glen <@163405522257575936>

That is interesting that it might related to the font_atlas specifically if I combine bevy_hanabi with bevy_rich_text3d I get sometimes missing fonts when multiple entities are spawned.

(which is not the case if I disable the hanabi plugin)

mortal falcon
#

Just encountered something strange, I'm using Avian physics but I'm manually advancing Time<Virtual> to run the physics simulation at a set speed. Just by adding the HanabiPlugin to my app, the avian Time<Physics> stops advancing when Time<Virtual> advances

ember pumice
#

Is there a way to get the default hanabi particle to be round instead of square?

native elbow
ember pumice
#

Got it, thank you!

wise plinth
# wise plinth Hmm so as far as I understand, the only real way to bundle effects together is t...

I have updated my project to 0.17, and the issue is still there, but instead of spawning OnDie effects as Always effects, it doesn't spawn them at all. It's like the effect has capacity of 14 emitters and that's it. I'm thinking it might be linked to https://github.com/djeedai/bevy_hanabi/issues/510, because it's the same effect for both issues. Perhaps a sneaky bug with indices and/or event buffers, sadly can't reproduce it in examples

GitHub

๐ŸŽ† Hanabi โ€” a GPU particle system plugin for the Bevy game engine. - djeedai/bevy_hanabi

native elbow
#

I think 510 is very specific to 0.17 because the internals changed quite a bit. So not sure itโ€™s related. Also youโ€™d see some asserts if that was the case, do you?

#

Unfortunately thereโ€™s a long list of reasons for an effect to not spawn anything. Maybe running with trace-level logs could hint at whatโ€™s breaking but fair warning itโ€™s called โ€œtraceโ€ for a reason, itโ€™s very verbose.

near zealot
#

is there like... a first-time compilation or something that has to happen before an effect is visible? It seems like mine are never visible the first time they're invoked

weary abyss
#

@native elbow maybe we should add this question to the readme as a FAQ ๐Ÿ™‚

near zealot
weary abyss
#

Pretty much, yeah.

native elbow
#

The main part is the shader compile and thatโ€™s the same as any other rendering, thatโ€™s why most games precompile shaders on start. (technically itโ€™s the entire pipeline compile, but letโ€™s simply and say itโ€™s the shader)

#

Thatโ€™s not specific to Hanabi. You have the same issue with Bevy standard material. Except that thereโ€™s a single material shader there whereas Hanabi has multiple per effect.

near zealot
#

is there a typical pattern to follow or a function I can call to do that? Like, beyond just looping through my effects and running each one? Mostly wondering before I implement something that is redundant

native elbow
#

In 0.17 the effects should wait by themselves if the PSO is not ready so you shouldn't have to do anythign

near zealot
native elbow
#

Yes

native elbow
#

See CompiledParticleEffect::is_ready()

weary abyss
#

I'm switching UnaryOperator::X and friends to emit v[0] instead of v.x so they can be used on matrices too. Does that make sense?

native elbow
#

If that works I have nothing against it

#

Except maybe mildly less readable

tender pulsar
#

hi! ok so i have kind of two questions. right now i can set spawn location and velocity etc. in rust code by calling EffectProperties::set and having my pipeline use that for the relevant setters. but what if i want to set more than one? i'm .. not sure if i can use vectors like that ?
this kind of leads into the second question, which is really just "how do i make an Image explode into particles" but it ends up with the same issue: how do i spawn a large vector of known positions/velocities?

weary abyss
weary abyss
#

you might have to hack Hanabi to add an optional extra texture binding to the init modifier though. I don't think init has access to the existing one.

weary abyss
#

You'd have to ask djee

tender pulsar
#

i'm just not sure how to fit this all together yet. i'll try it and see assuming i need to do my own init modifier

#

fork+PR is easy

coral phoenix
#

Is there any way to write a custom shader (for both vertex & fragment) using a wgsl file, instead of using the ExprWriter?

weary abyss
cerulean dune
#

hey ! would you like a PR with this example i wrote ? showing off ribbons. ping me you want @.pcwalton or a maintainer ?

weary abyss
#

Hmmm, the performance problem I'm having is almost entirely one Hanabi compute shader that's taking 8ms/frame on a 4070 thonk

#

Ahhhh, pretty sure it's the sort

weary abyss
#

I spent time reading about GPU sorts again. Iโ€™m starting work on mergesort. It should take log2(N)/8 dispatches, where N is the total number of particles that need sorting. This shouldnโ€™t be too bad and is certainly likely to be much fewer dispatches than radix sort would be, in addition to being much simpler.

weary abyss
#

I prototyped mergesort. It's not fully working yet but it's tentatively looking like it should solve the performance problem: the sort phase is well under 1ms now for 600 particle effects and is dominated by the actual rendering cost.

weary abyss
#

Just implemented a parallel GPU mergesort, dropping the total compute time to 17% of the frame time under load and the sort time to <5% of the frame time I believe

#

It's slow as far as GPU sorts go, but optimizing it more isn't worth it

weary abyss
#

My Hanabi-Batched fork now has the parallel mergesort in it. Feel free to pull it upstream if you want

weary abyss
#

I'm currently removing use of the render-world ECS in Hanabi-Batched since I need to go retained for performance. I already pushed a change that avoids reextracting effects if they haven't changed or spawned anything, which saved me 1.5ms or so a frame.

weary abyss
#

Ok, locally in Hanabi-Batched I've reduced prepare_effects from ~650us to ~200us if nothing has changed. Working on batch_effects now as that's dominating the profile.

weary abyss
#

batch_effects now caches the sort buffers if there are no changes, improving its performance by 50%-70% in most cases.

weary abyss
#

Yikes, compile_effects is incredibly slow. I'm working on a fix, feel free to steal it from Hanabi-Batched when it's done

#

Yeah, dropped it from ~1.5ms to 0.07ms per frame ๐Ÿ™‚

junior glen
#

Last time I tried it failed, but it would be neat if I could use it for the next jam broovy

#

I imagine that would need to be done anyways for when Hanabi-Batched is upstreamed

weary abyss
#

I don't have a lot of time for that right now, but please feel free to file bug reports and/or send PRs

gilded fox
#

Is there a way to scale an event dynamically?

#

Meaning- if I have an effect playing I can change its translation and it would play from different places. I noticed that changing the transform's scale won't change the scale of the effect. Is there a way to achieve something similar?

midnight hull
#

Hi folks, opened up hanabi for the first time today to add a few trails to a prototype vehicle controller, and saw performance plummet a lot faster than I expected when ribbons were enabled, with relatively few particles (240 particles per ribbon x 4 ribbons was giving me a ~40ms bottleneck on relatively high end mac hardware).

Performance was great without ribbons enabled, and the problem seemed to scale directly with particle count. Is this expected with ribbons in the current state of the crate, or is there a chance that I'm holding it wrong?

weary abyss
weary abyss
#

I might need to implement reading from images in init/update modifiers. This shouldn't be too bad as I don't need per-instance images, just per-graph images. This is useful for efficiently implementing noise, or for efficiently sampling a curve that an artist defined by rasterizing the curve to a floating point texture and using the texture filtering hardware to sample.

weary abyss
#

Added some quaternion binary operators to Hanabi-Batched. Feel free to grab them upstream

tender pulsar
weary abyss
#

This is an example of sampling from a Perlin noise texture to apply acceleration

#

I called these textures "LUTs" (lookup textures) to distinguish them from the existing Hanabi textures, which are associated with the material. LUTs are associated with the asset, and you use the LutSample expression to sample them.

tender pulsar
weary abyss
#

Yeah, I should take the upgrade

#

Hanabi-Batched does have some bugs, some severe. It's considered experimental

tender pulsar
weary abyss
#

Feel free then ๐Ÿ™‚ I'll be fixing bugs myself of course

tender pulsar
weary abyss
#

Nope, I didn't realize 0.18 would be out today. I don't think the changes are that bad

ember kindle
#

internals didnt really change much, would expect an easy port. if anything it'll be mostly the wgpu upgrade

ember kindle
weary abyss
#

The issue I'm thinking about is that effects can randomly fail to appear because of a bug in retained mode, depending on the order in which things load. I tried to fix it but there are still issues.

ember kindle
#

wow, hanabi-batched has no issues, its bug free ๐Ÿ˜

weary abyss
#

The 0.18 upgrade will probably be in a separate branch because I want main to be buildable with my project, and I have to wait for my dependencies like egui to upgrade

ember kindle
#

id be interested in taking a look, is there a repro case for the retain bug?

weary abyss
#

it's extremely random

ember kindle
#

i see

weary abyss
#

Try the firework or worms examples

#

It has a tendency to reproduce on my complex effects that artists have created, which are unfortunately NDA ๐Ÿ™

weary abyss
#

I believe I fixed it, feel free to test

weary abyss
#

OK, I have direct lit particles working. Indirect not yet because I ran out of bind groups. I broke 2d though so I need to fix that

#

This depends on a Bevy PR I need to submit

weary abyss
#

I have indirect lit particles working now in a branch: https://github.com/pcwalton/bevy_hanabi/tree/lit-particles

The way I remain compatible with Bevy's PBR bind groups is quite a hack, but it ends up OK and actually let me clean up a little code.

It depends on a Bevy PR: https://github.com/bevyengine/bevy/pull/22526

Once the Bevy PR lands I'll clean it up and merge to Hanabi-Batched.

GitHub

A fork of Bevy Hanabi, the GPU-driven VFX system for Bevy, with improved performance and functionality - GitHub - pcwalton/bevy_hanabi at lit-particles

GitHub

My fork of Hanabi, the Bevy VFX system, now supports full PBR rendering, including indirect light. To do that, it has to create its own bind groups containing the light probe and irradiance volume ...

narrow gust
#

srry

#

which one is the official repo ?

#

is pcwalton's one the maintained one ?

lyric flume
# narrow gust which one is the official repo ?

the djeedai repo is the official one, pcwalton's fork is a fork they use for their studio with stuff they need for that use case, so has newer stuff at the moment with the goal for the official repo to upstream or implement similar things

sour dock
#

how can i make a particle rotate with an entity

sour dock
#

Found the solution !

simple falcon
#

I'm trying to orient myself to using this crate. When should I be using ExprWriter as opposed to Module directly?

simple falcon
#

It seems that all the examples use ExprWriter, but the README example uses Module::new. Why?

vast aurora
weary abyss
weary abyss
weary abyss
#

Just pushed the 0.18 upgrade for Hanabi-Batched.

sinful urchin
#

Hey, what's the difference between ColorBlendMode::Modulate and Add, because for some reason when I change it to Add, the particle effect seemingly only shows like a full second late. Idk if this is a known thing

sinful urchin
#

Also, the random attribute seems to always use the same seed when it is first summoned, which feels like it goes against being "random"? (this is on 0.17 btw)

weary abyss
#

I redid the way Hanabi-Batched handles visibility: invisible effects are no longer yanked from the ExtractedEffects structure but are instead just marked as inactive and skipped at the sorting stage. This should be fine because Hanabi-Batched uses a retained render world so they should have no overhead.

weary abyss
#

Pushed a whole bunch of fixes to Hanabi-Batched. You can also now query the dimensions of a LUT using the new lut_dimensions expression. I'm using the new LUT feature to make artist-defined curves that evaluate efficiently using the texture sampler, and also to make Perlin noise gradient based velocity perturbation.

near zealot
#

has anyone used bevy_hanabi (or batched) for rain?

weary abyss
#

(Water splash effects were the motivation to add PBR particles to Batched, in fact)

near zealot
weary abyss
near zealot
# weary abyss I'm actually not too familiar with the state of the art for rain in AAA games

I was taking a look at the batched bevy_hanabi and ran into some errors on 0.17 (using the commit before 0.18)

I'm probably going to wait until I update to 0.18 to try again, but it was failing to compile because of references to binding_index_to_textures which is private (at least in 0.17?). I'm mostly curious if you've seen that and if there's something I should know about. Again, I'm probably going to wait until I update so no worries if it's like.. a weird thing, it might just be my setup

weary abyss
#

I should add that to the README.

near zealot
#

ah, are you saying you currently have to be on bevy main? just making sure I understand

weary abyss
#

I think you can be on Bevy main, but then you would have to update the version numbers in Cargo.toml

#

That won't be the case for long though because #rendering-dev is planning to break everything Very Soon Now

ember kindle
#

it might already be broken tbh

weary abyss
#

Unfortunately, there's kind of a perfect storm of problems here. The sensible thing to do would be to just #[cfg] off the PBR stuff if you're on 0.18. But since you're talking about rain presumably you want PBR.

ember kindle
#

we could probably put the public-ing of the thing you need in 18.1

weary abyss
#

Locally my studio uses a private branch of the latest release version of Bevy, and I cherry pick back fixes

near zealot
#

I personally am using local forks for everything, so I can always just patch bevy if needed. I try to minimize the amount of that I do. But, also, I don't mind waiting ๐Ÿ‘

weary abyss
#

It'd be a 3 month wait at least

#

It just missed the 0.18 cutoff

near zealot
#

what is time

split quail
#

how to achieve rotation of a particule in Hanabi?

#

I don't find angularAcc or Rotation attribute

#

rotation over time not random rotation on init

weary abyss
#

Use the AXIS_X/AXIS_Y/AXIS_Z attributes

split quail
#

I am tring to make a healing circle ๐Ÿ˜„

#

There's a NEW Healing Spell Tutorial: https://youtu.be/ZCtEQrEOx_M

In this Unity tutorial we are going to see how to create effects for games by using the particle system Shuriken. This is the second tutorial of the series Special Effects for Games, and we learn how to create a healing effect. Great way to learn VFX in Unity.

Check out the gam...

โ–ถ Play video
split quail
#

can I make the texture facing the sky instead of facing the cam?

red trellis
weary abyss
#

Yeah, it was just discussed in here -- it requires a backport of a change that landed too late for the 0.18 cutoff

#

Unfortunately there's not much I can do.

red trellis
#

oh like just above?? ๐Ÿคฆโ€โ™‚๏ธ

#

haha ok thanks

weary abyss
#

Yeah

red trellis
#

backporting your bevy_pbr commit from 2 weeks ago seems to work. thanks!!

split quail
#

so can I make the texture not facing the camera? in OrientMode I dont understand the others mode than FaceCameraPosition.

split quail
#

if I have this paticule : using OrientMode::ParallelCameraDepthPlane or OrientMode::FaceCameraPosition

#

when i change it to OrientMode::AlongVelocity:

#

nothing. can you please explain to me the issue here?

sour dock
weary abyss
split quail
#

I make it plane with texture with spinning system ๐Ÿ˜„

sour dock
#
Caused by:
  In Device::create_bind_group, label = 'hanabi:bind_group:vfx_indirect_batch@0'
    Binding size 32 of Buffer with 'hanabi:buffer:batch_descriptor' label is less than minimum 256
#

getting this error

#

using this commit ff5709bb4a1106a8d015b8f7655cc129053c0f75

split quail
junior glen
#

@weary abyss hanabi-batched is not compiling for me. I suspect you're using it while pointing to a Bevy fork that has more things pub than upstream?

#

the offending field is from bevy_pbr

junior glen
weary abyss
#

Gimme a sec, I'll go ahead and put the stuff that doesn't build on 0.18 behind a feature flag.

#

Given that Hanabi-Batched is going to be the only supported way to use Hanabi on 0.18 for a while I'll try to make it minimally usable.

#

Pushed a change, now Hanabi-Batched should work on 0.18.

#

Also updated the README to mention 0.18 support and the new features in Hanabi-Batched.

weary abyss
#

If anyone is interested in being an official maintainer for Hanabi-Batched, feel free to get in touch with me... I don't have the time myself, but since Hanabi is such an important piece of Bevy infrastructure for shipping games it deserves official maintainership.

#

I'm aware that Hanabi-Batched has a bunch of regressions right now which I'm kind of drowning in, but given that it's feature complete as far as my VFX artists' needs right now are concerned, I suspect its stability/maturity is going to significantly improve over time.

#

(The main large missing feature that we might need is particle collisions against the depth buffer, but I'm holding off on that until my VFX artists tell me that they need it for something.)

quasi wharf
weary abyss
#

It's got too many bugs to upstream right now. It needs to be stabler before that happens

quasi wharf
#

i think that could be part of the upstreaming work, particularly useful as a way to familiarize with internals. we wouldn't just copy/paste anyway. this would be a majorly chunky task but i think worth it given how much work you've done here on top of the existing library's work

weary abyss
#

Iโ€™m still breaking stuff a lot and not always getting reports, which leads me to the belief that Iโ€™m the only one using a lot of Hanabi. That makes me nervous about upstreaming.

#

Iโ€™m not sure why at the moment. Possibly people just tend to use mesh animations and ad hoc CPU particle systems for VFX in Bevy today instead of Hanabi?

#

Bevy rendering is fast enough that most indie level games can get away with just spawning a bunch of quad meshes and animating them ad hoc in a system, which I bet a lot of folks are doing

quasi wharf
#

happy to defer to your experience here if you think it really shouldn't be upstreamed, but this seems as much social as technical. i think we could have strategies for mitigating risk (i.e. experimental mod, don't publicize too much to start) but it seems like a bit of chicken and egg in terms of being able to socialize the maintenance and also get more users to flesh out bugs. the alternative is that we do vfx from scratch which also could be a viable option, esp if you were willing to do a retrospective on all the requirements and battle tested production fixes you've made

weary abyss
#

I donโ€™t think VFX from scratch makes sense. From scratch is for when the architecture is unsound, but Hanabiโ€™s architecture is fine. It just needs a lot of cleanup, which is mostly a question of getting more contributors

#

My hesitancy for upstreaming is mostly that it's in too immature of a state for Bevy's relatively heavyweight review processes, honestly. There's no way I could find even one reviewer for most of my code changes, let alone 2

quasi wharf
# weary abyss My hesitancy for upstreaming is mostly that it's in too immature of a state for ...

that's really fair. cart is going to discuss some process changes soon that i think will help clarify whether this could be in scope, i.e. whether we have enough resources to staff that effort. particle systems are critical to the kind of installation art i want bevy to be able to support and so it's a major goal of mine, and i've spent a small but non-trivial amount of time reading hanabi's code base. i have some big items i still need to finish but would be willing to make myself available to make this a priority if we have enough other parties that would be willing to form a working group (i.e. contribute review)

weary abyss
#

Honestly, if you wanted to take over maintenance that'd be the biggest thing

#

Just to keep crates.io up to date and coordinate releases

quasi wharf
#

okay, totally. i'd be happy to do that in the meantime. let me clear some space next week to do a deep dive into the batched changes vs upstream hanabi

junior glen
#

unfortunately, I still get stuck at Web backend does not support BINDING_INDEXING extension

#

but this should be a start

junior glen
#

it's AI-generated, so I don't trust it terribly much, but it's working on 0.18 + WebGPU

junior glen
junior glen
weary abyss
#

Yeah, I never bothered to have a fallback for our non-bindless PBR path

junior glen
weary abyss
#

It does not ๐Ÿ™

junior glen
#

the heck

#

TIL

weary abyss
#

Yes, it is a huge source of frustration for me

junior glen
#

now it is for me as well haha

weary abyss
#

especially since the last non-bindless GPU on desktop shipped 14 years ago

junior glen
weary abyss
#

It's not that I don't want to support the browser, it's just that not having bindless is incredibly antiquated

junior glen
#

I also only target native, but for the jam web builds are kinda a must

weary abyss
#

tbh there is a bit of a chicken and egg problem here, in that Unity and Unreal don't use bindless either in their "normal" mesh rendering paths I don't believe, so there isn't a huge amount of demand for it

#

but 14 years is extreme

weary abyss
#

("normal" meaning non-RT, non-Nanite)

#

devs have been asking Unity to use it for years and Unity keeps refusing

#

citing lack of support

#

like I said, chicken and egg problem

junior glen
junior glen
lyric flume
junior glen
native elbow
#

@junior glen v0.18.0 is released now, supports Bevy 0.18. I quickly tested the wasm examples and they work. Let me know if there's an issue.

junior glen
#

that's great news, thanks a bunch!

#

and just in time for the jam too ๐Ÿ™‚

native elbow
#

๐Ÿ˜„

weary abyss
weary abyss
#

Things I (or someone else) will probably want to implement at some point:

  • Depth sorting for particles within a single system (every other particle engine has this; djee had the foresight to make our sort generic and I upgraded it to a mergesort so it shouldn't be too bad; annoying part is doing it per-view)
  • Collision against depth buffer (Unreal & Unity VFX Graph have this)
  • Skinned particles (Unreal has this)
  • Lights (Unreal has this; requires my Bevy GPU light clustering patch to land, but is actually quite easy after that!)
#

None of this requires architectural changes. Hanabi's the little VFX system that punches above its weight ๐Ÿ™‚

cloud solar
#

Anyone else noticed a pink screen on startup in bevy_hanabi since 0.18? This is on AdapterInfo { name: "Apple M1 Max", vendor: 0, device: 0, device_type: IntegratedGpu, driver: "", driver_info: "", backend: Metal }

#

Also happens in release mode: cargo run --example firework --release.

near zealot
quasi wharf
weary abyss
#

and that'd be awesome!

#

It's also fun "pure graphics" work ๐Ÿ™‚

quasi wharf
#

yes, i've been craving some

weary abyss
#

@quasi wharf You probably want to make a CollideWithDepthBuffer modifier that takes a reference to a camera entity. Itโ€™s a little weird because the app has to specify which depth buffer to collide against: there may not be just one and the particles will behave differently depending on which one you use!

small prism
#

Hi, I am looking to make a 2d snow effect with a foreground and a background. If I wanted to use say a ConformToSphereModifier is there a simple way to have it only effect particles from one of the layers and not the other? Thanks. Edit: Think I got it, just use different effects

gilded fox
#

My effects that have .with_simulation_space(SimulationSpace::Local) spawn on weird offsets. I saw nothing about parameter tweaking when setting simulation space to local in the docs. Have you guys ever encountered similar bugs in your code and fixed them?

gilded fox
#

Ok so I now know exactly what's happening- the Y axis of the effect's transform is ignored. I don't know why. It doesn't matter whether it's a child of another transform with an offset or not.

gilded fox
#

So it's a problem with the crate

#

(or with my computer)

gilded fox
tender pulsar
#

ok so i can't use 0.18 (yet) til all my deps update .. i'm still unclear on if the 'batched' branch solves my issues or not
fundamentally, really, i would love it if i could have a variable size vector of "particles to spawn" set somewhere and hanabi reads from that when there are new particles to spawn.. that would be great. the information would include e.g. position, velocity, gravity, lifetime

native elbow
# tender pulsar ok so i can't use 0.18 (yet) til all my deps update .. i'm still unclear on if t...

Thatโ€™s a bit complex to do by design, and probably quite inefficient. The entire point of the Hanabi design is that particles are initialized on GPU directly by a compute shader when they spawn, which is much faster and avoids having to upload data from CPU, leaving the limited bandwidth for other usage. You can workaround this by using properties, uploading the CPU data you need in them, and reading it back from GPU with a property expression in the init pass. But this is quite convoluted, has the inefficiencies mentioned, so Iโ€™d suggest to reconsider why you need this in the first place. If you have a use case not covered by GPU init (for example, spawn particles exactly at a bunch of positions calculated by another CPU system which is not doable on GPU for example because itโ€™s from an animation), could you please open an issue on GitHub and describe it in details so we can discuss how to best implement it?

tender pulsar
#

i'm just evaluating options, and 'mimic the behavior of individual spawn particle calls' didn't seem like the worst option