一、核心概念(必须讲清楚)
- Draw Call(绘制调用)
👉 本质:CPU 向 GPU 提交一次渲染命令
一个 Mesh + 一个 Material ≈ 一个 Draw Call(如果材质是图片,那就是一个Mesh一个DrawCall)
CPU 负责组织数据 → GPU 负责执行
📌 问题本质:
Draw Call 多 → CPU 负担重 → GPU 反而可能在"等"
-
SetPass Call(重点!)
👉 本质:切换渲染状态(Shader / 材质)
包含:
Shader 切换
材质参数绑定
纹理绑定
每次 SetPass 都是高开销 CPU 操作
📌 关键结论:
SetPass Call 比 Draw Call 更影响性能
-
Batches(批次)
👉 Unity优化后的"合批结果"
一个 Batch ≈ 一组被合并的 Draw Call
Stats 面板中:
Batches < Draw Calls → 说明发生了合批(静态和动态合批前是相等的)
二、三者关系
SetPass Call(切换状态)
↓
Draw Call(提交绘制)
↓
Batch(合批优化结果)
📌 关键理解:
指标 本质 优先级
SetPass 状态切换 ⭐⭐⭐⭐⭐
Draw Call 提交次数 ⭐⭐⭐⭐
Batch 优化结果 ⭐⭐⭐
👉 面试金句:
优化核心不是单纯减少 Draw Call,而是减少 SetPass Call
三、为什么要"合批"
很多人误区:
❌ 合批越多越好
✅ 关键是减少材质切换(SetPass)
本质目标:
👉 减少"相同材质却被多次切换"的情况
四、Unity 四大批处理技术(重点)
1️⃣ Static Batching(静态批处理)
原理
编辑期 / 运行前:合并 Mesh
生成一个大 Mesh
特点
优点 缺点
减少 Draw Call 增加内存
运行时无CPU开销 不能移动
关键点
必须勾选:Static
会复制 Mesh(吃内存)
单批次:≈ 64k 顶点
2️⃣ Dynamic Batching(动态批处理)
原理
👉 CPU 实时合并小 Mesh
条件(非常苛刻)
顶点 ≤ 300
相同材质
相同缩放
Shader支持
评价(重点)
👉 实际项目中作用很小,甚至负优化
📌 建议:
Dynamic Batching 在现代项目中基本不依赖
3️⃣ GPU Instancing(最重要)
原理
👉 一次 Draw Call 渲染 N 个相同物体
CPU:发送一次 Mesh
GPU:用不同 Transform 渲染多个实例
特点
优点 说明
CPU 开销低 不重复提交
GPU 批量绘制 高效(稍微有所提升)
支持动态物体
使用条件
相同 Mesh
相同材质(同一个Material实例)
Shader支持 Instancing
4️⃣ SRP Batcher(现代核心)
👉 真正解决 SetPass 问题的方案
原理(重点理解)
传统:
每个材质 → 都要重新 SetPass
SRP Batcher:
👉 本质:SRP Batcher(Scriptable Render Pipeline Batcher)是 URP/HDRP 中的渲染优化技术,它的主要目的是减少 CPU 为不同材质准备和设置 GPU 数据(常量缓冲区 Constant Buffer)的开销,而不是像传统 Dynamic Batching 或 GPU Instancing 那样大幅减少 Draw Call 数量
Shader不变 (shader变体一致)→ 不重复 SetPass
只更新材质参数(CBUFFER)
SRP Batcher 核心条件(极简版):
必须相同:Shader Variant(着色器变体)
不需要相同:材质(Material) 和 Mesh(网格)
本质优化
👉 减少 SetPass Call,而不是 Draw Call
五、优先级(非常重要)
👉 综合结论:
SRP Batcher > GPU Instancing > Static Batching > Dynamic Batching
六、关键优化策略(实战总结)
-
材质优化(最核心)
👉 一切问题本质:材质太多
优化方法:
合图(Texture Atlas)
减少 Shader 变体
使用同一 Shader
-
合批策略选择
场景 方案
小物体 Dynamic(可选)
静态场景 Static
重复物体 GPU Instancing ⭐
URP/HDRP SRP Batcher ⭐⭐⭐
-
UI 优化
👉 UI 是 Draw Call 重灾区
优化:
合图(Sprite Atlas)
减少 Canvas
避免频繁重建
控制透明层级
-
光照优化
少用实时阴影
使用 Bake Lighting
减少光源数量
-
Mesh 合并
Mesh.CombineMeshes
适合静态小物件
七、透明物体 & Early-Z(进阶点)
Early-Z
👉 提前剔除被遮挡物体
仅对不透明物体有效
透明物体问题
👉 无法合批原因:
必须排序(从后往前)
→ 打破批处理
→ 增加 Draw Call / SetPass
八、性能判断标准
平台 Draw Call
PC < 1000
移动端 < 100
VR < 50
九、Profiler 分析方法
工具:
Stats 面板
Profiler(Rendering)
Frame Debugger ⭐
看什么:
Draw Calls
SetPass Calls
Saved by Batching


