在Unity3D中,常用的减少Draw call的优化技术就是批处理技术。批处理的原理是减少每一帧需要的Draw call数目。为了把一个对象渲染到屏幕上,CPU需要检查哪些光源影响了该物体,绑定shader并设置它的参数,再把渲染命令发送给GPU。当场景中包含了大量的对象时,这些操作就会非常耗时。例如,如果我们需要渲染一千个三角形,把它们按一千个单独的网格进行渲染所花费的时间要远远大于渲染一个包含一千个三角形的网格。在这两种情况下,GPU的性能消耗其实并没有多大的区别,但CPU的draw call数目就会成为性能瓶颈。因此,批处理的思想很简单,就是在每次调用draw call时尽可能多地处理多个物体。
使用同一材质的物体可以进行批处理,因为对于使用同一材质的物体,它们之间的不同仅仅在于顶点数据的差别。我们可以把这些顶点数据合并在一起,再一起发送给GPU,这样就可以完成一次批处理。
在Unity中支持两种类型的批处理,一种是动态批处理,另一种是静态批处理。对于动态批处理来说,优点是一切处理Unity自动完成的,不需要我们做任何操作,而且物体可以是移动的,缺点是限制有很多,可能一不小心就会破坏了这种机制,导致Unity无法动态批处理一些使用了相同材质的物体。而对于静态批处理来说,它的优点是自由度很高,限制很少;但缺点是可能会占用更多的内存,而经过静态批处理后的所有物体都不可以再移动了(即便在脚本中尝试改变物体的位置也是无效的)。
Unity3D中的动态批处理技术
动态批处理的原理是,每一帧把可以进行批处理的模型网格进行合并,再把合并后的模型数据传递给GPU,然后使用同一个材质对其渲染。除了实现方便,动态批处理的另一个好处就是,经过批处理的物体仍然可以移动,这是由于在处理每帧时Unity都会重新合并一次网格。
虽然Unity的动态批处理不需要我们进行任何额外工作,但只有满足条件的模型和材质才可以被动态批处理。(需要注意的是,随着Unity版本的变化,这些条件也有一些改变)这些条件限制是:
1.能够进行动态批处理的网格的顶点属性规模要小