Particle trails using feedback transform method


#1

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.

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();

#2

Hi,

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.

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.

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:

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;
    }
}

#3

Instead of casting a float to an int, you might want to use floatBitsToInt and intBitsToFloat for that.


#4

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!


#5

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


Transform feedback particle trails