djeedai / bevy_hanabi

🎆 Hanabi — a GPU particle system plugin for the Bevy game engine.
Apache License 2.0
927 stars 73 forks source link

Remove the gaps between particle geometry in the Ribbon render modifier #332

Open jakkos-net opened 4 months ago

jakkos-net commented 4 months ago

Describe the solution you'd like

Currently each particle in a ribbon creates it's own disconnected geometry, this leads to gaps in the ribbon. See below image from the "ribbon" example: image

It'd be cool if we could have consecutive particles share verts so that it'd be one continuous ribbon :)

djeedai commented 4 months ago

This looks more like a bug to me. @pcwalton any idea what's going on or a limitation I'm not aware of regarding ribbon joints?

djeedai commented 4 months ago

Oh I guess we never implemented miter joints so it makes sense. We only render a quad from one particle to the next, without looking at the previous one for example.

image

djeedai commented 4 months ago

Changing from Bug to Enhancement because I think I remember this was a known limitation of that first ribbon/trail version, we didn't want to complexify right away. So that's more of a feature request to improve the current implementation.

mrteathyme commented 4 months ago

Changing from Bug to Enhancement because I think I remember this was a known limitation of that first ribbon/trail version, we didn't want to complexify right away. So that's more of a feature request to improve the current implementation.

Preface, im not too well versed in graphics programming so I could be talking out my ass here.

But couldnt you just fill in those gaps with a single tri? youve got 3 vertices there (the single vertex that the two quads touch on when following the curve, and the two hanging vertices where they arent touching) so you could render a tri with those 3 vertices, shouldnt introduce too much complexity that way and should be relatively cheap since theres nothing to compute really.

jakkos-net commented 4 months ago

But couldnt you just fill in those gaps with a single tri?

Ideally you'd want to have the quads share verts (e.g. the last 2 verts of one quad are the first 2 verts of the next), you don't need additional tris.

However, it looks to me from glancing at the RibbonModifier code that the current vertex shader generation relies on the idea that each particle gets rendered as a single quad (specified by axes, size, and position).

I don't think there's a practical way to get all the quads join up nicely with the current system. Even if you skewed the axes to make the quads into parallelograms you'd have to look at every previous particle to work out the correct angle for the current particle, so not practical lol.

So to implement this feature, I think you'd either need to change how the vertex shader code gen works for all effects, or make the ribbon effect code gen separate from the normal effects - both sound annoying to do :grin:

djeedai commented 4 months ago

I don't think there's a practical way to get all the quads join up nicely with the current system.

Plot twist, there is! Each trail particle stores the index of its previous and next particle. This is how we can draw a quad between two consecutive particles. So it's "just" a matter of looking at a third particle in the chain to determine the orientation of the edge shared by two consecutive quads.

jakkos-net commented 4 months ago

Plot twist, there is! Each trail particle stores the index of its previous and next particle. This is how we can draw a quad between two consecutive particles. So it's "just" a matter of looking at a third particle in the chain to determine the orientation of the edge shared by two consecutive quads.

I only quickly looked at the code, so sorry if I'm being dumb 😁.

It looked like the only way to change the orientation of the edge was through the axis_ variables, but this would mean that when you set one edge of the quad you'd also be setting the other edge. So to calculate the orientation for a particle you'd also need to know the orientation of the previous particle which would depends on it's previous particle, which depends on it's previous particle... etc

Also while I'm here asking possibly dumb questions: the ribbon modifier code declares that it needs both NEXT and PREV attributes, but isn't it just using the current and next particles, not the prev?

djeedai commented 4 months ago

I only quickly looked at the code, so sorry if I'm being dum

No you're perfectly right that it's a bit more complicated, you need indeed some changes in the vertex shader I think.

Also while I'm here asking possibly dumb questions: the ribbon modifier code declares that it needs both NEXT and PREV attributes, but isn't it just using the current and next particles, not the prev?

I believe this is correct and was in anticipation if this very feature, which we culled in the first version to keep things simple and easier to review.

jakkos-net commented 4 months ago

Ah, I get it now! Thanks :)