Mask和Rect Mask 2D

目录

前言:

正文:

深度剖析: 

Mask就一定比Rect Mask 2D性能要好吗?

总结:


前言:

本人接触性能优化这一块的引子就是Mask,在之前的学习中了解到Mask会产生两个DrawCall??当时我也是第一次听到DrawCall这个词,至于什么是DrawCall,大家可以参阅下面这篇文章:DrawCall,Batches,SetPassCall_林万厦的博客-CSDN博客

本篇文章的内容是经过自己反复阅读源码和测试推敲出来的,如有解释不当的地方,望不吝赐教!

正文:

在过往的交流中身边总有人认为是Mask会产生两个DrawCall,Rect Mask 2D只占用一个,觉得用Rect Mask 2D一定能起到优化的作用,于是我看了源码,并亲自测试了一下。

下面是Mask为什么产生DrawCall的源码部分:

 可以看到在Mask实现最初添加了一个特殊材质(Material)来作为模板材质(StencilMaterial)而这就不符合我们的合批规则,Mask第一个DrawCall设置模板缓存的时候产生的,第二个是所有Mask下的物体逻辑执行完之后要还原模板缓存。(这里说的两个包括它所依附的Image对象的DrawCall)实际上Mask本身只会产生一次DrawCall,而Rect Mask 2D本身并不产生DrawCall。

 下图是一个Image添加了一个Mask组件,一共有3个Batch。相机,Image,Mask各占一个。

把Mask替换成Mask 2D后可以看到,减少了一个Batch

深度剖析: 

接下来就是重头戏了,我们先来剖析一下Rect Mask2D的源码:

 注意我加了注释的地方,在Mask2D组件获取到要裁剪的区域之后,遍历所要裁剪的子对象,调用了底层C++的SetClipRect方法,这里我猜测这个方法的作用是 告诉子对象哪些顶点不需要参与绘制,最终达到被裁减掉的部分像素和顶点不参与渲染的效果。我们可以根据猜想去测试一下:

首先创建一个空物体挂上Mask2D组件,在它的子节点下创建一个Image,注意顶点数(Verts)和面数(Tris)

 然后我们把Image移除Mask2D的范围,让它整个被裁剪掉:

 可以看到这个时候顶点数和面数的变化,也就证明了我们的猜想是正确的!

也就是说Mask2D与Mask最大的不同点就在于,Mask2D被裁剪掉的部分不会参与绘制,而使用Mask被裁剪掉的部分仍然参与绘制!这也就是为什么Mask会打断合批的原因。

Mask就一定比Rect Mask 2D性能要好吗?

        首先,多个Mask之间是可以进行合批的,而Mask 2D就不行,这是因为他们的实现原理不同,上文中有讲到Mask实现最初添加了一个特殊材质(baseMaterial)来作为模板材质,所以多个Mask用的也都是这个相同的材质,可以达到合批规则。单是这一点,我们在开发过程当中一个界面需要多个遮罩时,Mask的性能就要高于Mask 2D,再然后,不同Mask的子对象之间也可以进行合批的,而Mask2D就不行。上述是我用FrameDebug测试得出的结果,我这里不会制作gif,就不插图了,大家可以自行测试一下哈。

总结:

        使用Mask或是Mask2D要区分应用场景,首先Mask2D只能裁剪矩形,但是却能在单个界面只需要一个遮罩的时候起到优化作用,当单个界面需要多个遮罩时使用Mask更合理。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值