【Unity】批处理和实例化的底层优化原理(未完)
【Unity】批处理和实例化的底层优化原理
- 1.基础概念
- SetPassCalls
- DrawCalls
- Batches
- 2.重要性排序
- 既然如此为什么仍然要合批?
- 3.unity主流的合批优化方案和优先级
- Early-Z
- 透明物体情况
- 4.合批(小场景但是很复杂很多小物件刚需)
- 合并纹理图集更改uv映射(共享材质)
- 静态合批(一批次最多是64000顶点)
- 刺客信条场景案例
- 手动合批
- 动态合批
以下图片以及理解均来自b站up主:别看着我笑了。直达链接
侵权请联系我,第一时间删除!
看前须知渲染管线基本流程!!!!!!(games101前9课)
1.基础概念
SetPassCalls
这是对drawcall的准备工作,CPU设置资源和改变内部设置的地方,称之为渲染状态(下面有Unity的状态图)。例如改变材质,是图形API消耗极大的操作。
- Unity可设置渲染的状态
豆包解释:
DrawCalls
Batches
2.重要性排序
通过实验和例子发现,如果setpass相同的话(这里体现在更换材质),批次的多与少对渲染性能的优化其实是微乎其微的,甚至会更差。
这个例子更能看出区别,上面是合批优化的,下面是减少setpassCall的,可以发现前者虽然合批到了极致,但是后者只通过将不同的材质合批减少了一次setpassCall耗时就低于了前者,说明在渲染消耗的时间setpassCall是占大头的。
既然如此为什么仍然要合批?
既然合批之后的时间甚至不如不合批,那为什么我们还要去优化批次呢?
原因:unity可以识别一些简单的物体是否是相同的材质,并且自动合批,但是在大多数复杂的环境下unity在渲染的时候不能分辨哪些是同一个材质,只是在某些复杂场景下,比如动态物体较多、材质变体复杂等情况,可能无法完美做到所有相同材质物体都能高效合并,导致仍存在多次切换相同材质引发 SetPass Call 的情况,所以合批是为了让尽可能减少的切换到相同材质的情况导致多次调用 SetPass Call。
3.unity主流的合批优化方案和优先级
Early-Z
可以在渲染之前确定不透明物体是否要渲染,是否遮挡并且剔除。然而如果遇到半透明物体由于需要确定透明物体后面的材质,所以不可避免的需要切换渲染状态。
透明物体情况
左图勾选静态合批,如果没有红球,那么在profile页面确确实实看到了静态合批减少了2次DrawCall(显示在Static Batching栏中),而加上红球后,由于前面的透明物体的渲染必须先知道后面的物体是怎么渲染的才能渲染,所以前面和最后面的透明物体无法合批一同渲染,因此批次增加了3(2透明球,1红色球)。
4.合批(小场景但是很复杂很多小物件刚需)
本质:
合并纹理图集更改uv映射(共享材质)
- 如果多个模型相同或不同的物体(主要看Transform是不是静态的),材质不同,可以通过合并图集更改uv映射,来减少材质更换的次数。
- !局限性:合并图集可能增加纹理内存占用,若纹理利用率低,会浪费内存;调整 UV 映射过程较复杂,尤其是模型结构复杂时,手动调整工作量大,还可能影响纹理映射效果;此外,如果模型材质有复杂的动态变化效果,这种方式可能无法很好地满足需求。
静态合批(一批次最多是64000顶点)
原理:仅仅一次处理!!!
-
当使用的材质是多 Pass(一个渲染过程中执行多个渲染通道,比如一些复杂材质可能既要渲染基础颜色,又要渲染高光、阴影等,每个步骤算一个 Pass )时,静态批处理依然有效
-
然而如果合并多个相同网格会增加CPU的内存,不合并又会增加渲染时间,up主给出的建议是合并不同模型相同材质的静态网格物体,不过我个人认为下面说法更正确。
-
实际开发中要怎么权衡这种空间换时间的利弊呢?
总结:
1.合并相同且靠近的网格,但又不能过多。
2.考虑平台对内存资源的紧张程度,以及优先性。例如CSGO需要高帧数那么应该在许可的范围内以空间换时间,而在移动平台等资源紧张的平台应该更关注CPU内存的使用。
3.大型复杂场景对GPU压力大的情况下,尽可能利用CPU缓解压力。
刺客信条场景案例
把一个大的模型拆分成多个小块,通过小块之间的不同组合,实现不同的形状,使用同一个材质对应的uv地段,再通过shader脚本的编写就可以达成宏达而完美的场景甚至不用切换材质!
手动合批
任何相对运动且相对静止的物体,都可以通过再unity中调用Mesh.CombineMeshes,或者在建模软件中给它合批了。
然而unity不能自主的剔除手动合批的物体,您需要自己剔除(cull)!
动态合批
是在CPU中处理的。
据说很鸡肋使用条件十分之苛刻,只能在很有限的范围内进行优化,甚至是负优化,HDRP甚至不支持。
然而动态合批能够很好的处理unity的粒子系统。