Unity 游戏性能优化(3)Batching的优势
这章主要讨论动态批处理(dynamic batching)和静态批处理(static batching)。GPU Instancing 和 SRP 后期再讨论。
1. Draw calls
- draw call:CPU 向GPU 发送的渲染指令。
- 主要分两步:
- 上传纹理数据和网格数据到GPU
- 使用纹理数据设置网格的渲染
- GPU在切换渲染状态时消耗很大,Set Pass Call 显示切换次数。比Draw call还重要。
2. The Frame Debugger
使用Frame Debugger 可以帮助我们分析渲染状态,找出不能batching的原因
3. 动态批处理
-
特点:
- 运行时进行合批
- 可见的物体才可能进行合批
- 可动的物体也可以合批
-
需满足的条件:
- http://docs.unity3d.com/Manual/DrawCallBatching.html
3.1 顶点属性 要求
- 动态合批要求顶点数不能超过300个
- 注意:Unity加载的模型顶点数和模型原数据顶点数可能不一样。所以最好在Unity中Inspector的Preview窗口中确定顶点数。
- 动态合批要求顶点属性不能超过900. 顶点属性计算:顶点数*每个顶点上的属性数。如果使用的shader 有5个属性,那么顶点就不能超过900 / 5 = 180个
3.2 Mesh scaling 网格缩放 要求
- 如果有负缩放,这个是不能和全正数缩放一起合批的。但是可以跟其他的同负数个数的对象合批。比如(-1,1,1)可以和(1,-1,1)合批
3.3 动态合批要点
- 大量的简单模型情况下合批使用
- 如果因为使用不同的贴图导致不能合批,可以考虑将贴图和在一张图中,并且重新展UV。
- 多使用Frame Debugger来分析不能合批的情况
- 有时候可以调整不同材质物体间的渲染顺序来合批(比如:草和石头在一块,我们可以先渲染草再渲染石头,这样都能动态合批了。)
4. 静态合批
4.1 合批要求
- GameObject需要勾上 Static 选项
- 需要额外的内存来存放静态批处理后的结果网格
- 合批的顶点总数有限制:32000-64000之间
- 合批对象可以是不同的网格,但是必须是相同的材质球
4.2 内存问题
- 使用静态合批,很有可能增加内存
- 因为静态合批会把需要合批对象的网格,复制一份。如果有1000个相同的树,使用静态合批的内存就是不适用的1000倍。
4.3 其他需要注意的点
- 降低的Draw Call只能在运行中能看到
- 运行中动态创建的标注静态的对象,是不会自动被合批的
- 但是我们可以使用StaticBatchUtility.Combine() 对动态创建的对象进行静态合批
- 需要注意,这个方式消耗很大,不易在流程度敏感期间使用。
- 如果使用StaticBatchUtility.Combine() 的这个对象没有被标记Static,那么他其实是可以被移动的,除了他的网格外。就是说,可能会移动了Collider,但是网格还停留在原地。这种情况容易产生不期望的Bug,需要额外注意。