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:
[highlight=compute shader]
"#version 430
" +
"layout (local_size_x = 1000) in;
" +
"
" +
"struct Particle
" +
"{
" +
" vec4 pAnds;
" + //position and size
" vec3 velocity;
" +
" float lifespan;
" +
" float age;
" +
"};
" +
"
" +
"layout (std430, binding = 0) buffer members_in
" +
"{
" +
" Particle particle[];
" +
"} input_data;
" +
"
" +
"shared int shared_newParticles = 480 / 60;
" +
"
" +
"void main()
" +
"{
" +
" int id = int(gl_GlobalInvocationID.x);
" +
"
" +
" float timestep = 1.0 / 60.0;
" +
"
" +
" if (input_data.particle[id].lifespan > 0)
" +
" {
" +
" input_data.particle[id].age += timestep;
" +
"
" +
" if (input_data.particle[id].age > input_data.particle[id].lifespan)
" +
" {
" +
" input_data.particle[id].lifespan = 0;
" +
" }
" +
" else
" +
" {
" +
" input_data.particle[id].pAnds.y += -0.1;
" +
" }
" +
" }
" +
" else if (input_data.particle[id].lifespan == 0)
" +
" {
" +
" if (shared_newParticles > 0)
" +
" {
" +
" 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);
" +
" input_data.particle[id].lifespan = 1.0;
" +
" input_data.particle[id].age = 0.0;
" +
"
" +
" shared_newParticles–;
" +
" }
" +
" }
" +
“}”
Setting up buffers:
```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?