Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 2 of 2

Thread: Particles move toward a weird direction

  1. #1
    Junior Member Newbie
    Join Date
    Mar 2015
    Posts
    20

    Particles move toward a weird direction

    I want to implement a particle system simulating the raining effects with a compute shader. In the fragment shader, I simply discard the pixel when the lifespan is 0 (not sure if it's a good way). The living particles are expected to move along -y direction, and those dead should not be displayed. But the result comes out to be that all particles are displayed, and those alive behave correctly, and others which is dead turn out to move in a wrong direction -x. Here is the compute shader code:

    Code compute shader:
                "#version 430                                       \n" + 
                "layout (local_size_x = 1000) in;                   \n" + 
                "                                                   \n" + 
                "struct Particle                                    \n" + 
                "{                                                  \n" + 
                "   vec4 pAnds;                                     \n" + //position and size
                "   vec3 velocity;                                  \n" + 
                "   float lifespan;                                 \n" + 
                "   float age;                                      \n" + 
                "};                                                 \n" + 
                "                                                   \n" + 
                "layout (std430, binding = 0) buffer members_in     \n" + 
                "{                                                  \n" + 
                "   Particle particle[];                            \n" + 
                "} input_data;                                      \n" + 
                "                                                   \n" + 
                "shared int shared_newParticles = 480 / 60;         \n" + 
                "                                                   \n" + 
                "void main()                                        \n" + 
                "{                                                  \n" + 
                "   int id = int(gl_GlobalInvocationID.x);          \n" + 
                "                                                   \n" + 
                "   float timestep = 1.0 / 60.0;                    \n" + 
                "                                                   \n" + 
                "   if (input_data.particle[id].lifespan > 0)       \n" + 
                "   {                                               \n" + 
                "       input_data.particle[id].age += timestep;    \n" + 
                "                                                   \n" + 
                "       if (input_data.particle[id].age > input_data.particle[id].lifespan)     \n" + 
                "       {                                           \n" + 
                "           input_data.particle[id].lifespan = 0;   \n" + 
                "       }                                           \n" + 
                "       else                                        \n" + 
                "       {                                           \n" + 
                "           input_data.particle[id].pAnds.y += -0.1;    \n" + 
                "       }                                           \n" + 
                "   }                                               \n" + 
                "   else if (input_data.particle[id].lifespan == 0) \n" + 
                "   {                                               \n" + 
                "       if (shared_newParticles > 0)                \n" + 
                "       {                                           \n" + 
                "           input_data.particle[id].pAnds = vec4(input_data.particle[id].pAnds.x, 20, input_data.particle[id].pAnds.z, input_data.particle[id].pAnds.w);        \n" + 
                "           input_data.particle[id].lifespan = 1.0; \n" + 
                "           input_data.particle[id].age = 0.0;      \n" + 
                "                                                   \n" + 
                "           shared_newParticles--;                  \n" + 
                "       }                                           \n" + 
                "   }                                               \n" + 
                "}"

    Setting up buffers:
    Code java:
    		int dataSize = (4 + 3 + 1 + 1) * Float.SIZE / 8;//
    		int buffSize = particleCount * dataSize;
     
    		gl.glGenBuffers(vboCount, vboBuff);
     
    		gl.glBindBuffer(GL4.GL_SHADER_STORAGE_BUFFER, vboBuff.get(0));
    		gl.glBufferData(GL4.GL_SHADER_STORAGE_BUFFER, buffSize, null, GL4.GL_DYNAMIC_COPY);
     
                    //generate vao
    		gl.glGenVertexArrays(vaoCount, vaoBuff);
                    gl.glBindVertexArray(vaoBuff.get(0));
     
    		gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, vboBuff.get(0));
    		gl.glVertexAttribPointer(verPosLoc, 4, GL4.GL_FLOAT, false, dataSize, 0);
    		gl.glVertexAttribPointer(lsLoc, 1, GL4.GL_FLOAT, false, dataSize, (4 + 3) * Float.SIZE / 8);
     
    		gl.glVertexAttribDivisor(verPosLoc, 1);
    		gl.glVertexAttribDivisor(lsLoc, 1);
     
    		gl.glEnableVertexAttribArray(verPosLoc);
    		gl.glEnableVertexAttribArray(lsLoc);
     
                    gl.glBindBuffer(GL4.GL_ARRAY_BUFFER, vboBuff.get(0));
     
    		ByteBuffer byteBuff = gl.glMapBufferRange(GL4.GL_ARRAY_BUFFER, 0, buffSize, GL4.GL_MAP_WRITE_BIT | GL4.GL_MAP_INVALIDATE_BUFFER_BIT);
     
    		for (int i = 0; i < particleCount; i++)
    		{
    			byteBuff.putFloat(((float) Math.random() - 0.5f) * 20f);
    			byteBuff.putFloat(((float) Math.random() * 25));// + 25f
    			byteBuff.putFloat(((float) Math.random() - 0.5f) * 20f);
    			byteBuff.putFloat(0.02f);
     
    			byteBuff.putFloat(0);
    			byteBuff.putFloat(-16f);
    			byteBuff.putFloat(0);
     
    			byteBuff.putFloat(0);
     
    			byteBuff.putFloat(0);
    		}
     
    		gl.glUnmapBuffer(GL4.GL_ARRAY_BUFFER);

    I have narrowed down the error, it should be the std430 qualifier that caused the problem. But why?
    Last edited by A_Shuang; 04-08-2015 at 11:03 PM.

  2. #2
    Intern Newbie
    Join Date
    Sep 2014
    Posts
    30
    Quote Originally Posted by A_Shuang View Post
    I have narrowed down the error, it should be the std430 qualifier that caused the problem. But why?
    Because of alignment rules. With std430 layout a vec4 is 16-byte aligned, so your struct Particle is also 16-byte aligned. The size of the struct is rounded up to a multiple of the alignment, so the struct actually takes 48 bytes, not 9 * 4 = 36 bytes as your Java code expects.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •