FairyBatching
简述
FairyGUI内部对渲染过程进行了优化,以减少Draw Call。参见文档。一言以蔽之:将能合批的控件(相同材质、图集)调整到连续的渲染顺序(meshRenderer.sortingOrder
)。
原理
- 关于Dynamic Batching:是Unity自带的功能,文档在此。对于连续渲染的物体,如果材质、图集相同,并且没有超过最大顶点数量,那么就会自动把他们合并在一起提交渲染。
- 连续渲染顺序:FGUI里面使用的对象是树形结构,不同父节点下的子节点的渲染层级必然是不同的。为了契合Dynamic Batching的工作,FGUI内部会对节点的渲染顺序进行调整。这里的调整并不会改变已有的控件层级关系,而是在渲染时另外保存一份数组
Container._descendants
,这个数组里就是所有要调整渲染顺序的控件显示对象,遍历数组,设置递增的meshRenderer.sortingOrder
即可设置为连续的渲染顺序(这个顺序也是Unity自带的功能)。 - 关于所谓的不重叠:阅读Unity Dynamic Batching的官方文档,可以发现并没有说到需要不重叠的问题。是因为这个不重叠,是在调整渲染顺序时考虑的,而不是Unity内部渲染时考虑的。举个例子: 有两个按钮,分别有一个文本和图标背景,按照FGUI里的树形渲染顺序,正常来说应该是:这个顺序一会儿是文本一会儿是图标,自然无法合批,按照Fairy Batching的原理,我们可以把渲染顺序调整为:
1
icon1, text1, icon2, text2
这样一来,两个图标背景和两个文本标题分别都可以合并为一个批次。Unity会先绘制两个合并后的图标背景,两个合并后的文本。但是这样就一定没问题吗?设想一下,如果两个按钮有一些重叠,icon2把text1盖住了一点点,视觉上正确的表现应该是icon2在text1之上。但是按照上面的渲染顺序,text1是在icon2之后渲染,结果是text1盖住了icon2,于是视觉表现就不正确了!1
icon1, icon2, text1, text2
根据上面这个例子,可以得知,所谓不重叠是在合批之前所做的判断工作,Unity的Dynamic Batching并不知道这件事,不管有没有重叠都会合批。为了防止出现渲染层级的错误,对于促进合批的手段(FairyBatching就是一种)都需要考虑到控件交叉重叠问题,防止合批过头。 4. 快速判断两个矩形(用min-max两个端点描述)是否重叠:先看X轴上的两条线段,分别有两个端点xMin1
, xMax1
, xMin2
, xMax2
。我们假设这两条线段相交,那么相交部分的线段就是xMin = max(xMin1, xMin2)
, xMax = min(xMax1, xMax2)
。如果 xMin <= xMax
成立,也就说明相交的线段存在(边缘重叠也算吧)。同理可以比较Y轴上的。对于两个矩形,我们就也可以同时比较X轴和Y轴上的线段,如果都相交,那么就说明这两个矩形存在交点。
相关文章