我正在寻找一种同时渲染多个网格的方法,这样我就不必为每个网格发出绘制调用。我在这里处理的是2D渲染,一个典型的对象,比如正方形,可能只有两个三角形。然而,一个对象可能也很复杂,有数千个三角形。
现在,每个对象都可以自己移动。从概念上讲,每个"对象"都有一个VBO(或VBO/IBO对)是完全合理的:只要对象不改变,我只需要上传到GPU的每一帧都是转换信息:位置向量和方向值。或者,等价地,一个变换矩阵。
但这种方法的问题是,对于一个有1000个正方形对象的场景,我需要初始化1000个VBO和1000个IBO,以及1000个绘制调用,每个帧设置1000组统一,以便渲染2000个三角形。
好的。如果所有这些对象都相同,我可以用一个VBO/IBO来描述它们,为每个对象设置一个带有转换数据的统一缓冲区对象(或者统一数组更合适——我仍然需要学习如何使用这些),并发出一个实例化绘制调用,让顶点着色器通过使用它接收的实例号从UBO中提取转换数据。太棒了
我只想更进一步。我想在不完全相同的网格上进行实例化:我有1000个不同的对象,我很乐意在1000个单独的顶点/索引缓冲区对或一对巨大的顶点/指数缓冲区中描述它们。我想在一次调用中将他们的转换数据发送到GPU。这只是让驱动程序/GPU绑定或选择合适的顶点的问题。
这能做到吗?可以在不使用SM4几何体着色器的情况下完成吗?
更新:我刚刚想到了一个潜在的方法来实现这一点。我使用顶点属性作为我的"实例化"值,用它索引到包含转换的UBO中。这样做吗?
每个对象不需要一个VBO。只需将所有对象连接到一个单独的VBO或一小组VBO中。您可以在该VBO中寻址,或者向gl*Pointer
函数的数据参数添加偏移,或者在绘图时使用glDrawElementsBaseVertex
添加偏移。将所有小对象的索引数组连接起来,而不是索引数组中只有4个独立项。如果您使用的是条形或扇形基元,则可以使用glPrimitiveRestartIndex
设置一个特殊索引,当遇到该索引时,将启动一个新的基元。
这样,您只需要通过使用的材质设置、整体变换和着色器参数(即纹理、着色器、着色器制服)来拆分渲染调用。