OpenGL - 调用索引= 1的glBindBufferBase中断渲染(Pitch black)

Sil*_*lan 5 opengl buffer fragment-shader

我的着色器中有一系列统一块,其定义如下:

layout (std140) uniform LightSourceBlock
{
    int shadowMapID;
    int type;
    vec3 position;
    vec4 color;

    float dist;

    vec3 direction;
    float cutoffOuter;
    float cutoffInner;
    float attenuation;
} LightSources[12];
Run Code Online (Sandbox Code Playgroud)

为了能够将我的缓冲区对象绑定到每个LightSource,我将每个制服绑定到一个统一的块索引:

for(unsigned int i=0;i<12;i++)
    glUniformBlockBinding(program,locLightSourceBlock[i],i); // locLightSourceBlock contains the locations of each element in LightSources[]
Run Code Online (Sandbox Code Playgroud)

渲染时,我使用以下命令将缓冲区绑定到相应的索引:

glBindBufferBase(GL_UNIFORM_BUFFER,i,buffer);
Run Code Online (Sandbox Code Playgroud)

这很好,只要我只将一个缓冲区绑定到绑定索引0.只要有更多,一切都是黑色(即使使用完全不同的着色器的东西).(glGetError返回没有错误)

如果我将块索引范围从0-11更改为2-13(跳过索引1),则一切正常.我想如果我使用索引1,我会覆盖一些东西,但我的着色器中没有任何其他统一块,而且我在代码中的任何其他地方都没有使用glUniformBlockBinding或glBindBufferBase,所以我不确定.

什么可能导致这种行为?索引1是为某些东西保留的吗?

小智 0

1)不要使用多个块。将一个块与数组一起使用。像这样的东西:

struct Light{
  ...
}
layout(std430, binding=0) uniform lightBuffer{
 Light lights[42];
}
Run Code Online (Sandbox Code Playgroud)

跳过 glUniformBlockBinding 和仅 glBindBufferBase 到着色器中指定的索引

2) 阅读 std140、std430 的对齐方式。简而言之,缓冲区变量是对齐的,因此它们不会跨越 128 位边界。因此,在您的情况下,位置将从字节 16 (而不是 8)开始。这会导致 CPU/GPU 端访问不匹配。(重新排序变量或添加填充)