我正在编写一个在OpenGL中渲染一些网格的插件。
我在VBO中有一个Vertices数组,在另一个VBO中有一个Indices数组。我现在想要存储法线。作为一个顶点,在多个面之间共享,具有不同的法线,似乎我必须复制顶点倍数,因此失去了索引的使用。
例如,要存储具有顶点和索引的立方体,我需要8个顶点和24个索引(每个面4个)。但是,如果我想存储法线,我是否需要存储24个顶点(每个3个面8个),24个索引(所有顺序)和24个法线?
我看到它是正确的,因此指数变得无用,或者有没有办法不复制顶点,无论如何每个顶点都有多个法线?
答案 0 :(得分:2)
不那么容易。索引具有称为原始重启索引的强大功能。它可以让你描述你的形状,例如: GL_TRIANGLE_STRIP
,因此对同一网格使用较少的索引。此外,模型的平滑部分共享一些顶点,通常你有比重复顶点更多的共享数据,所以最后它是一个净赢。
现在考虑你的立方体示例。设I
为索引类型的大小,V
为顶点数据的大小。让我们取I = sizeof(uint) = 4
和V = 3*sizeof(float) + 4*sizeof(byte) = 16
(三个浮点位置和一个低精度法线)。
glDrawArrays
的{p> GL_TRIANGLES
每个面需要两个三角形,即2*3*6*V = 512
个字节。
具有glDrawElements
的 GL_TRIANGLE_STRIP
每个面需要四个索引加上重启索引,即5*6*I = 120
个字节,每个面有四个顶点,即4*6*V = 384
个字节。这总共是504个字节。
正如您所看到的甚至使用该多维数据集示例和一些保守类型选择,索引方法仍然在内存占用上获胜。实际上,您可以使用short
索引,并且可能需要更高的精度法线,这将更偏向于索引方法。
答案 1 :(得分:0)
您只需复制尖锐的边缘顶点,但网格通常有许多其他不需要复制的顶点(如曲率曲面)。
因此,指数不会失去其目的。 8顶点立方体只是一个错误的例子....尝试制作一个具有规则顶点覆盖的立方体,让每个面部说4x4 = 16
个顶点,突然你只需要复制边缘顶点...边缘和内部之间的比例顶点通常有利于内顶点