【问题标题】:OpenGL ES Polygon with Normals rendering (Note the 'ES!')具有法线渲染的 OpenGL ES 多边形(注意“ES!”)
【发布时间】:2011-01-03 04:01:06
【问题描述】:

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

我知道我可以将顶点放在一个数组中,然后使用索引数组来渲染它们,但我必须不断打破我的渲染步骤来更改法线(即设置法线 1...渲染 8 个面.. . 设置法线 2... 渲染 8 个面等)因此我必须维护一个索引数组数组... 每个法线一个!不好!

我可以做到的另一种方法是使用单独的法线和顶点数组(甚至将它们交错),但这意味着法线与顶点的比例需要一对一,这意味着法线将被复制比他们需要的多8倍!在具有球形甚至曲面的物体上,每个法线很可能都是不同的,但对于这个,这似乎真的是在浪费内存。

在一个完美的世界中,我希望我的顶点和法线数组具有不同的长度,然后当我去绘制我的三角形或四边形时,为该顶点指定每个数组的索引。

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

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

标记

【问题讨论】:

    标签: opengl-es vertex-buffer vertex


    【解决方案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 世界中(即不是在盒子世界中),这种机制的节省会很低:很少有属性可以共享。

    【讨论】:

    • 好的,模型再简化。你有一条像一卷胶带一样延伸的四边形。在边缘添加第二条带,就像第二条胶带一样,所有顶点都在“折叠”下共享但是由于法线,您无法共享顶点,因此您现在在顶点数据的内存中增加了 33%。 (即你有 ab 然后 cd 即使 b 和 c 是完全相同的顶点,只是不同的法线。从技术上讲,即使在单个条带的四边形下,如果你不希望这些面是相同的问题平滑但相当平坦。(平滑的顶点当然会共享法线。)
    • 此外,您不会丢失任何顶点变换,因为顶点仍然在 3d 空间中的相同位置。我在用法线做什么,或者我如何选择用哪些命令不影响它们来绘制它们。这不正是 DrawElements 命令所做的吗? ..通过索引?毕竟,如果我在按索引引用的十个操作中使用一个索引,那不就是对该顶点的一个计算/优化,而不是十个,与您上面的陈述完全相反吗?
    • 您所描述的内容听起来像是地形。在大多数情况下,您希望在地形胶带卷上共享法线。想要“平坦”是我在信息中所说的例外。至于后顶点变换:如果您的顶点位置输出取决于法线怎么办?它不一定仅基于顶点输入位置计算。而且我只是在描述我知道当前正在使用的优化(顺便说一下,它的大小通常很小。您并不总是会遇到它,尤其是如果您的地形带很长)。
    • 如果我说的是地形,那将是一个例外。但是折纸呢?再说一遍,基于简单几何形状的形状,比如有角和边缘的立方体?根据其定义,地形应该是平滑的。我说的是带角的形状。
    • 顺便说一句,即使在上面您自己的话中,面的边缘也会与相邻面共享它们的中间顶点,即 12那里少了,那么 8 个角中的每一个都将与它们的每个相邻面共享 3 次,这意味着那里节省了 16 个,所以你实际上消除了 54 个中的 28 个,这意味着实际上有 26 个独特的顶点或不到一半的内存为他们。并且需要定义 54 条法线,三角形的每个顶点一个意味着 54 条法线,而同样,您只需要所需内存的 6 或 9 分之一。
    猜你喜欢
    • 2015-04-16
    • 2011-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-31
    相关资源
    最近更新 更多