【发布时间】:2018-09-26 09:59:31
【问题描述】:
我目前创建了两个 SSBO 来处理一些灯光,因为 VS-FS in out 接口无法处理很多灯光(我使用前向着色)。
对于第一个,我只将值传递给着色器(基本上是只读的)[cpp]:
struct GLightProperties
{
unsigned int numLights;
LightProperties properties[];
};
...
glp = (GLightProperties*)malloc(sizeof(GLightProperties) + sizeof(LightProperties) * lastSize);
...
glGenBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(GLightProperties) + sizeof(LightProperties) * lastSize, glp, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 1, ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
着色器文件 [GLSL]:
layout(std430, binding = 1) buffer Lights
{
uint numLights;
LightProperties properties[];
}lights;
所以这第一个 SSBO 可以正常工作。但是,在另一个目的是 VS-FS 接口中,存在一些问题:
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo2);
glBufferData(GL_SHADER_STORAGE_BUFFER, sizeof(float) * 4 * 3 * lastSize, nullptr, GL_DYNAMIC_COPY);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
GLSL:
struct TangentProperties
{
vec4 TangentLightPos;
vec4 TangentViewPos;
vec4 TangentFragPos;
};
layout(std430, binding = 0) buffer TangentSpace
{
TangentProperties tangentProperties[];
}tspace;
所以你注意到我将nullptr 传递给glBufferData 因为vs 将写入缓冲区而fs 将读取其内容。
就像在 VS 阶段一样:
for(int i = 0; i < lights.numLights; i++)
{
tspace.tangentProperties[index].TangentLightPos.xyz = TBN * lights.properties[index].lightPosition.xyz;
tspace.tangentProperties[index].TangentViewPos.xyz = TBN * camPos;
tspace.tangentProperties[index].TangentFragPos.xyz = TBN * vec3(worldPosition);
memoryBarrierBuffer();
}
在此之后,FS 读取值,结果只是垃圾。我在记忆障碍方面做错了吗?
【问题讨论】:
-
我自己永远不要使用
memoryBarrierBuffer(),但是根据文档,它说屏障确保在内存屏障之前执行的所有更改在后续阶段都可见,这意味着它不会对当前阶段(如果我理解正确的话)。既然你有它在一个循环中,我猜你希望它为下一次迭代同步线程?文档:khronos.org/registry/OpenGL-Refpages/gl4/html/…