要在屏幕上绘制几何体时,Unity会调用底层的图形API的Draw命令进行绘制。一个Draw命令高数图形API绘制什么以及如何绘制。每个Draw命令都包含图形API所需的所有信息,其中包括texture,shader和buffers数据。绘图调用可能是资源密集型的,但绘图调用的准备工作通常比绘图调用本身更耗费资源。
准备绘制调用时,CPU去构建资源并通过图形API改变GPU的内部设置。这些设置统称为渲染状态。改变这些渲染状态通常时资源密集型的操作,比如切换不同的材质时。 因为渲染状态的改变是资源密集型的,所有减少渲染状态改变的次数是主要的优化方法,这有两种方法能到达此目的:
- 减少总的绘制调用
- 有效组织绘制调用,以减少渲染状态的切换。
优化绘制调用和渲染状态改变数量,主要减少每帧的时间,它也能:
- 减少应用程序的电池的消耗。
- 提高应用程序未来开发的可维护性。当你更早的优化绘制调用和渲染状态改变,那么它将长期维持在一个相对优化的级别。
Unity提供了如下几种优化绘制调用和渲染状态的方法,一些方法只适用于特定的场景。
- Static Batching : 静态合并Mesh来减少绘制调用和渲染状态的改变。需要将对象标记为static。Unity将组合数据发送到GPU,但单独渲染组合中的每个网格。Unity仍然可以单独剔除网格,但每次绘制调用占用的资源较少,因为数据状态永远不会改变。(减少DrawCall)
- Dynamic Batching : 在CPU动态上转换网格顶点,将相同配置的顶点分组,并在一次绘制调用中渲染它们。 比如顶点存储相同数量和类型的属性,则它们共享相同的配置。例如,位置和法线。 (减少DrawCall)
- Manually combining meshes : 通过调用Mesh.CombineMeshes函数将多个Mesh合并为一个。 (减少DrawCall)
- GPU Instancing : 渲染相同的mesh多次。GPU 实例化对于绘制在场景中多次出现的几何图形非常有用,例如树木或灌木丛。(减少DrawCall)
- SRP Batcher : 在SRP项目中,可以使用SRP Batcher减少相同着色器变体的材质准备和绘制调用所需的CPU时间。 (不减少DrawCall,减少状态改变次数)
您可以在同一场景中使用多个绘制调用优化方法,但请注意,Unity会按特定顺序对绘制调用优化方法进行优先排序。如果您将一个游戏对象标记为使用多种绘制调用优化方法,Unity将使用优先级最高的方法。唯一的例外是SRP Batcher。当您使用SRP Batcher时,Unity还支持对与SRP Batcher兼容的游戏对象进行静态批处理。 Unity 按以下顺序对绘制调用优化进行优先排序:
- SRP Batcher and Static batching
- GPU Instancing
- Dynamic Batching
如果您将GameObject标记为静态批处理并且Unity成功对其进行了批处理,Unity会禁用该GameObject的GPU实例化,即使渲染器使用实例化着色器也是如此。发生这种情况时,Inspector 窗口显示一条警告消息,建议您禁用静态批处理。 同样,如果Unity可以对网格使用GPU实例化,Unity会禁用该网格的动态批处理。