Mask和RectMask2D组件是什么?
Mask
Mask是遮罩,不是可见的控件,而是一种修改控件子元素外观的方法。遮罩将子元素显示为父元素的形状,如果子元素大于父元素,那么子项仅显示包含在父项的部分。
Mask组件需要依赖一个Image组件,裁剪区域就是Image的大小,其性质包括:
- Mask会在首尾(首=Mask节点,尾=Mask节点下的孩子遍历完后)多出两个drawcall,Mask下的子节点Image导致1个drawcall。证明如下:
-
新建一个场景,默认drawcall(batches)数是2,其中包括天空盒1个drawcall,Camera1个drawcall。
-
添加一个Mask(Mask对象上有一个Image组件,子节点也是一个Image),可以观察到,drawcall变成了5个,得出一个Mask导致3个drawcall,通过Frame Debug工具查到drawcall来源为:Mask导致2个drawcall(第1个和第三个,一头一尾),Mask下的子节点Image导致1个drawcall(中间)
-
- 多个Mask间如果符合合批条件这两个drawcall可以对应合批(mask1的首和mask2的首合,mask1的尾合mask2的尾合,首尾不能合)。证明如下:
-
复制一个Mask,让两个MasK的位置不重叠,可以观察到,drawcall还是5个,没有变化,这是因为Unity把2个Mask进行了网格合并。这里可以看出,Mask之间是可以进行合并的,从而不额外增加drawcall。
-
如果把两个Mask重叠,可以观察到drawcall升至8,这是因为Unity的合批需要同渲染层级(depth)、同材质、同图集,如果重叠了,depth就不同了,不满足合批条件,所以会再增加三个drawcall。
-
- Mask内的UI节点和非Mask内的UI节点不能合批。证明如下:
-
将两个图片设置为不重叠,添加一个image,可以观察到,不论image和两个Mask之间重不重叠,drawcall都为6,只增加了一个drawcall,说明Mask内外无法合批。
-
但是当把Image的Hierachy层级降低(在2个Mask下面),并将Imgae放在其中一个Mask下,可以观察到drallcall变成了8个,这是因为Image破坏了一个Mask的depth,导致两个Mask无法合批。
-
- 计算Depth的时候,当遍历到一个Mask的首,把它当作一个不可合批的UI节点看待,但注意可以作为其他孩子UI节点的bottomUI。
RectMask2D
RectMask2D是一个类似于Mask控件的遮罩控件,遮罩将子元素限制为父元素的矩形,与标准的遮罩控件不同,这种控件有一些限制,但也有许多性能优势。
RectMask2D不需要依赖一个Image组件,其裁剪区域就是它的RectTransform的rect大小,其性质如下:
- RectMask2D节点下的所有孩子都不能与外界UI节点合批且多个RectMask之间也不能合批。
- 计算depth的时候,所有RectMask2D都按一般UI节点看待,只是它没有CanvasRenderer组件,不能看作任何UI空间的bottomUI。
Mask和RectMask2D组件的区别是什么?
述RectMask2D的局限性包括:
- 仅在2d空间内有效
- 不能正确掩盖不共面的元素 RectMask2D的优势包括:
- 不适用模板缓冲区
- 高速性能
- 无需额外的绘制调用
- 无需更改材质