批量绘制具有不同变换的对象的最佳做法是什么?

时间:2013-04-21 07:10:57

标签: opengl graphics 3d opengl-es-2.0

我正在构思一个很好的方法,在OpenGL中使用单个绘制调用渲染尽可能多的脱节几何体,而我反对的墙是最好的方法,当每个部分有不同的翻译时,也许旋转,因为您无法在单个对象绘制之间更新模型视图。我在这里和其他地方已经阅读了其他一些问题,似乎人们所指出的方向是多种多样的。列出执行此操作的主要方法并尝试隔离最常见或建议的内容会很好。以下是我考虑过的想法:

[编辑:删除提及Instancing,因为它不适用于此处]

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

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

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

  4. 还有其他常用方法吗?

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

2 个答案:

答案 0 :(得分:12)

两个考虑因素:

  

一般来说,如果你有多个对象,每个对象   使用独立转换,您可以使用多个绘制调用。那是什么   他们在那里。旧的NVIDIA“Batch Batch Batch”演示文稿   引用每帧10,000到40,000个绘制调用(在D3D中。更多内容   GL)用于1GHz GPU。如今,你所看到的远不止于此。   所以,除非你处理成千上万的个别物品,   所有这些都是不同的(所以没有实例),可能性很大   你没事。

另一个想法:

  

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

(取自here。)

答案 1 :(得分:5)

这是另一个想法:

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