UGUI DrawCall合批细节(三)——RectMask2D与Mask的区别及选择
RectMask2D
那我们同比分析一下UI上常用的第二个Mask组件RectMask2D,等同于Mask的测试场景,我们测试单个mask2D开启和关闭对drawCall的影响。
开启前:
开启后:
我们可以发现DrawCall只增加了一个,因为内部的元素无法和外部进行合批增加了一个drawCall,并且内部的元素自己能够进行合批。而且和Mask不同的是,mask2D并不会产生两额外的pass增加两个drawcall的消耗。这是为什么呢?
查看rectMask2D的源码我们可以发现,他并没有替换材质的过程,没有用到模板缓冲的实现方式,而是通过了canvasRender里面进行了ClipRect的剔除,这样相比于Mask会带来以下不同:
(一)RectMask2D之间无法进行合批
我们复制一份mask2D对象可以发现,drawCall增加了1
查看差异的理由可以发现是因为不同的裁剪区域,所以我们能知道,RectMask2D之间内部的元素是无法进行合批的,这也是和Mask不同的部分
(二)被mask隐藏的物体不会参与合批计算
相比于mask不同,我们这里添加了RectMsk2D,虽然进行了重叠但是我们发现draw并没有增加,并且做一个测试,将同一个mask下的材质换成不同的贴图后,将一个mask移出区域,
会发现根本不会计算移除出区域的图片的drawCall,所以这是和Mask的第二个区别。
(三)RectMask2DUI组件上挂载的Image可以参与外部的合批
我们做一个简单的测试:
可以发现在添加和移除Image组件时,drawcall的数量没有增加,因为新添加的img和外部的黄色方块的材质一致,进行了合批。而Mask组件没有Image组件的话都无法生效,这是和mask的第三个区别。
总结:
所以到底我们项目是使用Mask还是使用RectMask2D呢?在我看来这是应用场景的选择问题,当界面只有一个mask需要使用的时候,RectMask2D无疑是最优解,只会带来一个drawCall的增加,如果是多个Mask并且互相是可以合批的,那无疑Mask更适合在那种情景下使用,但是使用的时候也需要注意被剔除区域的层叠问题。那这节对mask和RectMask2D的分析到这里就结束了,下节聊聊实际项目的避坑指南篇。