【问题标题】:How do I efficiently handle a large number of per vertex attributes in OpenGL?如何有效地处理 OpenGL 中的大量每个顶点属性?
【发布时间】:2013-10-23 17:27:29
【问题描述】:

计算顶点着色器输出所需的每个顶点属性的数量大于 GL_MAX_VERTEX_ATTRIBS。有没有一种有效的方法,例如使用统一的索引数组指向多个缓冲区并以这种方式访问​​每个顶点的数据?

【问题讨论】:

    标签: c++ opengl glsl vertex-shader


    【解决方案1】:

    这是一个硬件限制,所以简短的回答是否定的。 如果您考虑其他方法的变通方法,例如使用也有限制的制服,那么这也是没有办法的。

    我能想到的一种比较老套的方法是从纹理中获取额外的数据。由于您可以从顶点着色器访问纹理,但不支持纹理过滤(您不需要它,所以对您来说没关系)。 使用较新的 OpenGL 可以在纹理中存储相当大量的数据,并且即使在顶点着色器中也可以不受限制地访问它们,这似乎是一种方法。

    尽管使用这种方法,但您需要面对一个问题,您如何知道当前索引,即它是哪个顶点? 你可以查看 gl_VertexID 内置的。

    【讨论】:

      【解决方案2】:

      您可以绕过输入汇编器并将额外属性绑定到 SSBO 或纹理中。然后你可以在顶点着色器中使用 gl_VertexID 来获取你当前正在渲染的索引缓冲区条目的值(例如:你需要读取的顶点数据中的索引)

      因此,例如在 VS 中,以下代码基本上是相同的(但根据您的硬件,它可能具有不同的性能特征)

      in vec3 myAttr;
      
      void main() {
       vec3 vertexValue = myAttr;
       //etc
      }
      

      对比

      buffer myAttrBuffer {
       vec3 myAttr[];
      };
      
      void main() {
       vec3 vertexValue = myAttr[gl_VertexID];
       //etc
      } 
      

      CPU 端绑定代码是不同的,但通常是这个概念。 myAttr 计入 GL_MAX_VERTEX_ATTRIBS,但 myAttrBuffer 不计入,因为它是由着色器显式加载的。

      您甚至可以通过绑定不同的目标在这两种情况下使用相同的缓冲区对象。

      【讨论】:

        【解决方案3】:

        如果你不能绝对限制自己使用 GL_MAX_VERTEX_ATTRIBS 属性,我建议使用多通道着色器。重新设计您的代码,以便在第一遍中处理具有一半属性集的数据,而在第二遍中使用其余属性。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多