UPL6-6——DrawCall 优化方案对比
UPL6-6——DrawCall 优化方案对比
DrawCall 优化方案对比
| 方案 | 动态批处理 | 静态批处理 | GPU Instancing | SRP Batcher |
|---|---|---|---|---|
| 原理 | 运行时 CPU 每帧合并网格 运行时每帧动态合并小型网格的顶点数据 |
构建或首次运行时 CPU 合并网格 运行前合并静态物体的网格为一个大网格 |
GPU端批量绘制相同物体 一次 DrawCall 提交共享网格和实例数据,GPU 并行绘制多个对象 |
不减少 DrawCall,是将物体、材质参数缓存到 GPU,减少 CPU 开销 不合并网格,通过持久化 GPU 缓冲区优化材质、对象数据提交,降低 DrawCall 的CPU 开销 |
| 限制 | 网格顶点数小于 225 或 300 (Unity 2021 之前为 300) 并且顶点属性小于 900 相同材质实例 禁止镜像缩放、蒙皮、实时投影等 |
必须标记为静态批处理对象 相同材质实例 物体不可移动、旋转、缩放 每个静态批次最多可以包含 64,000 个顶点 |
相同网格 材质需启用 GPU Instancing 功能,并且支持该功能 不支持蒙皮网格渲染器等等 |
仅限 SRP 管线(URP / HDRP) 着色器需要兼容 SRP Batcher 功能 禁用 MaterialPropertyBlock 等等 |
| 优点 | 支持动态移动物体 自动化处理小型物体 小模型能显著减少 DrawCall |
显著减少静态物体 DrawCall 运行时 CPU 负担小 |
CPU 压力小 一次 DrawCall 绘制大规模相同物体 支持动态变换 |
CPU 提交极少,大幅降低 DrawCall 的 CPU 开销 支持蒙皮网格渲染器兼容不同材质实例 |
| 缺点 | CPU消耗较大 限制条件严格 不能和 SRP Batcher 一起用 |
内存占用高 静态物体不可变换(移动、旋转、缩放) |
必须相同网格 Shader 需要额外适配 |
仅支持 SRP 管线 需重写自定义着色器 |
| 适用场景 | 少量动态小物体 如会变换的箱子、树叶、小汽车、小粒子等等 |
静止的场景物件 如建筑、山体、岩石、房屋等 |
大量重复物体 如草、树、子弹、单位兵团等 |
SRP 项目中材质复杂、动态物体多的情况 |
| DrawCall 减少 | 有限(仅小物体) | 显著 | 极显著 (一次 DrawCall 绘制成千实例) |
不减少 DrawCall |
推荐使用优先级
-
SRP Batcher
- 适用条件:仅限 URP / HDRP 项目
- 组合逻辑:必选,它是 SRP 关键的基础优化技术,如果 Shader 不支持,优先让其支持
-
GPU Instancing
- 适用条件:大量动态、静止的重复物体(相同网格、材质)
- 组合逻辑:主力替代动态批处理,表现优于动态批处理
-
静态批处理
- 适用条件:完全静止的物体,需要注意内存问题
- 组合逻辑:静态场景专用,在确定内存可控时使用,它与 GPU Instancing 互斥
-
动态批处理
- 适用条件:动态、静止的重复物体(相同网格、材质)
- 组合逻辑:最后备选,仅无法用 GPU Instancing 时启用,如无使用它的情况,建议主动关闭节省 CPU 开销
按对象情况思考
| 对象情况 | 首选方案 | 替代方案 | 应避免方案 |
|---|---|---|---|
| 静止对象 + 内存充足 | 静态批处理 | 手动合并网格 SRP Batcher |
动态批处理 不做优化 |
| 静止对象 + 内存紧张 | 手动合并网格 SRP Batcher |
GPU Instancing | 静态批处理 不做优化 |
| 动态对象 + SRP 项目 | SRP Batcher | GPU Instancing | 不做优化 |
| 动态对象 + 内置渲染管线 | GPU Instancing | 动态批处理 | 不做优化 |
核心优化思路:
-
静态物体:
- 内存换性能 —> 静态批处理
- 内存敏感 —> 手动合并网格
-
URP 动态物体:
- 默认使用 SRP Batcher
- 存在大量相同网格对象时,追加使用 GPU Instancing
-
内置渲染管线 动态物体:
- 网格相同 —> GPU Instancing
- 网格不同 —> 小物体动态批处理
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 文KRIFE齐的博客!
