UGUI DrawCall合批细节(二)——Mask影响合批
在UGUI的开发中我们常谈少用Mask,但是为什么少用,用了Mask又会影响什么呢,今天我们就来简单说说。
(一)被mask的元素为什么不能和外部元素合批
首先我们先来聊聊mask的实现,我们简单搭建一个测试场景
会发现多了一个mask会多出3个drawCall,我们查看Mask的源码
他在StencilMaterial.Add的时候为这个maskUI增加了一个新的材质,导致了mask内的物体无法和外部同样材质的物体合批,这是其一,其二是mask会进行两次pass,第一步是对在模板缓冲中的值进行赋值,将要显示的部分缓存值设置为1,不显示的部分设置为0,在第二个pass绘制时对模板缓冲值为0的部分进行剔除,所以这两个pass也会带来两个drawcall的生成。所以添加一个mask最起码会增加3个drawcall。并且了解原理我们会发现,其实虽然是不显示但是被mask剔除的部分还是存在的,只是不会进行绘制而已,这也会影响到我们后面会说的,层叠下异常增长的drawcall,这个我们后面来详解。
(二) 不同mask之间的合批
不同的mask之间是可以合批的,在我们上一章《UGUI DrawCall合批细节(一)》中讲解过,相同材质和贴图的两个UI物件是能够进行合批的,虽然Mask会对原来的材质进行替换,添加一个新的材质,但是新添加的材质和新添加的材质之间就支持合批,所以我们现在简单添加两个mask查看drawCall效果:
一个Mask的情况下:
两个Mask的情况下:
我们会发现drawCall数量并没有增加,证明了我们的推论是正确的,但是这里有一个例外情况,也是我们接下来要论述的第三点也是最容易被人忽略的点。
(三)被mask的物体只是不被绘制,依旧会影响合批计算
我们先看我现在mask的物体被剔除的部分:
可以发现在下部分的红色方块被剔除了,那用第二节的理论验证了mask之间会进行合批的,但是是绝对的吗,并不是,我们看一个情况。
同样的物体我们把他移动到上一个mask的最底部我们发现合批并没有出现,而是又增长了3个drawCall,这是为什么?
细节就在这里被遮罩剔除的区域,实际上也是会参与合批计算的,当这两个mask不重叠的时候,他们depth相同,mat相同,可以进行合批,但是当他们重叠时,因为被剔除的部分参与了运算,发现depth不同并且mat也不同,就无法进行合批,会增加3个Drawcall,这就是很多时候项目里明明没重叠但是却多了很多drawCall的情况。
那mask的分析基本到这里,下节我们聊聊RectMask2D和Mask的区别以及如何选择,本来想合并一起发的,结果字数过长了,我们下节见~