Unity 几种常见合批手段的要求
概述合批Batching是 Unity 渲染优化的核心手段目的是将多个绘制调用Draw Call合并为一个减少 CPU 与 GPU 之间的通信开销。Unity 中常见的合批手段有四种SRP BatcherGPU Instancing动态合批Dynamic Batching静态合批Static Batching每种合批方式都有严格的前提要求和互斥关系理解这些是正确使用它们的前提。1. SRP Batcher原理SRP Batcher 通过复用 CPU 端的Material数据缓冲区让 GPU 在同一绘制循环中快速切换材质数据而不需要重新绑定 Shader 和 Constant Buffer。适用于大量使用相同 Shader 变体但不同材质属性的渲染对象。前提要求要求说明渲染管线必须使用SRPURP / HDRP / 自定义 SRPBuilt-in Render Pipeline 不支持Shader必须编写兼容 SRP Batcher的 Shader。所有材质属性要通过CBUFFER声明SRP 核心库中的 Shader 默认满足Shader 变体合批的对象必须使用同一个 Shader 变体即 Shader 文件和 keywords 组合完全一致平台所有支持 DX10SM 4.0的平台均可开启在 Project Settings Graphics SRP Batcher 中开启默认开启不满足时的行为如果某个 Material 使用了不兼容 SRP Batcher 的 Shader该 Material 会回退到传统渲染路径不会影响其他兼容对象的 SRP Batcher 合批。与 GPU Instancing 的关系互斥。如果材质开启了Enable GPU InstancingUnity 会优先走 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_IDMesh必须完全相同同一个 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 BatcherGPU 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 已经被合并了。参与静态合批的物体仍然可以配合Lightmap、Occlusion 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. 实际使用建议优先使用 SRP BatcherURP/HDRP 项目默认开启它是最通用、约束最少、CPU 开销最低的方案。重复物体用 GPU Instancing尤其是草地、树木、弹壳、粒子等大量相同 Mesh 的场景。动态合批只用于 UI 或极小物体顶点数必须确认 ≤ 300且不要跟 GPU Instancing 混用。静态合批在老项目或 Built-in 管线中还有价值但在 SRP 管线中已被 SRP Batcher 部分替代且内存代价较高需谨慎使用。不要同时开启 SRP Batcher 和 GPU Instancing同一材质会互斥但可以同时开启 SRP Batcher 和静态合批。