memoryBarrier()在Geometry Shader中意外地表现

时间:2014-06-16 21:31:19

标签: c++ opengl glsl geometry-shader

我试图了解memoryBarrier()在OpenGL 4.4中的工作原理 我使用纹理图像尝试了以下一次,使用着色器存储缓冲区对象(SSBO)尝试了一次。 基本思想是为需要在场景中渲染的许多对象创建一个标志数组,然后在几何着色器中执行简单测试。

  1. 对于GS中的每个基元,如果至少有一个顶点通过了测试,则为它 在指定位置的数组中设置相应的标志 通过这个原始对象ID(对象ID作为顶点传递给GS 属性)。

  2. 然后执行memoryBarrier()以确保所有线程都写入了它们的值。

  3. 接下来,我从flags数组中读取所有原语,并且只有在设置了标志时才发出一个顶点。
  4. 以下是我的着色器中的一些代码来解释:

    // 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()以及最有效的解决方法是什么?

    感谢。

0 个答案:

没有答案