18

我正在构思一种在 OpenGL 中通过一次绘制调用渲染尽可能多的不连贯几何体的好方法,而当每一块都具有不同的平移和旋转时,我所面对的墙是最好的方法,因为您没有在单个对象绘制之间更新模型视图制服的奢侈。我在这里和其他地方读过其他一些问题,似乎人们所指出的方向是多种多样的。最好列出执行此操作的主要方法并尝试隔离最常见或推荐的方法。以下是我考虑过的想法:

[编辑:删除了对实例化的提及,因为它在这里并不真正适用]

  1. 在着色器中创建矩阵变换。在这里,我将发送一个平移向量或者一个旋转角度或四元数作为属性的一部分。优点是它可以跨平台工作,包括移动设备。但是为对象中的每个顶点发送完全相同的转换数据作为属性似乎有点浪费。如果没有实例化,我必须在 VBO 中多次重复这些相同的向量或标量,作为交错数组的一部分,对吗?另一个缺点是我依靠着色器来做数学运算。我不知道这是否明智。

  2. 与 1) 类似,但不是依靠着色器进行矩阵计算,而是在客户端进行这些计算,但仍将最终模型视图矩阵作为 VBO 中的 16 个浮点流发送。但据我所知,如果没有实例化,我必须为 VBO 中的每个顶点重复这个相同的流,对吗?只是看起来很浪费。与上面 2) 的权衡是,我在每个顶点的 VBO 中发送了更多数据(16 个浮点数而不是 3 个浮点数向量用于平移,可能是 4 个浮点数四元数),但需要着色器做更少的工作。

  3. 跳过所有上述限制,而是通过为每个对象单独绘制调用来妥协。这是我正在阅读的书中通常“教授”的内容,毫无疑问是为了简单起见。

除了这些还有其他常用的方法吗?

作为一个学术问题,我很好奇以上所有内容是否可行且“可以接受”,或者其中一个是否明显胜过其他?如果我要专门使用桌面 GL,实例化是实现这一目标的主要方式吗?

4

2 回答 2

15

两个考虑:

一般来说,如果你有多个对象,每个对象都使用独立的变换,你会使用多个绘制调用。这就是他们的目的。旧的 NVIDIA“Batch Batch Batch”演示文稿引用了 1GHz GPU 的每帧 10,000 到 40,000 个绘制调用(在 D3D 中。在 GL 中更多)。如今,您所关注的远不止这些。因此,除非您要处理数以万计的单个对象,而且它们都是不同的(因此没有实例化),否则您会没事的可能性很大。

另一个想法:

将模型视图矩阵计算完全从着色器中取出,并在乘法后传递顶点。这允许对许多不同方向和平移的对象进行一次绘制调用。成本仅来自所有 CPU 计算,但我想如果该瓶颈没有多个绘制调用的瓶颈那么大,那将是值得的。

(取自这里。)

于 2013-04-27T04:10:48.470 回答
6

这是另一种想法:

给每个顶点一个通过属性传入的对象 ID。然后在顶点着色器中,使用此 ID 在存储变换矩阵的纹理中进行查找。

于 2014-05-29T01:53:51.590 回答