Jump to content

  • Log In with Google      Sign In   
  • Create Account


#ActualStanLee

Posted 04 October 2012 - 10:02 AM

Hello,

I am new to OpenGL and currently working on a particle system which makes use of the compute shader. I've got two questions. The first is about the compute shader itself. I create the particles and store them in shader storage buffer so I can access their position in the compute shader. Now I want to create a thread for every particle, which computes its new position. So I dispatch an one dimensional work group.
#define WORK_GROUP_SIZE 128
_shaderManager->useProgram("computeProg");
glDispatchCompute((_numParticles/WORK_GROUP_SIZE), 1, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
Compute shader:
#version 430
struct particle{
	 vec4 currentPos;
	 vec4 oldPos;
};

layout(std430, binding=0) buffer particles{
	 	 	 struct particle p[];
};

layout (local_size_x = 128, local_size_y = 1, local_size_z = 1) in;
void main(){
	 uint gid = gl_GlobalInvocationID.x;

	 p[gid].currentPos.x += 100;
}


But somehow not all particles are affected. I am doing this the same way it was done in this example but it doesn't work.
http://education.sig...eShader_6pp.pdf

When I want to render 128.000 particles, then the code above would dispatch 128.000/128=1.000 1-dimensional work groups and each of them would have the size of 128. Doesn't it thus create 128*1.000 = 128.000 threads which execute the code in the compute shader above and thus all particles are affected? Each thread would have a differen ID at gl_GlobalInvocationID.x because all work-groups are 1-dimensional Am I missing something?

My other question is relating to glDrawArrays().
The vertex shader receives all the vertices from the shared-storage-buffer and passes them through to the geometry shader, where I emit 4 particles to create a quad on which I map my texture in the fragment shader. The structure which is stored in the shared-storage-buffer for every particle looks like this:
struct Particle{
glm::vec4 _currPosition;
glm::vec4 _prevPosition;
};
When I draw the scene I do the following:
glBindBuffer(GL_ARRAY_BUFFER, BufferID);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), 0);
glEnableVertexAttribArray(0);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_POINTS, 0, _numParticles*2);
glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);

Somehow when I just call glDrawArrays(GL_POINTS, 0, _numParticles) not all particles are rendered. Why does this happen?
I would suggest the number of the vec4-vectors in the particle-struct is the reason but I am not sure. Could somebody explain it please? Posted Image

Regards,
StanLee

#2StanLee

Posted 04 October 2012 - 10:01 AM

Hello,

I am new to OpenGL and currently working on a particle system which makes use of the compute shader. I've got two questions. The first is about the compute shader itself. I create the particles and store them in shader storage buffer so I can access their position in the compute shader. Now I want to create a thread for every particle, which computes its new position. So I dispatch an one dimensional work group.
#define WORK_GROUP_SIZE 128
_shaderManager->useProgram("computeProg");
glDispatchCompute((_numParticles/WORK_GROUP_SIZE), 1, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
Compute shader:
#version 430
struct particle{
vec4 currentPos;
vec4 oldPos;
};
layout(std430, binding=0) buffer particles{
struct particle p[];
};
layout (local_size_x = 128, local_size_y = 1, local_size_z = 1) in;
void main(){
uint gid = gl_GlobalInvocationID.x;

p[gid].currentPos.x += 100;
}


But somehow not all particles are affected. I am doing this the same way it was done in this example but it doesn't work.
http://education.sig...eShader_6pp.pdf

When I want to render 128.000 particles, then the code above would dispatch 128.000/128=1.000 1-dimensional work groups and each of them would have the size of 128. Doesn't it thus create 128*1.000 = 128.000 threads which execute the code in the compute shader above and thus all particles are affected? Each thread would have a differen ID at gl_GlobalInvocationID.x because all work-groups are 1-dimensional Am I missing something?

My other question is relating to glDrawArrays().
The vertex shader receives all the vertices from the shared-storage-buffer and passes them through to the geometry shader, where I emit 4 particles to create a quad on which I map my texture in the fragment shader. The structure which is stored in the shared-storage-buffer for every particle looks like this:
struct Particle{
glm::vec4 _currPosition;
glm::vec4 _prevPosition;
};
When I draw the scene I do the following:
glBindBuffer(GL_ARRAY_BUFFER, BufferID);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), 0);
glEnableVertexAttribArray(0);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_POINTS, 0, _numParticles*2);
glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);

Somehow when I just call glDrawArrays(GL_POINTS, 0, _numParticles) not all particles are rendered. Why does this happen?
I would suggest the number of the vec4-vectors in the particle-struct is the reason but I am not sure. Could somebody explain it please? Posted Image

Regards,
StanLee

#1StanLee

Posted 04 October 2012 - 09:58 AM

Hello,

I am new to OpenGL and currentyl working on a particle System which makes use of the compute shader. I've got two questions. The first is about the compute shader itself. I create the particles and store them in shader storage buffer so I can access their position in the compute shader. Now I want to create a thread for every particle, which computes its new position. So I dispatch a one dimensional work group.
#define WORK_GROUP_SIZE 128
_shaderManager->useProgram("computeProg");
glDispatchCompute((_numParticles/WORK_GROUP_SIZE), 1, 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
Compute shader:
#version 430
struct particle{
vec4 currentPos;
vec4 oldPos;
};
layout(std430, binding=0) buffer particles{
struct particle p[];
};
layout (local_size_x = 128, local_size_y = 1, local_size_z = 1) in;
void main(){
uint gid = gl_GlobalInvocationID.x;

p[gid].currentPos.x += 100;
}


But somehow not all particles are affected. I am doing this the same way it was done in this example but it doesn't work.
http://education.siggraph.org/media/conference/S2012_Materials/ComputeShader_6pp.pdf

When I want to render 128.000 particles, then the code above would dispatch 128.000/128=1.000 1-dimensional work groups and each of them would have the size of 128. Doesn't it create 128*1.000 = 128.000 threads which execute the code in the compute shader above and thus all particles are affected? Each thread would have a differen ID at gl_GlobalInvocationID.x because all work-groups are 1-dimensional Am I missing something?

My other question is relating to glDrawArrays().
The vertex shader receives all the vertices from the shared-storage-buffer and passes them through to the geometry shader, where I emit 4 particles to create a quad on which I map my texture in the fragment shader. The structure which is stored for every particle in the shared-storage-buffer looks like this:
struct Particle{
glm::vec4 _currPosition;
glm::vec4 _prevPosition;
};
When I draw the scene I do the following:
glBindBuffer(GL_ARRAY_BUFFER, BufferID);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(glm::vec4), 0);
glEnableVertexAttribArray(0);
glEnableClientState(GL_VERTEX_ARRAY);
glDrawArrays(GL_POINTS, 0, _numParticles*2);
glDisableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, 0);

Somehow when I just call glDrawArrays(GL_POINTS, 0, _numParticles) not all particles are rendered. Why does this happen?
I would suggest the number of the vec4-vectors in the particle-struct is the reason but I am not sure. Could somebody explain it please? :)

Regards,
StanLee

PARTNERS