湖北网站建设专家,百度账号登陆入口,山东嘉祥做网站的有哪几家,seo网站建设是什么意思UGUI合批 UGUI合批规则概述UGUI性能查看工具合批部分的特殊例子一个白色image、蓝色image覆盖了Text#xff0c;白色image和Text哪个先渲染 Mask合批Mask为什么会产生两个drawcallMask为什么不能合批Mask注意要点 RectMask2D为什么RecMask2D比Mask性能更好主要代码RectMask2D注… UGUI合批 UGUI合批规则概述UGUI性能查看工具合批部分的特殊例子一个白色image、蓝色image覆盖了Text白色image和Text哪个先渲染 Mask合批Mask为什么会产生两个drawcallMask为什么不能合批Mask注意要点 RectMask2D为什么RecMask2D比Mask性能更好主要代码RectMask2D注意要点 根据应用场景选择使用哪个Mask、RectMask2D)只需要一个遮罩需要多个遮罩遮罩下有多个子物体 UGUI合批规则概述 遍历所有UI元素 根据深度Depth(优先级最高-1表示不用渲染)、材质ID、图片ID、渲染顺序对所有UI进行排序 进行合批处理比如UI1和UI2两者必须是紧挨着的是相同材质、相同图片就可以进行合批如果UI1和UI2之间有一个中间层UI3根UI1和UI2材质不同就会打断合批
Text必须文字的网格覆盖到image上面才算相交Rect Transform框框相交不算白色image的深度为0最先渲染然后判断Text是否相交再判断材质ID和图片ID是否相同如果相同则可以合批因为不相同所以Text深度为白色image1为1如果Text底下有很多image则取最大的深度1红色image因为底下有Text和白色image所以计算出两个深度值分别1和0取最大值加1就是2黄色和蓝色image会进行合批测试操作深度值都是2这里只是测试是否能合批并还没有真正合批最后会得到一个排序数组list并把所有深度为-1的值剔除掉0、1、2、2、2传给合批部分的程序进行合批操作判断相邻的元素是否能进行合批通过判断数组的值是否相等
UGUI性能查看工具 合批部分的特殊例子
一个白色image、蓝色image覆盖了Text白色image和Text哪个先渲染 根据分析工具可以看到白色image先渲染文本后渲染白色图片ID小一点这样得到的数组list会先是白色image、Text、蓝色image导致白色和蓝色无法合批解决办法是把白色image和蓝色image赋值同一个texture 只要是满足合批条件合批数组紧挨着虽然没有覆盖也可以合批能不能合批在最后合批数组上才能决定
Mask合批 mask无法跟mask外的物体进行合批但是mask之间可以合批 mask本身会产生两个drawcall性能损耗
Mask为什么会产生两个drawcall
第一个drawcall是mask在设置模板缓存产生的第二个drawcall是mask在还原模板产生的mask之间可以进行合批设置模板缓存和还原模板时候因为图片ID和材质是一样的所以可以合批设置模板缓存时候会把需要显示部分的缓存值设置为1遮罩的部分设置为0在渲染的时候会取出我存在当前像素当中的一个模板缓存值然后判断它呢是否为一。如果为一的话才进行渲染如果不为一就不不渲染了每一个像素点上创建了一个这样类似于一个数据缓存通过它的模板缓存值来判断是否显示都是像素级别的单位模板还原也要产生一次drawcall把每个像素点的模板缓存清除
Mask为什么不能合批
因为Mask会产生一个特殊的材质材质不同就不能合批 public virtual Material GetModifiedMaterial(Material baseMaterial){if (!MaskEnabled())return baseMaterial;var rootSortCanvas MaskUtilities.FindRootSortOverrideCanvas(transform);var stencilDepth MaskUtilities.GetStencilDepth(transform, rootSortCanvas);if (stencilDepth 8){Debug.LogWarning(Attempting to use a stencil mask with depth 8, gameObject);return baseMaterial;}int desiredStencilBit 1 stencilDepth;// if we are at the first level...// we want to destroy what is thereif (desiredStencilBit 1){// StencilMaterial.Add是最主要的方法这里添加了特殊的材质因为材质不同所以不能和mask外的物体合批var maskMaterial StencilMaterial.Add(baseMaterial, 1, StencilOp.Replace, CompareFunction.Always, m_ShowMaskGraphic ? ColorWriteMask.All : 0);StencilMaterial.Remove(m_MaskMaterial);m_MaskMaterial maskMaterial;var unmaskMaterial StencilMaterial.Add(baseMaterial, 1, StencilOp.Zero, CompareFunction.Always, 0);StencilMaterial.Remove(m_UnmaskMaterial);m_UnmaskMaterial unmaskMaterial;graphic.canvasRenderer.popMaterialCount 1;graphic.canvasRenderer.SetPopMaterial(m_UnmaskMaterial, 0);return m_MaskMaterial;}//otherwise we need to be a bit smarter and set some read / write masksvar maskMaterial2 StencilMaterial.Add(baseMaterial, desiredStencilBit | (desiredStencilBit - 1), StencilOp.Replace, CompareFunction.Equal, m_ShowMaskGraphic ? ColorWriteMask.All : 0, desiredStencilBit - 1, desiredStencilBit | (desiredStencilBit - 1));StencilMaterial.Remove(m_MaskMaterial);m_MaskMaterial maskMaterial2;graphic.canvasRenderer.hasPopInstruction true;var unmaskMaterial2 StencilMaterial.Add(baseMaterial, desiredStencilBit - 1, StencilOp.Replace, CompareFunction.Equal, 0, desiredStencilBit - 1, desiredStencilBit | (desiredStencilBit - 1));StencilMaterial.Remove(m_UnmaskMaterial);m_UnmaskMaterial unmaskMaterial2;graphic.canvasRenderer.popMaterialCount 1;graphic.canvasRenderer.SetPopMaterial(m_UnmaskMaterial, 0);return m_MaskMaterial;}Mask注意要点
Mask剔除的部分还是会影响深度计算的从而影响合批增加drawcall次数Mask剔除的部分还是会drawcall只不过mask把绘制的像素剔除了Mask下的子物体可以正常进行合批mask之间只要满足合批条件那么他们之间的元素也是能够进行合批的
RectMask2D
RectMask2D本身不占用drawcall因为实际的具体逻辑是在canvas render里进行的涉及到渲染具体的操作都是内部用c类做的性能更好这里通过性能分析渲染的面和点判断遮盖的部分是否被渲染出来
为什么RecMask2D比Mask性能更好
RectMask2D本身不占用drawcallMask本身有两次drawcallRectMask2D对于被遮罩的部分并不会绘制Mask是把遮罩的部分剔除了
主要代码
public virtual void PerformClipping()
{if (ReferenceEquals(Canvas, null)){return;}//TODO See if an IsActive() test would work well here or whether it might cause unexpected side effects (re case 776771)// if the parents are changed// or something similar we// do a recalculate hereif (m_ShouldRecalculateClipRects){MaskUtilities.GetRectMasksForClip(this, m_Clippers);m_ShouldRecalculateClipRects false;}// get the compound rects from// the clippers that are validbool validRect true;// 获取需要剪切的区域Rect clipRect Clipping.FindCullAndClipWorldRect(m_Clippers, out validRect);// If the mask is in ScreenSpaceOverlay/Camera render mode, its content is only rendered when its rect// overlaps that of the root canvas.RenderMode renderMode Canvas.rootCanvas.renderMode;bool maskIsCulled (renderMode RenderMode.ScreenSpaceCamera || renderMode RenderMode.ScreenSpaceOverlay) !clipRect.Overlaps(rootCanvasRect, true);if (maskIsCulled){// Children are only displayed when inside the mask. If the mask is culled, then the children// inside the mask are also culled. In that situation, we pass an invalid rect to allow callees// to avoid some processing.clipRect Rect.zero;validRect false;}if (clipRect ! m_LastClipRectCanvasSpace){foreach (IClippable clipTarget in m_ClipTargets){//设置剪切效果clipTarget.SetClipRect(clipRect, validRect);}foreach (MaskableGraphic maskableTarget in m_MaskableTargets){maskableTarget.SetClipRect(clipRect, validRect);maskableTarget.Cull(clipRect, validRect);}}else if (m_ForceClip){foreach (IClippable clipTarget in m_ClipTargets){clipTarget.SetClipRect(clipRect, validRect);}foreach (MaskableGraphic maskableTarget in m_MaskableTargets){maskableTarget.SetClipRect(clipRect, validRect);if (maskableTarget.canvasRenderer.hasMoved)maskableTarget.Cull(clipRect, validRect);}}else{foreach (MaskableGraphic maskableTarget in m_MaskableTargets){//Case 1170399 - hasMoved is not a valid check when animating on pivot of the objectmaskableTarget.Cull(clipRect, validRect);}}m_LastClipRectCanvasSpace clipRect;m_ForceClip false;UpdateClipSoftness();
}RectMask2D注意要点
遮罩的部分因为没有绘制所以不影响深度计算不影响合批会打断合批一个RectMask2D下的子物体不可以跟另一个RectMask2D下的子物体进行合批但RectMask2D下的子物体可以进行合批RectMask2D组件的Image之间可以进行合批
根据应用场景选择使用哪个Mask、RectMask2D)
只需要一个遮罩
选择用RectMask2D性能更好
需要多个遮罩遮罩下有多个子物体
选择用Mask可以对不同Mask之间的子物体进行合批这种情况就会比RectMask2D性能更好