-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement particle groups, enabling simple particle trails. #296
Conversation
Oh, that limit of 4 dynamic offsets is terribly annoying. I'll have to think of how to work around it. |
This is if I remember the default for "downlevel" in wgpu, and therefore is expected to be a conservative value for Web. I don't know how many users we'd lose (especially on Web) by raising that limit, but if possible I'd really like to avoid doing so. Let me know if I can help (discussion, review, ...) find a solution. |
16c0ba9
to
0c49f95
Compare
This commit essentially allows multiple effects to share the same underlying buffer. Such sub-effects are known as *particle groups*. An effect may have up to 32 particle groups, each with its own capacity. Every modifier specifies which particle groups it affects. Spawners always spawn into particle group 0; this restriction was implemented for simplicity and can be lifted later. A new modifier has been added, `CloneModifier`. This allows particles to be duplicated into a group on a fixed rate. By cloning particles into a group, particle trails can be created. It's intended that a node graph can be layered on top of particle groups in the future. Particle groups are the most efficient way I can think of to implement node graphs in any case, so this seems to me to be a step toward a node-based editor. Currently, init modifiers don't run on cloned particles. Their age is, however, reset to 0 if present, as this is typically the most useful behavior. Internally, each particle group receives its own update and render invocation. This reduces branching in both shaders, simplifies much of the bookkeeping, and enables ribbon rendering for trails in the future (needed for weapon effects, etc.) The new `worms` example illustrates how trails can be produced with this groups feature.
CI looks good now. I worked around the dynamic offsets limit by switching to separate per-effect bind groups for init and update. This is a bit unfortunate, but shouldn't affect performance much since we aren't batching anyhow. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't finish, and most comments are minor in the grand scheme of things ;) but I took the worms
example and added a loop around it, to spawn 2 similar worms effects, except one has double the particle size (so we can see which is which). Unfortunately, the second effect has no trail, so there's a bug. See how the bigger head particles have no trail.
Fix the rendering of multiple effects, which was broken due to the use of a `HashMap<>` keyed by the cached render pipeline ID, which is not unique by definition (the cache is here to prevent duplicates, and reuse a shader across effects and groups if the code is the same). The core issue comes from the fact `EffectBatch` used to drive rendering, mapping 1:1 with entities spawned in the render world to emit draw calls. With the grouping of multiple draw calls per `EffectBatches` (renamed from `EffectBatch`), each draw call of a group inside an effect shares the same `EffectBatches` so has lost access to its own unique group index. To solve this, add a new `EffectDrawBatch` component, unique per draw call, and containing the group index. For simplicity, this new component references the existing `EffectBatches`, so we don't need to change everything and we can share the data across groups. This adds one level of indirection in the draw call, but hopefully ECS is fast enough for the low number of calls we typically have. We can revisit later.
Addressed review comments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Merging as is, we can refine later if needed. Thanks a lot, this is an awesome change! 🥳
This commit essentially allows multiple effects to share the same underlying buffer. Such sub-effects are known as particle groups. An effect may have up to 32 particle groups, each with its own capacity. Every modifier specifies which particle groups it affects. Spawners always spawn into particle group 0; this restriction was implemented for simplicity and can be lifted later.
A new modifier has been added,
CloneModifier
. This allows particles to be duplicated into a group on a fixed rate. By cloning particles into a group, particle trails can be created.It's intended that a node graph can be layered on top of particle groups in the future. Particle groups are the most efficient way I can think of to implement node graphs in any case, so this seems to me to be a step toward a node-based editor.
Currently, init modifiers don't run on cloned particles. Their age is, however, reset to 0 if present, as this is typically the most useful behavior.
Internally, each particle group receives its own update and render invocation. This reduces branching in both shaders, simplifies much of the bookkeeping, and enables ribbon rendering for trails in the future (needed for weapon effects, etc.)
The new
worms
example illustrates how trails can be produced with this groups feature.This PR obsoletes #288. Feedback is very welcome!