我正在使用OpenGL开发一个小粒子系统 问题是更新计算着色器中的位置似乎不起作用。
以下是代码:
缓冲区
struct ParticleInfo {
Vec4f position; // w: s coordinate
Vec4f normal; // w: t coordinate
float materialIndex;
Vec3f oldPosition;
};
初始缓冲区
glGenVertexArrays(1, &mParticleVAO);
glBindVertexArray(mParticleVAO);
glGenBuffers(1, &mParticleVBO);
glBindBuffer(GL_ARRAY_BUFFER, mParticleVBO);
glBufferData(GL_ARRAY_BUFFER, sizeof(ParticleInfo) * mNumParticles, particleData.data(), GL_STATIC_DRAW);
glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 4, GL_FLOAT, GL_FALSE, sizeof(ParticleInfo), (void*)NULL);
glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 4, GL_FLOAT, GL_FALSE, sizeof(ParticleInfo), (void*)(NULL + sizeof(Vec4f)));
glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 1, GL_FLOAT, GL_FALSE, sizeof(ParticleInfo), (void*)(NULL + 2*sizeof(Vec4f)));
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
使用计算着色器更新缓冲区
gl->setUniform(mParticleMoveProgram->getUniformLoc("numParticles"), mNumParticles);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, mParticleVBO);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, mAttractorSSBO);
int localSizeX = 64*8;
int groupSizeX = (mNumParticles + localSizeX - 1) / localSizeX;
glDispatchCompute(groupSizeX, 1, 1);
glMemoryBarrier(GL_ALL_BARRIER_BITS);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, 0);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, 0);
着色器代码
#version 450
layout(local_size_x = 64) in;
struct ParticleInfo {
vec4 position; // modify only the position;
vec4 normal;
float materialIndex;
vec3 oldPosition;
};
struct Attractor {
vec3 position;
float mass;
};
layout(binding = 0, std430) buffer ParticleArray {
ParticleInfo particles[];
};
layout(binding = 1, std430) buffer AttractorArray {
Attractor attractors[];
};
uniform int numParticles;
vec3 verlet(in vec3 a, in vec3 x, in vec3 xOld, in float dt) {
return 2.0 * x - xOld + a * dt*dt;
}
void main() {
const int PARTICLES_PER_THREAD = 8;
int index = int(gl_LocalInvocationIndex)*PARTICLES_PER_THREAD;
if (index >= numParticles) return;
Attractor attr = attractors[0];
const float G = 9.8;
for (int i = 0; i < PARTICLES_PER_THREAD; ++i)
{
particles[i+index].position = vec4(0.0);
particles[i+index].normal = vec4(0.0);
particles[i+index].oldPosition = vec3(0.0);
}
}
答案 0 :(得分:1)
正如@derhass评论的那样。记忆结构并不匹配。每个线程的正确索引似乎也存在问题。我通过将每个线程的索引设置为:
来修复它index = PARTICLES_PER_THREAD * int(gl_WorkGroupSize.x * gl_WorkGroupID.x + gl_LocalInvocationID.x);
感谢您的帮助。