简体   繁体   English

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

[英]How do I efficiently handle a large number of per vertex attributes in OpenGL?

The number of per vertex attributes that I need to calculate my vertex shader output is bigger than GL_MAX_VERTEX_ATTRIBS. 我计算顶点着色器输出所需的每个顶点属性的数量大于GL_MAX_VERTEX_ATTRIBS。 Is there an efficient way to eg point to a number of buffers using a uniform array of indices and to access the per vertex data this way? 有没有一种有效的方法可以使用统一的索引数组指向多个缓冲区并以这种方式访问​​每个顶点数据?

This is a hardware limitation so the short answer is no. 这是硬件限制所以简短的答案是否定的。 If you consider workarounds for other ways, like using uniforms that also got limitations so that is a no way to go either. 如果您考虑使用其他方法的解决方法,例如使用也有限制的制服,那么这也是一种无法解决的问题。

One possible way I can think of which is rather hackish is to get the extra data from a texture. 我能想到的另一种可能的方法是从纹理中获取额外的数据。 Since you can access textures from the vertex shader, but texture filtering is not supported ( you wont need it so it doesn't matter for you ). 由于您可以从顶点着色器访问纹理,但不支持纹理过滤(您不需要它,因此对您来说无关紧要)。 With the newer OpenGLs its possible to store rather large amount of data in textures and access them without limitation even in the vertex shader, it seems to be one way to go. 使用更新的OpenGL可以在纹理中存储相当大量的数据并且即使在顶点着色器中也可以无限制地访问它们,这似乎是一种方法。

Altho with this approach there is a problem you need to face, how do you know the current index, ie which vertex it is? 用这种方法来说,你需要面对一个问题,你怎么知道当前的指数,即它是哪个顶点? You can check out gl_VertexID built-in for that. 您可以检查内置的gl_VertexID。

You could bypass the input assembler and bind the extra attributes in an SSBO or texture. 您可以绕过输入汇编程序并绑定SSBO或纹理中的额外属性。 Then you can use gl_VertexID in the vertex shader to get the value of index buffer entry you are currently rendering (eg: the index in the vertex data you need to read from) 然后你可以在顶点着色器中使用gl_VertexID来获取你当前渲染的索引缓冲区条目的值(例如:你需要读取的顶点数据中的索引)

So for example in a VS the following code is essentially identical (it may however have different performance characteristics depending on your hardware) 因此,例如在VS中,以下代码基本相同(但根据您的硬件,它可能具有不同的性能特征)

in vec3 myAttr;

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

vs.

buffer myAttrBuffer {
 vec3 myAttr[];
};

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

The CPU-side binding code is different, but generally that's the concept. CPU端绑定代码是不同的,但通常这是概念。 myAttr counts towards GL_MAX_VERTEX_ATTRIBS, but myAttrBuffer does not since it is loaded explicitly by the shader. myAttr计入GL_MAX_VERTEX_ATTRIBS,但myAttrBuffer没有,因为它由着色器显式加载。

You could even use the same buffer object in both cases by binding with a different target. 在两种情况下,您甚至可以通过绑定不同的目标来使用相同的缓冲区对象。

If you can not absolutely limit yourself to GL_MAX_VERTEX_ATTRIBS attributes, I would advise using multi pass shaders. 如果你不能绝对限制自己GL_MAX_VERTEX_ATTRIBS属性,我会建议使用多通道着色器。 Redesign your code to work with data with half set of attributes in first pass, and the remaining in second pass. 重新设计代码以在第一遍中使用具有一组属性的数据,并在第二遍中使用剩余的数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM