我试图了解memoryBarrier()在OpenGL 4.4中的工作原理 我使用纹理图像尝试了以下一次,使用着色器存储缓冲区对象(SSBO)尝试了一次。 基本思想是为需要在场景中渲染的许多对象创建一个标志数组,然后在几何着色器中执行简单测试。
对于GS中的每个基元,如果至少有一个顶点通过了测试,则为它 在指定位置的数组中设置相应的标志 通过这个原始对象ID(对象ID作为顶点传递给GS 属性)。
然后执行memoryBarrier()以确保所有线程都写入了它们的值。
以下是我的着色器中的一些代码来解释:
// Vertex Shader:
#version 440
uniform mat4 model_view;
uniform mat4 projection;
layout(location = 0) in vec3 in_pos;
layout(location = 1) in vec3 in_color;
layout(location = 2) in int lineID;
out VS_GS_INTERFACE
{
vec4 position;
vec4 color;
int lineID;
} vs_out;
void main(void) {
vec4 pos = vec4(in_pos, 1.0);
vs_out.position = pos;
vs_out.color = vec4(in_colo, 1.0);
vs_out.lineID = lineID;
gl_Position = projection * model_view * pos;
}
这是一个简单的几何着色器,其中我只使用基于lineID的简单测试(我意识到这个测试不需要共享数据结构,但这只是为了测试程序行为)
#version 440
layout (lines) in;
layout (line_strip, max_vertices = 2) out;
layout (std430, binding = 0) buffer BO {
int IDs[];
};
in VS_GS_INTERFACE
{
vec4 position;
vec4 color;
int lineID;
} gs_in[];
out vec4 f_color;
void main()
{
if(gs_in[0].lineID < 500)
{
IDs[gs_in[0].lineID] = 1;
}
else
{
IDs[gs_in[0].lineID] = -1;
}
memoryBarrier();
// read back the flag value
int flag = IDs[gs_in[0].lineID];
if ( flag > 0)
{
int n;
for( n = 0; n < gl_in.length(), n++)
{
f_color = gs_in[n].color;
gl_Position = gl_in[n].gl_Position;
emitVertex();
}
}
}
无论我放的是什么值而不是500,这段代码总是只渲染2个对象。如果我将GS中渲染的条件更改为if(flag&gt; = 0),在我看来,所有对象都会被渲染,这意味着在着色器回读这些ID时,从不写入-1。 有人可以解释为什么写入对所有着色器调用都不一致,尽管memoryBarrier()以及最有效的解决方法是什么?
感谢。