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)
这里有什么问题吗?
我的猜测是您在渲染之前缺少 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 组红绿蓝值放入存储缓冲区,看看它是否会将它们加载为其他两个点的颜色值。