我正在尝试清楚地了解何时应该使用gl [multi]绘制绘制的openGL顶点的索引阵列,而不是何时应该使用连续的顶点,并用GL [Multi] Drawarrays绘制。

(更新: 我得到的答复中的共识是,应该始终使用索引顶点。)

我已经在这个问题上来回走了几次,所以我要概述我目前的理解,希望有人可以告诉我我现在或多或少正确,或者指出我剩下的误解在哪里。具体来说,我有三个结论,大胆。如果他们错了,请纠正它们。

一种简单的情况是,我的几何形状由形成弯曲表面的网格组成。在这种情况下,对于使用顶点的每个三角形,网格中间的顶点将具有相同的属性(位置,正常,颜色,纹理坐标等)。

这使我得出结论:

1.对于几个接缝的几何形状,索引阵列是一个巨大的胜利。

始终遵循规则1,除了:

对于非常“块状”的几何形状,每个边缘代表接缝,索引阵列的好处不太明显。以简单的立方体为例,尽管每个顶点都在三个不同的面中使用,但我们不能在它们之间共享顶点,因为对于一个顶点,表面正常(以及其他可能的东西,例如颜色和纹理坐标) )每张脸都会有所不同。因此,我们需要明确将冗余顶点位置引入我们的数组中,以便可以使用不同的正态等几次使用相同的位置。这意味着索引阵列的使用较少。

例如,当呈现一个立方体的脸时:

 0     1
  o---o
  |\  |
  | \ |
  |  \|
  o---o
 3     2

(这可以孤立地考虑,因为这张脸和所有相邻面之间的接缝意味着比这些顶点之间的任何一个无法共享这些顶点)

如果使用gl_triangle_fan(或_strip)渲染,则可以渲染多个立方体的每个面:

verts  = [v0, v1, v2, v3]
colors = [c0, c0, c0, c0]
normal = [n0, n0, n0, n0]

添加索引不允许我们简化这一点。

我得出的结论是:

2.当使用GL_TRIANGLE_STRIP或_FAN时,当渲染几何形状或大部分是接缝时,我绝不应该使用索引阵列,而应始终使用GL [Multi] drawarrays。

(更新: 答复表明该结论是错误的。即使索引不允许我们减少这里的数组的大小,但仍应使用其他性能优势,如评论中所述)

规则2的唯一例外是:

当使用gl_triangles(代替条带或风扇)时,一半的顶点仍然可以重复使用两次,具有相同的正态和颜色等,因为每个立方体的脸部都被呈现为两个独立的三角形。同样,对于同一单个立方体面孔:

 0     1
  o---o
  |\  |
  | \ |
  |  \|
  o---o
 3     2

没有索引,使用gl_triangles,阵列将是:

verts =   [v0, v1, v2,  v2, v3, v0]
normals = [n0, n0, n0,  n0, n0, n0]
colors =  [c0, c0, c0,  c0, c0, c0]

由于顶点和正常通常是每个浮标,而且颜色通常为3个字节,因此,对于每个立方体的脸部,大约为:

verts   = 6 * 3 floats = 18 floats
normals = 6 * 3 floats = 18 floats
colors  = 6 * 3 bytes  = 18 bytes

= 36 floats and 18 bytes per cube face.

(我知道如果使用不同类型的字节数可能会更改,确切的数字仅用于说明。)

使用索引,我们可以简化一点,给予:

verts   = [v0, v1, v2, v3]     (4 * 3 = 12 floats)
normals = [n0, n0, n0, n0]     (4 * 3 = 12 floats)
colors  = [c0, c0, c0, c0]     (4 * 3 = 12 bytes)
indices = [0, 1, 2,  2, 3, 0]  (6 shorts)

= 24 floats + 12 bytes, and maybe 6 shorts, per cube face.

查看在后一种情况下,顶点0和2使用两次,但在每个Vert,正常和颜色数组中仅表示一次。这听起来像是使用索引的小胜利,即使在每个几何边缘都是接缝的极端情况下也是如此。

这使我得出结论:

3.使用GL_Triangles时,即使是所有接缝的几何形状,也应始终使用索引阵列。

如果他们错了,请大胆地更正我的结论。

有帮助吗?

解决方案

我得出的结论是,当使用GL_TRIANGLE_STRIP或_FAN呈现所有接缝或大部分接缝的几何形状时,我绝不应该使用索引阵列,而应始终使用GL [Multi] Drawarrays。

不,原因很简单。

您的结论是基于您分析了一个由两个三角形组成的单一四边形的事实。使用三角形风扇/条绘制的这两个三角形无法使用索引阵列简化。

但是,尝试考虑一个大的地形几何形状。使用三角形风扇/条形原始性,每个地形块都作为四边形绘制。例如:

图中的每个三角形条具有带有相邻三角条带的所有顶点,并且使用索引允许压缩几何定义,而不是为每个三角形带重复顶点。


基本上,只要您可以与另一个原始的绘制绘图绘制原始绘制(三角形,风扇和条),只要您可以共享一个单一原始的大多数顶点。

共享信息允许保存信息传输带宽,但这并不是唯一的优势。实际索引阵列允许:

  • 避免属于相同“概念”顶点的信息的同步,已多次指定
  • 允许在单个顶点上执行相同的着色器操作,而是执行多次,每个顶点重复。
  • 此外,结合使用三角形条/风扇和索引的使用允许应用程序压缩索引缓冲区,因为条带/风扇规格需要更少的索引(三角形需要每个面的三角形始终需要3个索引)。

每当顶点无法共享与之关联的所有信息(颜色,纹理坐标等)与另一个重合顶点相关联时,就不能使用索引阵列。


仅出于完整性的目的,几何规范所需的信息的大小并不是唯一确定最佳渲染操作的因素。

事实,原始渲染的另一个基本因素是数据的缓存定位。严格指定的几何数据(非交织的缓冲物对象,长三角条...)会导致许多缓存误差,从而降低了图形卡的性能。

为了优化渲染操作,应以最大的概率重复使用先前指定的顶点的方式重新排序顶点规范。这样,图形卡缓存线可以重复使用先前指定的顶点,而无需从内存中获取它们。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top