Slightly modified gpuParticle example went wrong

Hello everyone,
I first want to say that I’m really happy that I found openframeworks as my starting point for learning computer science stuffs, since it really is helping and motivating me to learn about various stuffs regarding cs.

Here comes my question.
I’m now trying to understand the gl/gpuParticleSystemExample, and trying to make a little change to it, to figure out if I’m understanding it right.

I changed the velUpdate.frag file just a bit to make the particles to have different behavior.

#version 150

uniform sampler2DRect backbuffer;   // previous velocity texture
uniform sampler2DRect posData;      // position texture
uniform sampler2DRect uniqVal;
uniform vec2 mousePos;
uniform float timestep;

in vec2 vTexCoord;

out vec4 vFragColor;
    
void main(void){
    // Get the position and velocity from the pixel color.
    vec2 pos = texture( posData, vTexCoord).xy;
    vec2 vel = texture( backbuffer, vTexCoord ).xy;
    float uniq = texture(uniqVal, vTexCoord).x;
    
    vec2 acc = normalize(mousePos - pos) * uniq;
    vel += acc;
    
    // Then save the vel data into the velocity FBO.
    vFragColor = vec4(vel.x,vel.y,0.0,1.0);
}

I’m sharing just this shader file, since everything is just as how it was but this part.
I was trying to make the particles circling around the mouse position with some offset(which is made and passed as texture named uniqVal, which is ofRandom(0.0, 0.1) for each particle).
And of course, I also added an uniform to pass the mouse position.

But the particles are just flying off to the bottom of the screen.
I tried to figure out what’s wrong for few days, but couldn’t find any clue of it, because this simple code of circling particles worked just fine as I wrote it first without any shader.

Any tips regarding this problem will definitely make me happy, Thanks!

You must normalize the mouse position that is fed to the shader like this:

updateVel.setUniform2f("mousePos", ofGetMouseX()/(float)ofGetWindowWidth(), ofGetMouseY()/(float)ofGetWindowHeight());

This is because the particle positions are remapped to screen coordinates in render.vert.

    // Maps the position from the texture (from 0.0 to 1.0) to
    // the screen position (0 - screenWidth/screenHeight)
    //
    pixPos.x *= screen.x;
    pixPos.y *= screen.y;

Thank you for the reply! :slight_smile: @lshoek

The mouse position has been already normalized exactly like your answer.

Since I couldn’t solve this problem until now,
I guess its better to share the whole code, although its almost identical to the original example.

github repo

The change I made is like:

  1. I added a Texture passing to the velUpdate shader, which contains uniqVal for each pixels respectively.

  2. Also, I added a uniform2f passing to the velUpdate containing the mouse position. I wanted it to test with mouse interaction.

  3. I modified the render.geom shader. This is because I wanted to get rid of the spark texture.
    I made it to being a single vertex, so that I have just a bunch of small dots on the screen instead.

Thanks :slight_smile:

Took a quick look at your code and found the issue! posPingPong and uniqValFbo use the same texture location. Just change either to 2 and you’re good!

updateVel.setUniformTexture("posData", posPingPong.src->getTexture(), 1);
updateVel.setUniformTexture("uniqVal", uniqValFbo.getTexture(), 1);
1 Like

Ohhh, what a shame… :hot_face:
I have no idea how I could have miss this.

Big thanks @lshoek !
Now I can go further with experimenting it!

1 Like