简单的 OpenGL 着色器存储缓冲区对象 (SSBO) 不起作用

She*_*ard 5 opengl shader buffer glsl opengl-4

我试图通过一个非常基本的示例来弄清楚 SSBO 是如何工作的。顶点着色器:

#version 430

layout(location = 0) in vec2 Vertex;

void main() {
    gl_Position = vec4(Vertex, 0.0, 1.0);
}
Run Code Online (Sandbox Code Playgroud)

和片段着色器:

#version 430

layout(std430, binding = 2) buffer ColorSSBO {
    vec3 color;
};

void main() {
    gl_FragColor = vec4(color, 1.0);
}
Run Code Online (Sandbox Code Playgroud)

我知道它们有效,因为如果我替换vec4(color, 1.0)为,vec4(1.0, 1.0, 1.0, 1.0)我会在屏幕中央看到一个白色三角形。

我使用以下代码初始化并绑定 SSBO:

GLuint ssbo;
glGenBuffers(1, &ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo);
float color[] = {1.f, 1.f, 1.f};
glBufferData(GL_SHADER_STORAGE_BUFFER, 3*sizeof(float), color, GL_DYNAMIC_COPY);
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ssbo);
glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
Run Code Online (Sandbox Code Playgroud)

这里有什么问题吗?

SRG*_*SRG 7

我的猜测是您在渲染之前缺少 SSBO 绑定。在您的示例中,您正在复制内容,然后立即绑定它,这对于声明来说是不必要的。换句话说,您的示例中的以下行:

...
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ssbo);
...
Run Code Online (Sandbox Code Playgroud)

必须放在渲染之前,如:

...
glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 2, ssbo);

/*
 Your render calls and other bindings here.
*/

glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0);
...
Run Code Online (Sandbox Code Playgroud)

如果没有这个,你的着色器(理论上)将无法看到内容。

此外,正如Andon M. Coleman所建议的,在声明数组时必须对元素使用填充(例如,使用 vec4 而不是 vec3)。如果你不这样做,它显然会起作用,但会因为这个事实而产生奇怪的结果。

以下两个链接帮助我理解了 SSBO 的含义以及如何在代码中处理它们:

https://www.khronos.org/opengl/wiki/Shader_Storage_Buffer_Object http://www.geeks3d.com/20140704/tutorial-introduction-to-opengl-4-3-shader-storage-buffers-objects-ssbo-demo /

我希望这对面临类似问题的人有所帮助!

PS:我知道这篇文章很旧,但我想做出贡献。


小智 1

绘制三角形时,需要三个点,每个点需要 3 组独立的红绿蓝值。您仅将一组放入着色器缓冲区中。对于其他两个点,颜色值降至默认值,即黑色 (0.0,0.0,0.0)。如果您没有启用混合,则三角形可能会被漆成完全黑色,因为它的两个顶点是黑色的。

尝试将另外 2 组红绿蓝值放入存储缓冲区,看看它是否会将它们加载为其他两个点的颜色值。