我的着色器中有一系列统一块,其定义如下:
layout (std140) uniform LightSourceBlock
{
int shadowMapID;
int type;
vec3 position;
vec4 color;
float dist;
vec3 direction;
float cutoffOuter;
float cutoffInner;
float attenuation;
} LightSources[12];
为了能够将我的缓冲区对象绑定到每个LightSource,我将每个制服绑定到一个统一的块索引:
for(unsigned int i=0;i<12;i++)
glUniformBlockBinding(program,locLightSourceBlock[i],i); // locLightSourceBlock contains the locations of each element in LightSources[]
渲染时,我使用以下命令将缓冲区绑定到相应的索引:
glBindBufferBase(GL_UNIFORM_BUFFER,i,buffer);
这个工作正常,只要我只将一个缓冲区绑定到绑定索引0.只要有更多,一切都是黑色(即使使用完全不同的着色器的东西)。 (glGetError返回没有错误)
如果我将块索引范围从0-11更改为2-13(跳过索引1),则一切正常。我想如果我使用索引1,我会覆盖一些东西,但我的着色器中没有任何其他统一块,而且我在代码中的任何其他地方都没有使用glUniformBlockBinding或glBindBufferBase,所以我不确定。
可能导致此类行为的原因是什么?索引1是为某些东西保留的吗?
答案 0 :(得分:0)
1)不要使用多个块。使用一个数组块。像这样:
struct Light{
...
}
layout(std430, binding=0) uniform lightBuffer{
Light lights[42];
}
跳过glUniformBlockBinding并且只将glBindBufferBase转换为着色器中指定的索引
2)阅读std140,std430的对齐。简而言之,缓冲变量是对齐的,因此它们不会跨越128位边界。所以在你的情况下,位置将从字节16(而不是8)开始。这导致CPU / GPU侧访问不匹配。 (重新排序变量或添加填充)