如何在OpenGL中有效处理大量的每个顶点属性?

时间:2013-10-23 17:27:30

标签: c++ opengl glsl vertex-shader

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

3 个答案:

答案 0 :(得分:3)

这是硬件限制所以简短的答案是否定的。 如果您考虑使用其他方法的解决方法,例如使用也有限制的制服,那么这也是无法做到的。

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

通过这种方法,你需要面对一个问题,你怎么知道当前的指数,即它是哪个顶点? 你可以检查出内置的gl_VertexID。

答案 1 :(得分:1)

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

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

in vec3 myAttr;

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

VS

buffer myAttrBuffer {
 vec3 myAttr[];
};

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

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

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

答案 2 :(得分:0)

如果你不能绝对限制自己GL_MAX_VERTEX_ATTRIBS属性,我会建议使用多遍着色器。重新设计代码以在第一遍中使用具有一组属性的数据,并在第二遍中使用剩余的数据。