代码之家  ›  专栏  ›  技术社区  ›  Mark A. Donohoe

带法线渲染的opengl es多边形(注意'es!')

  •  0
  • Mark A. Donohoe  · 技术社区  · 15 年前

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

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

    另一种方法是使用单独的法线和顶点数组(甚至交错它们),但这意味着我需要有一个一对一的法线和顶点的比率,这意味着法线的重复将比需要的多8倍!在球面甚至曲面的物体上,每个正常的物体很可能都是不同的,但对于这个物体来说,这真的是浪费记忆。

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

    现在obj文件格式允许您精确地指定…一个顶点数组和一个不同长度的法线数组,然后在指定要渲染的面时,指定一个顶点和一个法线索引(如果也使用纹理,还可以指定一个UV坐标),这看起来是一个完美的解决方案!48个顶点,但只有8条法线,然后定义形状面的索引对。但我不知道如何在opengl es中渲染(同样,请注意“是”),目前我不得不用顶点数组将法线“去规格化”(很抱歉这里的sql双关语),然后渲染。只是在浪费我的记忆。

    有人帮忙吗?我希望我遗漏了一些很简单的东西。

    作记号

    1 回复  |  直到 15 年前
        1
  •  1
  •   Bahbar    15 年前

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

    我不会讨论实现支持一系列索引的硬件的复杂性,但我会指出一个可能会丢失的优化: gl可能将单个索引用作顶点转换后缓存的索引,以便在下次迭代时不必重新转换顶点。使用一组索引可以使优化变得更加复杂。

    关于内存节省:在你的例子中,你说的是一个立方体,每个面使用4个四边形,8个三角形。所以我们说的是9*6=54个唯一顶点。如果只有位置和法线,则为顶点数据的54*4*3*2=1296b+索引数据的2*48*3=288b(假设属性基类型为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世界中(即不在盒子的世界中),这样一种机制的节省将很低:很少有属性可以被共享。