Unity 几种常见合批手段的要求

📅 2026/7/23 4:42:28 👁️ 阅读次数 📝 编程学习
Unity 几种常见合批手段的要求

概述

合批(Batching)是 Unity 渲染优化的核心手段,目的是将多个绘制调用(Draw Call)合并为一个,减少 CPU 与 GPU 之间的通信开销。Unity 中常见的合批手段有四种:

  • SRP Batcher
  • GPU Instancing
  • 动态合批(Dynamic Batching)
  • 静态合批(Static Batching)

每种合批方式都有严格的前提要求互斥关系,理解这些是正确使用它们的前提。


1. SRP Batcher

原理

SRP Batcher 通过复用 CPU 端的Material数据缓冲区,让 GPU 在同一绘制循环中快速切换材质数据,而不需要重新绑定 Shader 和 Constant Buffer。适用于大量使用相同 Shader 变体但不同材质属性的渲染对象。

前提要求

要求说明
渲染管线必须使用SRP(URP / HDRP / 自定义 SRP),Built-in Render Pipeline 不支持
Shader必须编写兼容 SRP Batcher的 Shader。所有材质属性要通过CBUFFER声明(SRP 核心库中的 Shader 默认满足)
Shader 变体合批的对象必须使用同一个 Shader 变体(即 Shader 文件和 keywords 组合完全一致)
平台所有支持 DX10+(SM 4.0+)的平台均可
开启在 Project Settings > Graphics > SRP Batcher 中开启(默认开启)

不满足时的行为

如果某个 Material 使用了不兼容 SRP Batcher 的 Shader,该 Material 会回退到传统渲染路径,不会影响其他兼容对象的 SRP Batcher 合批。

与 GPU Instancing 的关系

互斥。如果材质开启了Enable GPU Instancing,Unity 会优先走 GPU Instancing,不会走 SRP Batcher。


2. GPU Instancing

原理

GPU Instancing 将多个相同 Mesh、相同 Material的渲染实例打包为一个 Draw Call,数据以 Instance Buffer 形式传给 GPU,由 GPU 一次性绘制。适合大量重复物体如草、树、子弹、粒子等。

前提要求

要求说明
ShaderShader 必须声明#pragma multi_compile_instancing,并在顶点着色器中调用UNITY_VERTEX_INPUT_INSTANCE_ID/UNITY_SETUP_INSTANCE_ID
Mesh必须完全相同(同一个 Mesh 引用)
Material必须使用同一个 Material 实例(同一个引用,而非属性相同)
批次数量单个 Draw Call 的实例数量受 GPU 限制(通常 500~1023 个实例)
开启Material Inspector 中勾选Enable GPU Instancing

额外说明

  • 每个实例可以通过MaterialPropertyBlock传递不同的属性(如颜色、缩放等),但MaterialPropertyBlock的字段必须在 Shader 中声明为UNITY_INSTANCING_BUFFER_START/END
  • 不支持LOD 组内不同 LOD 级别的合批(不同 LOD 模型不同,无法 Instancing)。
  • 如果 Mesh 使用 SkinnedMeshRenderer,需要额外的兼容处理(部分平台不支持)。

互斥关系

合批方式是否兼容
SRP Batcher❌ 互斥,开启 GPU Instancing 后不走 SRP Batcher
动态合批❌ 互斥
静态合批❌ 互斥,但物理上不太会同时使用

3. 动态合批(Dynamic Batching)

原理

Unity 在 CPU 端将多个小 Mesh 合并为一个大的 Vertex Buffer,然后一次性提交 GPU 绘制。Unity 会自动检测满足条件的渲染器在每帧进行合并。

前提要求

要求说明
顶点数单个 Mesh 的顶点数≤ 300,<=900个顶点属性(Shader 中如果使用了某些属性会增加顶点计算量,实际会更严格)
UV 通道最多支持UV 0 和 UV 1,如果使用 UV 2、UV 3 则无法动态合批
光照如果使用多 Pass Shader(包含多个 ForwardBase/ForwardAdd Pass),动态合批会失效
材质参与合批的物体必须使用完全相同的 Material(同一个引用)
变换物体不能同时受多个缩放因子不一致的父级影响,Uniform Scale 环境下表现最佳
镜像变换负缩放(Scale 为负数)会导致法线计算错误,动态合批会自动跳过

性能代价

动态合批是在CPU 端每帧合并顶点数据,对于顶点数较多的物体反而会拖慢性能。因此它只适合少量小顶点物体(如粒子、小道具)。

互斥关系

合批方式是否兼容
SRP Batcher可以共存,但如果一个物体走动态合批就不会走 SRP Batcher
GPU Instancing❌ 互斥
静态合批❌ 互斥,同一物体不会同时参与两者

4. 静态合批(Static Batching)

原理

构建时(Build / Baking)将标记为Batching Static的物体合并到一个大的 Vertex Buffer 中,并生成统一的 Index Buffer。运行时直接作为一个 Mesh 提交绘制。

前提要求

要求说明
Static 标记物体必须勾选Static或单独勾选Batching StaticFlag
材质参与合批的物体必须使用相同的 Material
移动物体在运行时不能移动、旋转、缩放
内存静态合批会创建合并后的大 Mesh,会显著增加 Build 后包体和运行时内存
顶点属性不同 Mesh 可以有不同顶点格式,Unity 会自动补齐

注意事项

  • 静态合批会禁用 GPU Instancing(因为 Mesh 已经被合并了)。
  • 参与静态合批的物体仍然可以配合LightmapOcclusion Culling使用。
  • 如果场景中有大量重复物体(如路灯),静态合批后的 Mesh 无法利用 GPU Instancing,反而可能不如单独走 Instancing。

互斥关系

合批方式是否兼容
SRP Batcher可以共存。静态合批只是合并几何数据,渲染时仍走 SRP Batcher 管线
GPU Instancing❌ 互斥。合批后的 Mesh 无法 Instancing
动态合批❌ 互斥。静态合批优先级更高

5. 合批对比总表

特性SRP BatcherGPU Instancing动态合批静态合批
适用管线URP / HDRPAllAllAll
合批时机运行时(GPU 端)运行时(GPU 端)运行时(CPU 端)构建时
相同 Mesh不需要必须相同不需要不需要
相同 Material不需要(相同 Shader 变体即可)必须相同引用必须相同必须相同
顶点限制≤ 300
内存/CPU 开销高(CPU 合并)中(构建时增加内存)
运行时移动可以可以可以❌ 不可以
与 SRP Batcher 兼容❌ 互斥✅ 共存但二选一✅ 共存
与 GPU Instancing 兼容❌ 互斥❌ 互斥❌ 互斥
推荐场景大量不同材质但同 Shader 的对象大量相同物体(草、树、子弹)少量小顶点物体完全静止的环境物体

6. 实际使用建议

  1. 优先使用 SRP Batcher(URP/HDRP 项目默认开启),它是最通用、约束最少、CPU 开销最低的方案。
  2. 重复物体用 GPU Instancing,尤其是草地、树木、弹壳、粒子等大量相同 Mesh 的场景。
  3. 动态合批只用于 UI 或极小物体,顶点数必须确认 ≤ 300,且不要跟 GPU Instancing 混用。
  4. 静态合批在老项目或 Built-in 管线中还有价值,但在 SRP 管线中已被 SRP Batcher 部分替代,且内存代价较高,需谨慎使用。
  5. 不要同时开启 SRP Batcher 和 GPU Instancing(同一材质会互斥),但可以同时开启 SRP Batcher 和静态合批