1

我已经绑定shader storage buffershader 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指向一个std::vector包含 4 个glm::vec3对象。

因为我绑定48 bytes了我期望lights[]持有的缓冲区范围48/(4*3) = 4 vec3s

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

1my中 index 处的元素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);

它可以工作(白色像素)。

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

4

1 回答 1

4

这是因为人们不接受这个简单的建议:永远不要vec3在 UBO/SSBO 中使用 a 。

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

是的,std430布局与std140. 但它并没有那么不同。具体来说,它只防止数组元素的基本对齐和步幅(以及结构的基本对齐)被四舍五入到 a 的值vec4。但由于 的 基本对齐方式vec3始终等于a的基本对齐方式vec4,因此对它们没有任何改变。它只影响标量和vec2's。

于 2016-05-27T23:30:50.647 回答