参考链接:
https://www.jianshu.com/p/8a9ccf34860e
https://www.jianshu.com/p/39b3702eb4f3
https://www.jianshu.com/p/061e67308e5f
https://blog.csdn.net/akak2010110/article/details/80964416
一.渲染顺序
1.UI-Default.shader
UI默认使用内置shader(UI-Default),即处于Transparent队列中,是半透明对象。在这个队列中,为了得到正确的遮挡效果,必须从后往前渲染(相对于相机)
2.深度
UGUI和NGUI一样,也有深度的概念,不过前者是内部计算的,后者是手动控制的。深度的计算和Hierarchy窗口的顺序有关,靠上的UI会被画在底部。
深度(层次)计算方法:
计算好深度后,就会进行合批:
a.使用多条件Depth、MaterialID、TextureID、RendererOrder(HierarchyOrder)对UI元素进行排序(条件的优先级依次递减)
b.对相邻而且可以合批的UI元素进行合批
因此,控制UI元素的深度就是合批的关键了,尽量使UI元素处于同一深度
结论:
a.相同材质的UI可以叠在一起(例如AAA,占1个dc),避免中间插入不同材质的(例如ABA,占3个dc,因为这样会破坏合批)
测试:
a.2个dc
b.4个dc
c.3个dc
二.Mask & RectMask2D
1.RectMask2D
a.不需要依赖Image组件,其裁剪区域就是其RectTransform的矩形区域
b.RectMask2D组件自身不会占用dc(如下,2个dc)
c.RectMask2D内部的元素依然可以正常合批,但无法和RectMask2D外部的元素合批,即使都使用同一材质(如下,4个dc)
d.多个RectMask2D不能合批,即每个RectMask2D都是独立的(如下,4个dc)
e.完全裁掉的部分不占dc(如下,2个dc)
f.在Hierarchy中原本连续可以被合批的元素,如果中间插入RectMask2D,那么合批可能会被打断(如下,6个dc)
2.Mask
a.需要依赖Image组件,其裁剪区域就是Image的矩形区域
b.Mask组件自身会占用2个dc,一个在底下设置Stencil Buffer,一个在顶上还原Stencil Buffer,Mask下的子元素夹在中间(如下,4个dc)
c.Mask内部的元素依然可以正常合批,但无法和Mask外部的元素合批,即使都使用同一材质(如下,6个dc)
d.多个Mask可以合批,即Mask之间是共通的(如下,4个dc)
e.完全裁掉的部分会占dc(如下,6个dc)
f.在Hierarchy中原本连续可以被合批的元素,如果中间插入Mask,那么合批不受影响(如下,6个dc)
结论:
a.并非Mask越多就越不好,因为Mask之间是可以合批的,而RectMask2D之间是不可以合批的,因此,当一个界面有:
1个滑动列表:使用RectMask2D,因为单个RectMask2D性能高于单个Mask
大于1个滑动列表:当滑动列表里的元素都比较简单时(例如测试例子只占2个dc),可以用RectMask2D;否则用Mask。具体使用哪个组件,和滑动列表的数量和里面元素的复杂度有关
b.不要把RectMask2D放在可合批的元素中间,尽量放后面
三.其他
1.RawImage
一般来说,1个RawImage占1个dc,但如果有2个RawImage都用同一张Texture,那就可以合批,占1个dc(因为相同材质)
2.合批不受UI控件类型影响
1个Image和1个RawImage,如果都用同一张Texture,那就可以合批,占1个dc(因为相同材质)
3.3D UI
当UI元素的PosZ不为0时,就会被视为3D UI,导致无法合批
当UI元素的RotX和RotY修改后,若元素不在UI平面内,则无法合批,原因同上