哪些内容需要被Batching
广义上讲:
- 资源Batching(Mesh、Textur、Shader参数、材质属性)
- DrawCall Batching(Static Batching、Dynamic Batching)
- GPU Instance(直接渲染、间接渲染、程序化间接渲染)
- Set Pass Call Batching(SRP Batching)
资源的Batching
Mesh
- Mesh.CombineMesh 合并静态网格对象
- Submeshes->Single Mesh 合并材质与贴图,不同材质通过通道图标记
Texture
- AtlasTexture 通过纹理坐标映射多张贴图
- TextureArray 纹理数组
Shader变量与材质属性
- Material Property Block(Build In 管线)
- Const buffer(SRP管线)
Draw Call Batching
- Static Batching
- Dynamic Batching
GPU Instancing
GPU Instancing也是一种Batching,用于渲染网格的多个副本;它是将基础网格对象传递给GPU后,充分利用Instancing Buffer的方法,传递多个网格实例位置、朝向与颜色等其他属性构成的Instancing Buffer到GPU,避免了反复传递多个基础网格对象在世界空间下变化后的顶点数据和其他额外数据,所有的实例都会引用同一个基础网格对象,非常适合用于创建植被、石头等场景中大量重复的网格对象;
- DrawMeshInstanced
- DrawMeshInstancedIndirect
- DrawMeshInstancedProcedural
SetPassCall Batching
- SRP Batcher
- Const Buffer
- UnityPerCamera
- UnityPerFrame
- UnityPerPass
- UnityPerDraw
- UnityPerDrawRate
- UnityPerMaterial
Batching优化顺序
资源Batching > SRP Batching = Static Batching > GPU Instancing > Dynamic Batching
Batching的限制
Static Batching
- 额外内存开销
- 64000个顶点限制
- 影响Culling剔除
Dynamic Batching
- 合批不超过900个顶点属性(注意不是900个顶点)
- 除了渲染阴影对象外,相同材质,不同材质实例也不能合并
- 具有光照贴图的游戏对象如果有附加渲染器参数时,如果需要动态合批这些对象,他们必须指向相同的光照贴图位置
- 有多Shader Pass的游戏对象无法做动态合批
- 受多个光照影响的游戏对象,满足动态合批条件合批后,只会受一个光源的影响
- 延迟渲染不支持动态合批
- CPU开销可能会增大,需要测试开启使用
GPU Instancing
- 图形API版本要求
- 与SRPBatcher不兼容
- 不同绘制API的参数与绘制个数不同
- 渲染顶点数较少的网格时,效率可能会较差
SRP Batching
- 图形API版本要求
- 必须是SRP渲染管线
- 粒子对象不能合批
- 使用MaterialPropertyBlocks的游戏对象不能合批
- Shader必须是compatible的
Batching失败原因
- 此物体受到多个前向灯光影响
- 此物体拥有不同的材质
- 此物体使用了多Pass着色器
- 此物体Transform的Scale使用了负数
- 此物体接受阴影的设置不同,或者物体有不同的阴影距离设置
- 此物体受到不同的前向灯光影响
- 此物体在不同的Lighting Layer上
- 此物体有不同的投影体设置
- 此物体有不同的投影着色器设置或者有不同的着色器属性或者关键字影响Shadow Caster Pass的输出
- 着色器中显式设置了DisableBatching的标记
- 此物体有不同的MaterialPropertyBlock集合
- Instanced的着色器有非Instanced属性集
- 此物体使用了不同的LightMap或者虽然使用相同的LightMap但使用的UV不同
- 此物体受到不同的光照探针影响
- 此物体烘焙了遮挡,并且设置了不同的遮挡因子
- 此物体受到不同的反射探针影响
- 使用GPU实例化渲染不同的网格或子网格
- 此物体有不同的静态合批设置
- 此物体归属不同的Static Batches
- 在Player Settings中关闭了动态合批,或者在当前的环境中为了避免深度冲突而临时关闭了合批
- 动态合批中有太多的索引(大于32k)
- Mesh Renderer具有其他顶点流,动态批处理不支持此类网格渲染器
- 动态合批超过300个顶点
- 动态合批超过900个顶点属性
- 新阴影级联的第一次绘制调用
- 材质未启用GPU Instancing功能
- 使用不同的渲染,如果渲染器的类型不同(例如网格/蒙皮网格),或者在同一渲染器中使用不同的设置(例如精灵遮罩),则可能会发生这种情况
- 此对象具有不同的Batching Keys,这通常是由于粒子系统上使用不同的顶点流,或混合线和轨迹,或混合Lit和Unlit的几何体造成的
- Mesh使用了32位的索引缓冲
- 子网格对象有非0的基础顶点,submesh.BaseVertexLocation != 0
- 先前的InstanceDrawCall已经达到了Instance的最大数量
- Motion Vector的渲染不支持Batching
- 使用late latching时,XR late latched GameObject的子级不能合批
- 对象具有不同的包裹体,那么包裹体实例化被禁用
以下为SRP Batching失败
- 节点具有不同的着色器
- 节点使用了多Pass着色器
- 节点使用了不同的着色器关键字
- Batch Flush结束
- 节点与SRP Batcher不兼容
- 节点材质需要改变渲染设备状态
- ScriptableRenderLoopJob第一次调用
- 材质有自定义重写的Buffer