Unity 3D - Mask和RectMask2D区别 :
主要区别:
-
区别1:
Mask主要处理不规则图形遮罩效果
RectMask2D只能做矩形遮罩. -
区别2:
Mask需要一个Image来当作遮罩区域,子节点在Image[渲染区域]才会显示
RectMask2D以自身RectTransform为裁剪区域,子节点在[RectTransform区域]内显示
从效果上看 Mask+无图Image是可以替代RectMask2D , 但是为什么还存在RectMask2D呢?
先看下官方文档给出的说明
最重要的是最后一条[性能优势]
新建一个场景,默认drawcall(batches)数是2(天空盒1个drawcall, Camera1个drawcall).
现在添加一个Mask(Mask对象上有一个Image组件,子节点也是一个Image)
drawcall从2上升到5, 一个Mask导致增加了3个drawcall.
通过Frame Debug工具查到drawcall来源
Mask导致2个drawcall(第1个和第3个,一头一尾),Mask下的子节点Image导致1个drawcall(中间的)
再看下RectMask2D的情况(隐藏Mask, 显示RectMask2D)
drawcall为3, 只有新增1个drawcall.
从Frame Debug可以看出就是子节点Image导致的1个drawcall, 而RectMask2D不会导致drawcall.
结论 :
-
到这里可以暂时得出结论,如果只用固定矩形遮罩,不需要特殊形状遮罩的情况下,可以优先使用RectMask2D.
(例如常见于scrollview的情况下,创建scrollview默认是Mask,可以选择手动替换成RectMask2D,大多数情况都适用,会有些许性能提升)
进阶内容 :
把Mask复制一个出来Mask(1), 然后把位置摆开, 让2个Mask别重叠(后面会解释为什么不重叠).
摆成这个样子(不重叠就行)
然后再看一下drawcall情况, 还是5个drawcall, 没有变化.
Unity把2个Mask进行了网格合并, 3个drawcall, 分别为[2个Mask头]、[2个Image]、[2个Mask尾].
-
这里可以看出, Mask之间是可以进行合并的, 从而不额外增加drawcall
刚才强调不要重叠,现在看下如果重叠的话会出现什么情况
现在把2个Mask摆成下图这样.
然后会发现drawcall飙升至8.
这是因为Unity的合批需要同渲染层级(depth), 同材质, 同图集, 如果重叠了, depth就不同了, 6个drawcall分别为Mask头、Mask的Image、Mask尾、Mask(1)头、Mask(1)的Image、Mask(1)尾.
把2个Mask位置还原, 然后在Mask外创建一个Image, 看看Mask和外部的合并情况.
drawcall为6, 增加了1个drawcall, 说明Mask内外无法合批
然后把外部Image的Hierarchy的层级降低(2个Mask下面)
然后把Image放到Mask下
然后drawcall变成了9, 因为破坏了一个Mask的depth, 导致2个Mask无法合批, 这也再次验证了, Unity的合批需要depth相同.
最后看一下这种情况下的drawcall顺序
7个drawcall从上到下分别为Mask(1)的头、蓝色Image、Mask的头、Mask(1)的Image、Mask(1)尾、Mask的Image、Mask的尾.
Mask还有其他情况这里就不多做测试了
Mask小结:
1.多个Mask之间可以进行合批(头和头合批, 子对象和子对象合批, 尾和尾合批),需要同渲染层级(depth), 同材质, 同图集.
2.Mask内外不能进行合批.
再试试RectMask2D
把RectMask2D复制一个出来RectMask2D(1), 然后把位置摆开.
然后看drawcall为4, 因为RectMask2D本身不会导致drawcall, 所以RectMask2D之间不能进行合批.
RectMask2D小结:
1.RectMask2D本身不产生drawcall.
2.不同RectMask2D的子对象不能合批.
总结 :
如果界面只需要一个遮罩, 推荐使用RectMask2D, 如果界面需要多个遮罩, 根据情况分析, 看多个遮罩之间能否合批, 如果可以则可以考虑使用Mask.
小提示 :
根据UGUI源码, 嵌套Mask不能超过9层, 超过部分会使用默认材质, 超出部分遮罩失效.