十、终极总结
Unity 渲染优化的核心是减少 CPU 向 GPU 提交渲染命令的开销,其中最关键的是降低 SetPass Call,其次是 Draw Call。
实际优化中应优先统一材质和 Shader,减少状态切换,再结合 SRP Batcher、GPU Instancing 等技术进行优化。
静态物体使用 Static Batching,重复物体使用 GPU Instancing,而 Dynamic Batching 在现代项目中作用有限。
最终目标是让 GPU 持续工作、减少 CPU 等待,从而提升整体帧率。
思维导图:
Unity 渲染优化
│
├── 一、核心指标
│ │
│ ├── Draw Call
│ │ ├── CPU → GPU 绘制命令次数
│ │ ├── 多 → CPU瓶颈
│ │ └── 目标:移动端 <100
│ │
│ ├── SetPass Call(重点)
│ │ ├── 渲染状态切换(Shader / 材质)
│ │ ├── CPU开销最大
│ │ └── 优先优化对象 ⭐⭐⭐⭐⭐
│ │
│ └── Batches
│ ├── 合批结果
│ └── 越少越好
│
├── 二、核心关系
│ │
│ ├── SetPass → Draw Call → Batch
│ └── 本质目标:减少状态切换(SetPass)
│
├── 三、批处理技术
│ │
│ ├── 1. Static Batching(静态)
│ │ ├── 合并 Mesh
│ │ ├── 不可移动
│ │ ├── 减少 Draw Call
│ │ └── ❗增加内存
│ │
│ ├── 2. Dynamic Batching(动态)
│ │ ├── CPU实时合批
│ │ ├── 顶点 ≤ 300
│ │ ├── 条件苛刻
│ │ └── ❗实际项目较少用
│ │
│ ├── 3. GPU Instancing ⭐
│ │ ├── 一次绘制多个实例
│ │ ├── 相同 Mesh + 材质
│ │ ├── GPU执行
│ │ └── 重复物体首选
│ │
│ └── 4. SRP Batcher ⭐⭐⭐
│ ├── 减少 SetPass
│ ├── Shader不变 → 不切换
│ └── URP/HDRP核心优化
│
├── 四、优化优先级
│
│ SRP Batcher
│ ↓
│ GPU Instancing
│ ↓
│ Static Batching
│ ↓
│ Dynamic Batching
│
├── 五、核心优化手段
│ │
│ ├── 材质优化(最重要)
│ │ ├── 合图(Texture Atlas)
│ │ ├── 减少 Shader 变体
│ │ └── 统一材质
│ │
│ ├── Mesh优化
│ │ ├── Mesh.CombineMeshes
│ │ └── 减少小物体
│ │
│ ├── UI优化
│ │ ├── 减少 Canvas
│ │ ├── 合图
│ │ └── 控制重建
│ │
│ ├── 光照优化
│ │ ├── Bake Lighting
│ │ ├── 减少实时光
│ │ └── 减少阴影
│ │
│ └── 批处理策略选择
│ ├── 静态物体 → Static
│ ├── 小物体 → Dynamic
│ ├── 重复物体 → Instancing
│ └── URP → SRP Batcher
│
├── 六、进阶知识
│ │
│ ├── Early-Z
│ │ └── 提前剔除不可见物体
│ │
│ ├── 透明物体
│ │ ├── 必须排序
│ │ └── ❗无法合批
│ │
│ └── 材质切换问题
│ └── 本质:SetPass增加
│
└── 七、性能分析工具
│
├── Stats 面板
├── Profiler(Rendering)
└── Frame Debugger ⭐