了解GL_SHADER_STORAGE_BLOCK绑定

时间:2014-01-16 15:01:03

标签: c++ opengl glsl

在使用计算着色器时,我看到大多数示例都创建了GL_SHADER_STORAGE_BUFFERS,就像普通缓冲区一样:

glGenBuffers, glBindBuffer, glBufferData

然后就像这样使用了它们:

    glUseProgram(computeShader);
    glBindBufferRange(GL_SHADER_STORAGE_BUFFER, **3**, bufferA, 0, bufferSize);
    glBindBufferRange(GL_SHADER_STORAGE_BUFFER, **4**, bufferB, 0, bufferSize);
    glDispatchCompute(computeShader);

在计算着色器缓冲区中声明如下:

layout ( **binding = 3** ) buffer
buffer1
{
vec4    data1[];
};
layout ( **binding = 4** ) buffer
buffer2
{
vec4    data2[];
};

然后我得到一些建议,在初始化后我应该做这样的事情:

GLuint index = glGetProgramResourceIndex(computeShader, GL_SHADER_STORAGE_BLOCK, "buffer1");
    glShaderStorageBlockBinding(shader, index, index);

为什么这有必要?

由于glBindBufferRange需要布局指定的索引( binding = x ),它有什么用途?

1 个答案:

答案 0 :(得分:2)

在这种情况下,它没有任何意义。您已经在着色器中显式设置了绑定 - 但是如果查询着色器存储块的索引,也可以手动执行。您可能希望在加载时更改它而不是将其硬编码到着色器中,因为着色器存储缓冲区对象可以使用全局绑定点共享,就像统一缓冲区对象一样。

事实上,它们与UBO非常相似,直到几乎相同的API。真正的区别在于你可以:

  1. 在着色器中写入它们(如果这样做,最好使用内存屏障)
  2. 使用更大的存储空间(最低16 MiB)
  3. 有可变长度。
  4. 当引入UBO时,ARB_shading_language_420pack(给出layout (binding = ...))尚未创建;这可能就是为什么你看到明确绑定SSB索引的建议。