# Particle trails using feedback transform method

**URL:** <https://discourse.libcinder.org/t/particle-trails-using-feedback-transform-method/946>\
**Category:** Using Cinder\
**Created:** [November 8, 2017, 9:01pm UTC](https://discourse.libcinder.org/t/particle-trails-using-feedback-transform-method/946 "2017-11-08T21:01:33Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![sandblasted7](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/sandblasted7/32/675_2.png) [@sandblasted7](https://discourse.libcinder.org/u/sandblasted7)\
**Post date:** [November 8, 2017, 9:01pm UTC](https://discourse.libcinder.org/t/particle-trails-using-feedback-transform-method/946/1 "2017-11-08T21:01:33Z")

</div>

Hello,

I am in the process of building a particle system which at the moment is capable of calculating movements based on transform feedback method. Could anyone give some ideas on how to create a trail effect using the history of the positions?

I have 2 VAOs and 2VBOs. The VBOs contain the current and previous position values.  
If I want to keep track of say 10 previous positions to create the trail effect, would I declare another VBO with 10 times the size of the VBO that contains all current positions? Or should the initial 2 VBOs be created with 10 times the size of the initial particle count? While updating the destination VBO, how would I only update the new values and push back the older positions further down the buffer? I would really appreciate it if you could give me some tips of solving this issue. Thanks and regards

The following thread talks about the same issue, but I am not sure how the indices are being saved and used to retrieve value from the buffer.

> [@Transform feedback particle trails](http://discourse.libcinder.org/t/transform-feedback-particle-trails/521):
>
> Hi, 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 …

Here is a snippet of my code:

In setup():

```
int trailLength = 10;
particles.assign(trailLength*NUM_PARTICLES, SingleParticle()); // this is the vector of particles containing the init pos

//creating buffers
mParticleBuffer[mSourceIndex] = gl::Vbo::create(GL_ARRAY_BUFFER, particles.size() * sizeof(SingleParticle),             
    particles.data(), GL_STATIC_DRAW);
mParticleBuffer[mDestinationIndex] = gl::Vbo::create(GL_ARRAY_BUFFER, particles.size() * sizeof(SingleParticle),     
    nullptr, GL_STATIC_DRAW);

```

In update():

```
// Bind the source data (Attributes refer to specific buffers).
gl::ScopedVao source(mAttributes[mSourceIndex]);
// Bind destination as buffer base.
gl::bindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, mParticleBuffer[mDestinationIndex]);
gl::beginTransformFeedback(GL_POINTS);

// Draw source into destination, performing our vertex transformations.
gl::drawArrays(GL_POINTS, 0, trailLength * NUM_PARTICLES);

gl::endTransformFeedback();

```

---

<div class="post-metadata">

**Author:** ![gabor\_papp](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/gabor_papp/32/769_2.png) [@gabor\_papp](https://discourse.libcinder.org/u/gabor_papp)\
**Post date:** [November 9, 2017, 7:07am UTC](https://discourse.libcinder.org/t/particle-trails-using-feedback-transform-method/946/2 "2017-11-09T07:07:19Z")

</div>

Hi,

> [@sandblasted7](#):
>
> should the initial 2 VBOs be created with 10 times the size of the initial particle count

Yes, this is how I did it based on the suggestions from @seph.  
What would be good idea is to separate the particle attributes to individual Vbo’s. This will probably make your life easier.

```auto
mParticlePositionsBuffer[mSourceIndex] = gl::Vbo::create( GL_ARRAY_BUFFER, particles.size() * sizeof(vec4), particlePositions.data(), GL_STATIC_DRAW );

```

What you also need to do is create a buffer texture that you can read old positions from in the shader.

```auto
mPositionBufferTextures[0] = gl::BufferTexture::create( mParticlePositionsBuffer[0], GL_RGBA32F );
mPositionBufferTextures[1] = gl::BufferTexture::create( mParticlePositionsBuffer[1], GL_RGBA32F );

```

Now it helps that you have `vec4` size positions only in the Vbo.  
You also need to store the id of the particle, you can do it in the `w` part of the `vec4`.

To update you do something like this in your transform feedback shader:

```auto
const int kTrailSize = 10;

layout (location = 0) in vec4 iPosition;

uniform samplerBuffer uTexPositions;

out vec4 oPosition;

void main()
{
    int id = int( iPosition.w );
    if ( ( id % kTrailSize ) == 0 )
    {
        // head of trail, update as you would do it without trails
    }
    else
    {
        // part of trail, copy previous position
        oPosition = texelFetch( uTexPositions, id - 1 );
        oPosition.w = iPosition.w;
    }
}

```

---

<div class="post-metadata">

**Author:** ![paul.houx](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/paul.houx/32/31_2.png) [@paul.houx](https://discourse.libcinder.org/u/paul.houx)\
**Post date:** [November 9, 2017, 9:55am UTC](https://discourse.libcinder.org/t/particle-trails-using-feedback-transform-method/946/3 "2017-11-09T09:55:33Z")

</div>

> [@gabor\_papp](#):
>
> You also need to store the id of the particle, you can do it in the w part of the vec4.

Instead of casting a float to an int, you might want to use [floatBitsToInt](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/floatBitsToInt.xhtml) and [intBitsToFloat](https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/intBitsToFloat.xhtml) for that.

---

<div class="post-metadata">

**Author:** ![sandblasted7](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/sandblasted7/32/675_2.png) [@sandblasted7](https://discourse.libcinder.org/u/sandblasted7)\
**Post date:** [November 9, 2017, 3:31pm UTC](https://discourse.libcinder.org/t/particle-trails-using-feedback-transform-method/946/4 "2017-11-09T15:31:54Z")

</div>

Thank you @gabor_papp for the helpful description. I really appreciate it. I will give this a shot and see how things look.  
And thank you @paul.houx for the suggestion. Cheers!

---

<div class="post-metadata">

**Author:** ![roxlu](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/roxlu/32/509_2.png) [@roxlu](https://discourse.libcinder.org/u/roxlu)\
**Post date:** [January 11, 2018, 1:57pm UTC](https://discourse.libcinder.org/t/particle-trails-using-feedback-transform-method/946/5 "2018-01-11T13:57:07Z")

</div>

Hey, just wanted to share some experiments I did with GPU based ribbons using transform feedbacks. There is not a lot info online and I only found some talk about xfb ribbons on this forum. I’m experimenting with ribbons using an index buffer to select the positions that make up the ribbons. For now just 2D, but it shows one approach you can take: [https://bitbucket.org/roxlu/2018-002-gpu-ribbons](https://bitbucket.org/roxlu/2018-002-gpu-ribbons)

---

<div class="post-metadata">

**Author:** ![Malfunkn](https://yyz2.discourse-cdn.com/flex030/user_avatar/discourse.libcinder.org/malfunkn/32/761_2.png) [@Malfunkn](https://discourse.libcinder.org/u/Malfunkn)\
**Post date:** [August 22, 2018, 3:48am UTC](https://discourse.libcinder.org/t/particle-trails-using-feedback-transform-method/946/6 "2018-08-22T03:48:13Z")

</div>

So how would one approach a compute shader method? I hear it’s pretty grand. I admit, I’m freshly new to compute shaders. However, using [avseol’s ssbo example for example](https://github.com/avseoul/ci_ssbo_sample)…

Would it just be a matter of adding a massive ssbo or vbo that would hold the FLOCK\_SIZE\*TRAILSIZE positions and trail ID?  
I was thinking, since we are only updating the newest position on the trail, perhaps we can just copy the vbo positions into a larger vbo at a specific offset in the main app.  
I was digging around and came across CopyBufferSubData. Theres not really a ton out there on this flocking trails subject but I did also come across this [massive hlsl Unity code](https://github.com/fuqunaga/GPUTrail/tree/master/Assets/Packages/GPUTrail/Shaders) which would be cool to implement some of the ideas but I’m having a hard time figuring out the overall technique in the main app.  
I even looked into texture3D since most every resource refers to smaller particle systems that use textures but figured I’d get some opinions.
