具有法线渲染的OpenGL ES多边形(注意它们!')

时间:2010-01-09 01:23:16

标签: opengl-es vertex-buffer vertex

好吧......想象一下,我有一个相对简单的实体,有六个不同的法线,但实际上有近48个面(每个方向有8个面),并且面之间有很多共享顶点。在OpenGL中渲染它的最有效方法是什么?

我知道我可以将顶点放在一个数组中,然后使用一个索引数组来渲染它们,但是我必须不断修改渲染步骤来改变法线(即设置正常1 ...渲染8个面...设置正常2 ...渲染8个面等等。因为我必须维护一个索引数组数组...每个法线一个!不好!<​​/ p>

我可以做的另一种方法是使用单独的法线和顶点阵列(甚至交错它们),但这意味着我需要与法线到顶点具有一对一的比率,这意味着法线将被复制比他们需要的多8倍!在具有球形或甚至曲面的东西上,每个正常情况最有可能是不同的,但为此,它看起来真的是浪费记忆。

在一个完美的世界里,我想让我的顶点和普通数组有不同的长度,然后当我去绘制三角形或四边形时为每个顶点指定索引。

现在,OBJ文件格式允许您精确指定...顶点数组和不同长度的法线数组,然后在指定要渲染的面时,指定顶点和法线索引(以及UV coord如果你也使用纹理)这似乎是完美的解决方案! 48个顶点但只有8个法线,然后是定义形状面的索引对。但是我不确定如何在OpenGL ES中渲染它(再次注意'ES'。)目前我必须'denormalize'(抱歉那里的SQL双关语)法线回到1比1顶点数组,然后渲染。只是浪费了我的记忆。

有人帮忙吗?我希望我在这里遗漏一些非常简单的东西。

标记

1 个答案:

答案 0 :(得分:1)

你没有遗漏任何东西。这就是规范的工作原理,因为这就是大多数硬件的工作方式(也就是说你的完美并不是硬件完美)。

我不会介绍实现支持索引数组的硬件的复杂性,但我会指出一个你可能会丢失的优化: GL可能使用单个索引作为后顶点变换高速缓存的索引,而不必在下一次迭代时重新变换顶点。通过一组索引,您可以使该优化更加复杂。

关于内存节省:在你的情况下,你谈论的是每个面使用4个四边形,8个三角形的大致立方体。所以我们谈论的是9 * 6 = 54个独特的顶点。如果你只有位置和法线,那么54 * 4 * 3 * 2 = 1296 B的顶点数据+ 2 * 48 * 3 = 288 B的索引数据(假设属性基类型为4字节,索引为GLushort)。总计1584B。这也是假设位置和法线的非最佳数据格式。替代方案大致为26 * 4 * 3(pos)+ 8 * 4 * 3(norm)+ 2 * 48 * 3 * 2 = 312 + 96 + 576 = 984B。所以你在这个人为的情况下节省了大约0.5kB。 将此传递给属性的更多内存节省类型,你得到:648 + 288 = 936 vs 156 + 48 + 576 = 780 ......差异开始是可以忽略的。

为什么我提起这件事?因为如果想要优化内存消耗,你应该查看属性数据类型。

最后,正如你所注意到的那样,在实际的3d世界中(即不在盒子世界中),这种机制的节省会很少:很少有属性可以共享。