DrawCall优化总则

优化绘制调用

要将几何体绘制到屏幕上,Unity会向图形API发送绘制调用(Draw Call)。每个绘制调用包含图形API所需的所有信息(如纹理、着色器、缓冲区等)。虽然绘制调用本身可能消耗资源,但更耗资源的往往是其准备阶段——尤其是渲染状态(Render State)的变更(例如切换材质)。


为何优化绘制调用?

优化绘制调用和渲染状态变更的主要目标是提升帧率,同时带来以下优势:

1. 降低设备能耗:减少电量消耗(对移动设备尤为重要)和设备发热。

2. 提高项目可维护性:保持优化后,可向场景中添加更多GameObject而无需担心性能骤降。


优化方法

Unity提供多种优化策略,按优先级从高到低排序如下:

1. SRP Batcher与静态批处理(Static Batching)

SRP Batcher:适用于使用可编程渲染管线(SRP)的项目。通过减少相同着色器变体的材质切换开销优化CPU性能。

静态批处理:预合并静态GameObject的网格。合并后每个网格仍独立渲染,但共享数据状态,降低每次调用的开销。

注意:静态批处理会覆盖GPU实例化。若检测到冲突,Unity编辑器会提示禁用静态批处理。

2. GPU实例化(GPU Instancing)

适用场景:同网格重复出现(如树木、草丛)。

原理:单次绘制调用渲染多个实例,通过着色器传递每实例属性(如位置、颜色)。

3. 动态批处理(Dynamic Batching)

原理:CPU动态合并共享相同配置(如顶点属性)的网格顶点,单次调用渲染。

限制:仅适用于小规模网格(顶点数通常不超过900)。

4. 手动合并网格

方法:使用Mesh.CombineMeshes将多个网格合并为单个网格,减少绘制调用次数。


优化优先级与冲突处理

Unity按以下顺序优先应用优化方法(SRP Batcher除外,可与静态批处理共存):
1. SRP Batcher + 静态批处理
2. GPU实例化
3. 动态批处理

冲突示例:

若GameObject启用静态批处理,即使其材质支持GPU实例化,Unity也会禁用实例化。

若GPU实例化可用,动态批处理将被禁用。


各方法对比与适用场景

方法 适用场景 优点 缺点
SRP Batcher SRP项目,同着色器变体材质 减少CPU准备开销 仅限SRP,需兼容的着色器结构
静态批处理 静态物体(如建筑、地形) 降低每调用开销,支持独立剔除 增加内存占用,不可动态修改
GPU实例化 大量重复网格(如植被、子弹) 高效渲染大量实例,节省CPU 需着色器支持,属性数量受限
动态批处理 小规模动态物体(如UI元素) 自动合并,无需预操作 顶点数限制,CPU计算开销
手动合并网格 复杂静态结构(如模块化场景资产) 完全控制,减少调用次数 失去独立剔除,增加内存占用



实施建议

分析性能瓶颈:使用Frame Debugger和Profiler确定绘制调用开销来源。

按优先级启用优化:优先尝试SRP Batcher和静态批处理,再考虑GPU实例化。

权衡内存与性能:静态批处理和手动合并会增大内存占用,需根据目标平台调整。

着色器适配:为需要GPU实例化的材质编写或修改着色器,添加实例化支持。


版权声明:本文为CSDN博主「小李也疯狂」的原创文章,
遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/qq_40882017/article/details/148145949

最新文章