下面详细讲解 Unity 的 Dynamic Batching(动态合批),包括原理、条件、优缺点、常见问题和优化建议。
1. 什么是 Dynamic Batching?
Dynamic Batching 是 Unity 的一种自动合批技术,目的是将多个小型、动态物体的渲染请求合并为一次 Draw Call,从而减少 CPU 到 GPU 的通信次数,提高渲染效率。
- “动态” 指的是这些物体可以移动、旋转、缩放(不是静态的)。
- “合批” 指的是多个物体一起提交给 GPU 绘制。
2. Dynamic Batching 的工作原理
- Unity 在渲染时会检测场景中所有满足条件的小型动态物体。
- 如果它们的材质、渲染状态等一致,Unity 会在 CPU 端把它们的顶点数据合并到一个大缓冲区,然后一次性提交给 GPU。
- 这样多个物体只产生一次 Draw Call。
3. 启用方式
- Player Settings > Other Settings > Dynamic Batching 勾选即可(默认开启)。
- 也可以通过脚本
PlayerSettings.enableDynamicBatching控制。
4. 合批条件(非常重要!)
只有同时满足以下条件的物体,Unity 才会自动进行 Dynamic Batching:
- 使用相同的材质(Material)
- 材质参数完全一致(如贴图、Shader、颜色等)。
- 顶点数限制
- 每个物体的顶点数 ≤ 300(有些平台是 900,具体看 Unity 版本和平台)。
- 合批后总顶点数不能超过 900。
- Mesh 不能有太多变形
- 不能有顶点动画(如 SkinnedMeshRenderer)。
- 不能有动态变形(如 BlendShape)。
- 渲染状态一致
- 例如:光照贴图、阴影、渲染队列、剔除设置等要一致。
- Transform 不能有非均匀缩放
- 即 x、y、z 缩放比例要相等。
- Shader 必须支持
- Shader 不能用
Pass标签,不能有多 Pass,不能用GrabPass。
- Shader 不能用
- 不能使用 GPU Instancing
- Instancing 和 Dynamic Batching 互斥,开启 Instancing 的物体不会被动态合批。
5. 优缺点
优点
- 自动化:无需手动合批,Unity 自动处理。
- 减少 Draw Call:适合大量小型动态物体(如子弹、金币、粒子等)。
缺点
- CPU 开销:每帧都要在 CPU 端合并顶点数据,物体多时反而拖慢性能。
- 顶点数限制:只适合小物体,复杂模型无法合批。
- 不适合大规模场景:大场景建议用 GPU Instancing 或 Static Batching。
6. 常见问题与误区
- 为什么我的物体没被动态合批?
- 检查是否满足上面所有条件,尤其是材质、顶点数、缩放、Shader。
- 动态合批和静态合批能一起用吗?
- 可以,但同一个物体只能属于一种合批方式。
- 动态合批和 GPU Instancing 能一起用吗?
- 不能,Instancing 优先级更高。
- 动态合批会增加内存吗?
- 不会像静态合批那样增加显存,但会增加 CPU 计算量。
7. 性能建议
- 小型、动态、重复物体:适合用 Dynamic Batching。
- 大量相同物体:优先考虑 GPU Instancing。
- 静态不动物体:用 Static Batching。
- 材质合并:减少材质种类,提高合批率。
- 避免非均匀缩放:保持物体缩放一致。
8. 如何查看动态合批效果?
- Game 视图 Stats 面板
- Batches(批次)数减少,说明合批生效。
- Dynamic Batching: xx batched(显示动态合批了多少物体)。
- Frame Debugger
- 可以逐步查看每个 Draw Call 是否为动态合批。
9. 实际案例
假设有 100 个金币,每个金币 100 顶点,材质完全相同,且都在移动:
- 开启 Dynamic Batching:理论上只需 1 个 Draw Call。
- 金币顶点数超过 300:无法合批,产生 100 个 Draw Call。
- 金币材质不同:无法合批,产生 100 个 Draw Call。
- 金币有非均匀缩放:无法合批。
10. 总结
- Dynamic Batching 是 Unity 针对小型动态物体的自动合批技术。
- 合批条件严格,适用场景有限。
- 优化 Draw Call 的同时要注意 CPU 开销。
- 大量相同物体建议用 GPU Instancing,静态物体用 Static Batching。
下面继续深入讲解 Dynamic Batching 的更多细节,包括调试方法、常见合批失败原因、与其他合批方式的对比、实际开发建议等。
1. 如何调试和验证 Dynamic Batching 是否生效?
1.1 Stats 面板
- 在 Game 视图点击左上角的 Stats 按钮。
- 观察 Batches(批次)和 Saved by batching(有的版本显示为“Batched Draw Calls”)。
- 如果 Dynamic Batching 生效,通常会看到类似:
Batches: 10 Saved by batching: 90 Dynamic Batching: 90 batched - 说明有 90 个物体通过动态合批被合并了。
1.2 Frame Debugger
- 打开 Window > Analysis > Frame Debugger。
- 点击 Enable,逐步查看每个 Draw Call。
- 动态合批的 Draw Call 通常会显示为:
Dynamic Batching: (X meshes) - 可以点开看具体合批了哪些物体。
2. 常见 Dynamic Batching 失败原因及排查方法
2.1 材质不一致
- 原因:即使 Shader 一样,只要材质参数(如颜色、贴图)不同,也无法合批。
- 排查:确保所有物体引用同一个材质实例。
2.2 顶点数超限
- 原因:单个物体顶点数超过 300(或平台限制),无法合批。
- 排查:检查 Mesh 顶点数,必要时简化模型。
2.3 非均匀缩放
- 原因:Transform 的 x、y、z 缩放不一致。
- 排查:检查物体的缩放属性,保持一致。
2.4 Shader 不支持
- 原因:Shader 使用了多 Pass、GrabPass、Pass 标签等。
- 排查:使用 Unity 标准 Shader 或自定义 Shader 时避免多 Pass。
2.5 动态变形
- 原因:如 SkinnedMeshRenderer、BlendShape、顶点动画等。
- 排查:只对普通 MeshRenderer 有效。
2.6 使用了 GPU Instancing
- 原因:开启 Instancing 的物体不会被动态合批。
- 排查:材质 Inspector 里 Instancing 选项是否勾选。
3. Dynamic Batching 与其他合批方式的对比
| 合批方式 | 适用对象 | 优点 | 缺点 |
|---|---|---|---|
| Dynamic Batching | 小型动态物体 | 自动合批,易用 | CPU 开销大,顶点数限制 |
| Static Batching | 静态不动物体 | 合批效果好,Draw Call 少 | 占用内存,需静态标记 |
| GPU Instancing | 大量相同物体 | Draw Call 极少,效率高 | 需 Shader 支持,属性有限 |
4. 实际开发建议
4.1 何时用 Dynamic Batching?
- 场景中有大量小型、动态、重复的物体(如金币、弹壳、粒子等)。
- 物体顶点数较少,材质完全一致。
- 不适合大模型、复杂动画、材质多样的场景。
4.2 何时不用 Dynamic Batching?
- 物体顶点数大于 300。
- 物体需要用 Instancing(如大面积草地、士兵)。
- 物体是静态的(用 Static Batching 更高效)。
4.3 优化建议
- 合并材质:减少材质种类,提升合批率。
- 简化模型:降低顶点数,适应动态合批条件。
- 避免非均匀缩放:保持物体缩放一致。
- 合理选择合批方式:根据物体类型选择最合适的合批方式。
5. 代码示例:动态合批的典型用法
// 假设有一个金币预制体 goldPrefab,材质 goldMaterial
for (int i = 0; i < 100; i++)
{
GameObject gold = Instantiate(goldPrefab);
gold.GetComponent<MeshRenderer>().sharedMaterial = goldMaterial; // 确保用同一个材质
gold.transform.position = Random.insideUnitSphere * 10f;
gold.transform.localScale = Vector3.one; // 保证缩放一致
}
- 这样生成的金币,如果顶点数不超限,都会被动态合批。
6. 进阶:动态合批的底层原理
- Unity 在 CPU 端将所有满足条件的 Mesh 数据合并到一个大缓冲区。
- 合批后的数据一次性提交给 GPU。
- 每帧都要重新合并,CPU 有一定开销。
- 合批失败的物体会单独产生 Draw Call。
7. 总结
- Dynamic Batching 是 Unity 针对小型动态物体的自动合批技术,能有效减少 Draw Call,但有顶点数和材质等多种限制。
- 实际开发中要根据物体类型、数量、材质等合理选择合批方式,避免盲目依赖动态合批。
- 通过 Stats 面板和 Frame Debugger 可以方便地调试和验证合批效果。
1091

被折叠的 条评论
为什么被折叠?



