Transform feedback particle trails


I’m thinking about adding trails for a transform feedback particle system. What would be the best way to do this? I could add some vertex attributes to store previous particle positions and generate the trail in a geometry shader. But since the number of attributes are limited, it would result in a quite short trail, I think. I’m ping-ponging 2 vbo’s in the transform feedback, so theoretically I could use more vbo’s to hold the positions, but I’m not sure how to connect them as a trail. Is this possible to do this in an efficient way? Any suggestions would be appreciated.



I have used transform feedback to render trails.
some old works: inkfall and waterfall for teamlab.

I’m not sure whether you are going to render the trails as line or just particles,
but here is what I did:

2 VBOs to hold all vertex data (for pingpong);
2 BufferTexture referring to the same vertex data, so that you could access all vertices in the update shader;
1 VBO storing index data(which was static in my case): I render lines with GL_LINES_ADJACENCY_EXT format, so that I could separate vertices into multiple lines.

So these structure will be like:
position vbo: line1[vert1, vert2, vert3, vert4, vert5, vert6], line2[vert1, vert2, vert3, vert4, vert5, vert6]
segment vbo: line1[0,1,2,3, 1,2,3,4, 2,3,4,5], line2[6,7,8,9, 7,8,9,10, 8,9,10,11]
so that when you render, you will have 2 lines in this case.

To find the corresponding index of predecessor vertex, you probably need another VBO to store index of each vertex in the specific line, like in the above case, it would be: line1[0,1,2,3,4,5], line2[0,1,2,3,4,5].

Hopefully this makes sense to you…
I also think if you don’t mind losing support for OS X,
using compute shader would probably give you more freedom when updating trails.



Thanks. The video links are awesome. Teamlab is a big favorite.

It’s still not perfectly clear. Rendering particles or lines hopefully won’t be a problem, but I still don’t get it how you store the positions from the previous frames. I’m using two Vao’s and two Vbo’s like in the ParticleSphereGpu sample. One of them holds the current frame position, the other one holds the previous frame position, but where are you storing the previous frames?
Or if you want to have 10 long trail. you have the Vbo 10 times bigger than the number of particles and update every 10th to calculate the new position, and for the other 9 you only read the previous positions from the BufferTexture and store them?

Yes, I did use more space to store all trail datas.

So say each of my long trails have ~150 verts, then every frame only the first vertex in each trail will be updated.
And the other 149 verts will just move one slot backwards.

Performance wise its not bad - the inkfall was running on an Radeon r9 270, with 3000 trails, every trail holds 200 vertices, it reached about 110fps with a pretty complex geometry shader for the specific ink stroke trail shapes.

1 Like

Thanks! It seems I have to sacrifice some of the 1 million particles for the sake of the trails then :).
I will try to implement it. Thanks again for the explanation.

No problem :slight_smile:

Another thought, if you want the trail size can be calculated dynamically instead of static indices,(say crazily active particles have 100 vert trails and lazy ones have 10) maybe you could try use compute shaders - for it could write multiple outputs (vertex positions and trail indices) in the same render pass. With transform feedback, you would probably have to leave the indices static. And this will probably save you some memory…
Have not tried it, but could be helpful if large portions of your particles won’t move that much every frame.


At the moment, I’m on OS X, which unfortunately does not support compute shaders. So, I’m stuck with transform feedback, but I’m good with static trail size for now. Maybe later, when this version works :). Thanks.

Thank you again. Works perfectly!


Added some related info here: Particle trails using feedback transform method