只能从Shader Storage Block获取垃圾?

时间:2016-05-27 22:36:57

标签: opengl glsl shader fragment-shader shader-storage-buffer

我已将shader storage buffer绑定到shader storage block,就像这样

GLuint index = glGetProgramResourceIndex(myprogram, GL_SHADER_STORAGE_BLOCK, name);
glShaderStorageBlockBinding(myprogram, index, mybindingpoint);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, mybuffer)
glBindBufferRange(GL_SHADER_STORAGE_BUFFER, mybindingpoint, mybuffer, 0, 48);
glBufferSubData(GL_SHADER_STORAGE_BUFFER, 0, 48, &mydata);

mydata指向包含4个std::vector个对象的glm::vec3

因为我将48 bytes作为缓冲区范围绑定,我希望lights[]能够保留48/(4*3) = 4 vec3s

layout(std430) buffer light {
    vec3 lights[];
};

1中索引为std::vector的元素包含数据x=1.0, y=1.0, z=1.0

但是通过

查看输出
gl_FragColor = vec4(lights[1], 1.0);

我看到黄色x=1.0, y=1.0, z=0.0)像素。这不是我加载到缓冲区中的内容。

有人可以告诉我我做错了吗?

修改

我只是将着色器存储块更改为

layout(std430) buffer light {
    float lights[];
};

和输出

gl_FragColor = vec4(lights[3],lights[4],lights[5],1.0);

它有效(白色像素)。

如果有人可以解释这一点,那仍然会很棒。

1 个答案:

答案 0 :(得分:4)

因为人们不接受这个简单的建议:never use a vec3 in a UBO/SSBO

vec3的基本对齐是16个字节。 始终。因此,当它被排列时,数组步长(从一个元素到下一个元素的字节数)始终为16.与vec4完全相同。

是的,std430布局与std140不同。但它并没有那么不同。具体来说,它只能防止数组元素的基本对齐和步幅(以及结构的基本对齐)向上舍入到vec4的基本对齐和步长。但由于vec3的基本对齐总是等于vec4的基本对齐,因此它不会改变它们。它只会影响标量和vec2