如果我们需要渲染1000个三角形,那么把它们按1000个单独的网格进行渲染(1000次DrawCall)所花费的时间要远大于直接渲染1个包含了1000个三角形的网格(1次DrawCall)。使用批处理,可以减少DrawCall(其实也不一定,比如SRP Batcher是SetPass优化)。
Static Batching
使用方式
在游戏中不移动不旋转不缩放的物体可以被视为静态物体。在检视面板,勾选【Static】以标记物体为静态物体。
使用相同材质引用的静态物体可以被静态批处理。
原理
Static Batching将静态物体合并为一个大网格,从而以更快的速度渲染它们。可以减少DrawCall(符合条件的情况下),同时让CPU在设置渲染状态到提交Draw Call之间的工作上更高效。
Unity将静态物体合并为一个(或多个)大网格,这个(或这些)大网格以vertex buffers和index buffers的形式存储在GPU上。
Unity按顺序绘制场景中的物体时,如果两个物体的数据属于同一块buffer,且在vertex buffer和index buffer上连续,那么这两个物体仅产生1次DrawCall;
如果它们不连续,那么将产生2次DrawCall(specify different regions of this buffer)。但是由于它们属于同一块buffer,因此这2次DrawCall之间的GPU状态不发生改变,它们构成1次StaticBatch;虽然没有降低DrawCall次数,但是避免了重复的设置渲染状态过程;
静态批处理不一定减少DrawCall,但是会让CPU在设置渲染状态到提交DrawCall之间的工作上更高效。
静态批处理一般比动态批处理更高效,但是由于需要存储合并后的网格,会占据额外的内存,有的时候可能需要牺牲渲染性能来换取较小的内存占用。比如,在一个森林场景中把重复出现的树标记为静态物体,会造成巨大的内存占用,尽管这些树共享了同一个Mesh,但是开启静态批处理,会使得每一棵树都产生一个Mesh然后合并为一个大Mesh。
开启条件
- 使用相同材质引用的静态物体;
- 物体需为Mesh,具有MeshFilter和MeshRenderer组件;
- Mesh 需要在ImportSettings面板勾选【read/write enabled】;
一个静态批处理中,顶点上限为64000。整个批处理中网格索引的总数有上限,具体取决于Graphics API,一般在 32~64K 之间;