Unity 3D - Mask和RectMask2D区别

时间:2024-04-14 14:44:33

Unity 3D - Mask和RectMask2D区别 :

主要区别:

  • 区别1:
    Mask主要处理不规则图形遮罩效果
    RectMask2D只能做矩形遮罩.

    Unity 3D - Mask和RectMask2D区别Unity 3D - Mask和RectMask2D区别

  • 区别2:
    Mask需要一个Image来当作遮罩区域,子节点在Image[渲染区域]才会显示
    RectMask2D以自身RectTransform为裁剪区域,子节点在[RectTransform区域]内显示

从效果上看 Mask+无图Image是可以替代RectMask2D , 但是为什么还存在RectMask2D呢?

先看下官方文档给出的说明
Unity 3D - Mask和RectMask2D区别

最重要的是最后一条[性能优势]

新建一个场景,默认drawcall(batches)数是2(天空盒1个drawcall, Camera1个drawcall).
Unity 3D - Mask和RectMask2D区别
现在添加一个Mask(Mask对象上有一个Image组件,子节点也是一个Image)
Unity 3D - Mask和RectMask2D区别Unity 3D - Mask和RectMask2D区别
drawcall从2上升到5, 一个Mask导致增加了3个drawcall.
Unity 3D - Mask和RectMask2D区别

通过Frame Debug工具查到drawcall来源
Mask导致2个drawcall(第1个和第3个,一头一尾),Mask下的子节点Image导致1个drawcall(中间的)

Unity 3D - Mask和RectMask2D区别

再看下RectMask2D的情况(隐藏Mask, 显示RectMask2D)
Unity 3D - Mask和RectMask2D区别

drawcall为3, 只有新增1个drawcall.
Unity 3D - Mask和RectMask2D区别
从Frame Debug可以看出就是子节点Image导致的1个drawcall, 而RectMask2D不会导致drawcall.
Unity 3D - Mask和RectMask2D区别

结论 :

  • 到这里可以暂时得出结论,如果只用固定矩形遮罩,不需要特殊形状遮罩的情况下,可以优先使用RectMask2D.
    (例如常见于scrollview的情况下,创建scrollview默认是Mask,可以选择手动替换成RectMask2D,大多数情况都适用,会有些许性能提升)

进阶内容 :

把Mask复制一个出来Mask(1), 然后把位置摆开, 让2个Mask别重叠(后面会解释为什么不重叠).
Unity 3D - Mask和RectMask2D区别
摆成这个样子(不重叠就行)
Unity 3D - Mask和RectMask2D区别

然后再看一下drawcall情况, 还是5个drawcall, 没有变化.
Unity把2个Mask进行了网格合并, 3个drawcall, 分别为[2个Mask头]、[2个Image]、[2个Mask尾].

  • 这里可以看出, Mask之间是可以进行合并的, 从而不额外增加drawcall
    Unity 3D - Mask和RectMask2D区别

刚才强调不要重叠,现在看下如果重叠的话会出现什么情况
现在把2个Mask摆成下图这样.
Unity 3D - Mask和RectMask2D区别
然后会发现drawcall飙升至8.
Unity 3D - Mask和RectMask2D区别
这是因为Unity的合批需要同渲染层级(depth), 同材质, 同图集, 如果重叠了, depth就不同了, 6个drawcall分别为Mask头Mask的ImageMask尾Mask(1)头Mask(1)的ImageMask(1)尾.

把2个Mask位置还原, 然后在Mask外创建一个Image, 看看Mask和外部的合并情况.
Unity 3D - Mask和RectMask2D区别

drawcall为6, 增加了1个drawcall, 说明Mask内外无法合批
Unity 3D - Mask和RectMask2D区别
然后把外部Image的Hierarchy的层级降低(2个Mask下面)
Unity 3D - Mask和RectMask2D区别
然后把Image放到Mask下
Unity 3D - Mask和RectMask2D区别
然后drawcall变成了9, 因为破坏了一个Mask的depth, 导致2个Mask无法合批, 这也再次验证了, Unity的合批需要depth相同.
Unity 3D - Mask和RectMask2D区别
最后看一下这种情况下的drawcall顺序
7个drawcall从上到下分别为Mask(1)的头蓝色ImageMask的头Mask(1)的ImageMask(1)尾Mask的ImageMask的尾.
Unity 3D - Mask和RectMask2D区别
Mask还有其他情况这里就不多做测试了

Mask小结:

1.多个Mask之间可以进行合批(头和头合批, 子对象和子对象合批, 尾和尾合批),需要同渲染层级(depth), 同材质, 同图集.
2.Mask内外不能进行合批.


再试试RectMask2D
把RectMask2D复制一个出来RectMask2D(1), 然后把位置摆开.
Unity 3D - Mask和RectMask2D区别

然后看drawcall为4, 因为RectMask2D本身不会导致drawcall, 所以RectMask2D之间不能进行合批.
Unity 3D - Mask和RectMask2D区别

RectMask2D小结:

1.RectMask2D本身不产生drawcall.
2.不同RectMask2D的子对象不能合批.

总结 :

如果界面只需要一个遮罩, 推荐使用RectMask2D, 如果界面需要多个遮罩, 根据情况分析, 看多个遮罩之间能否合批, 如果可以则可以考虑使用Mask.


小提示 :
根据UGUI源码, 嵌套Mask不能超过9层, 超过部分会使用默认材质, 超出部分遮罩失效.
Unity 3D - Mask和RectMask2D区别

Unity 3D - Mask和RectMask2D区别