一、静态合批 (Static Batching)
这是最有效、最常用的合批方式,属于离线合批(在运行前完成)。
-
工作原理:
- 将不会移动、旋转、缩放的物体(如场景建筑、岩石)标记为 Static(在Inspector面板左上角勾选)。
- 在构建(Build)游戏或运行时的场景加载阶段,Unity会自动将这些静态物体的网格数据合并成一个大的顶点/索引缓冲区。
- 运行时,Unity直接渲染这个合并后的大网格,只需极少的Draw Call。
-
限制条件:
- 同一个材质实例。
-
优点:
- 性能极佳:运行时几乎无额外CPU开销。
- 无顶点数限制:可以合并非常复杂的模型。
-
缺点:
- 增加内存和存储空间:合并后的网格会复制顶点数据,而不是共享。例如两个相邻的立方体,原本共享的顶点在合并后会被复制,导致内存占用增加。
- 物体必须为静态:标记为Static的物体在运行时完全不能移动。
-
适用场景 :游戏场景中所有静止不动的环境物体。
-
官方提醒 :静态批次可包含的顶点数量是有限的。每个静态批次最多可包含64000个顶点。如果有更多,Unity会再创建一批。
二、动态合批 (Dynamic Batching)
Unity在运行时每帧自动尝试合并小型动态物体的技术。
-
工作原理 :每一帧,CPU会遍历使用相同材质的小型网格,动态地将它们的顶点数据转换到世界空间并合并到一个公共的顶点缓冲区中,然后用一个Draw Call绘制。
-
苛刻的限制条件官方文档:
-
Unity 无法对包含超过 900 个顶点属性和 300 个顶点的网格应用动态批处理。这是因为网格的动态批处理每个顶点都有开销。例如,如果你的着色器使用顶点位置、顶点法线和单个UV,然后Unity可以批量处理最多300个顶点。但是,如果你的着色器使用顶点位置、顶点法线、UV0、UV1 和顶点切线,那么 Unity 只能批量处理 180 个顶点。
-
如果GameObjects使用不同的材质实例,Unity无法把它们批量处理在一起,即使它们本质上相同。唯一的例外是阴影投射渲染。
-
带有光照贴图的GameObject会有额外的渲染器参数。这意味着,如果你想批量处理光照贴图的GameObject,它们必须指向相同的目标光照贴图位置。
-
Unity 无法对使用多通道着色器的 GameObjects 完全应用动态批处理。
-
优点 :全自动,对开发者透明。
-
缺点:
- 限制极多,实用性有限。
- CPU开销较大:因为每帧都要进行顶点变换和合并计算。如果过度使用,反而可能降低性能。
-
适用场景 :少量、小型的动态物体,如移动的子弹、金币等。不要依赖它作为主要的优化手段。
三、实战
我们用Unity原生的小球和方块,顶点数小球>300和方块<300。


我们可以在Unity的Project Settings > Player > Other Settings 是否开启静态和动态批处理

静态合批:只开启Static Batching
正常态下:
关闭灯光下,Batches数是5 (4个cube+1个天空盒)

开启FrameDebug,我们看到DrawMesh绘制了5次

勾选static:
运行,Batch数变为2,

对所有的Cube做了静态合批

增加小球:
Batch数依旧是2,是参与了静态合批的

增加其他材质的Cube:
Batch数会增加

静态批处理只会对同一材质实例的物体进行合批,如果是不同材质实例但参数一致也会导致静态合批失败。

动态合批:只开启Dynamic Batching
顶点数小于300的Cube:
可以动态合批

顶点数大于300的Sphere:
不可以动态合批

不同材质的Cube:
不可以动态合批

同时满足静态合批和动态合批:
Unity会优先当作动态合批处理:
比如两个都勾选static的小球
