UGUI合批分析和优化方法整理

资料

Unity3D UGUI系列之合批_unity ui合批-CSDN博客

Unity 3D - Mask和RectMask2D区别-CSDN博客

Unity UI性能优化技巧

分析工具

Frame Debugger
查看每个批次渲染情况
Profiler-UI
可看到每帧批次和draw call

UI合批机制和原理

合批流程

描述:将一些元素合并起来,一次渲染绘制多个图形。这将大大降低draw call
基础条件:图形相邻,并且材质,图片完全相同。UGUI会根据材质,图片,层级顺序,遮罩情况等排序,之后将可合批的内容合批。将多个图片打成图集可视为一张图,从而合批。
完整流程:
1.合批以 Canvas为单位,子canvas会视为另一个合批过程。不渲染的canvas会被剔除:透明度为0,长宽为0,在RectMask2D控件下且在RectMask2D的区域外
2.计算depth。depth描述了遮挡关系,如果两个相同图片中间夹了另一张图,他们是不能合批的。
3.各个UI的Depth计算完毕后,依次按照Depth、material ID、texture ID、RendererOrder(即UI层级队列顺序,即Hierarchy面板上的顺序)排序(条件的优先级依次递减,且均为从小到大排序)。然后剔除Depth = -1的UI元素,得到Batch前的UI 元素队列,这个队列被称之为VisiableList。
4.依次检查VisiableList的相邻元素,如果能合批就合批。

  • 注意:如果其中任何一个元素的材质、网格顶点、位置(Transform)甚至颜色或者在该Canvas下动态创建或删除UI元素都将导致该Canvas重新计算合批。可通过动静分离隔离动态与静态元素。
  • 注意:排序按照texture ID,因此有时会导致图片交换,打断合批。
  • 注意:文本的不同字体视为不同的图,使用不同字体会打断合批。

depth计算规则:

按照Hierarchy中从上往下的顺序依次遍历Canvas下所有UI元素
对于当前的UI元素CurrentUI
i.如果CurrentUI不渲染,则Depth = -1
ii.如果CurrentUI要渲染,但CurrentUI下面没有其他UI元素与其相交,则Depth = 0
iii.如果CurrentUI要渲染,下面只有一个UI元素(LowerUI)与其相交,且CurrentUI与LowerUI可以合批(材质和贴图完全相同),则CurrentUI.Depth = LowerUI.Depth;如果两者不能合批,CurrentUI.Depth= LowerUI.Depth + 1
iv.如果CurrentUI要渲染,下面有n个元素与其相交,则按照步骤iii,分别计算出n个Depth(Depth_1、Depth_2、Depth_3...),然后CurrentUI.Depth取其最大值,即CurrentUI.Depth = max(Depth_1, Depth_2, Depth_3,...)
上面步骤中的"下面"和"相交"要明确下意思,这两个概念很重要。
CurrentUI下面的UI,指Hierarchy面板中,在CurrentUI之上的元素。
两个UI元素相交,是指这两个元素的网格有相交(有重叠部分),一定要注意不是两个元素的Rect区域相交。

  • 注意:源码中16个元素打组合并计算包围盒

遮罩对合批的影响

两种遮罩:mask和rectmask2D

|--------|-----------------------------------------|----------------|
| | mask | rectmask2D |
| 原理 | 模板测试 | 矩形裁剪 |
| 功能 | 可实现不规则遮罩,支持3D | 仅能实现矩形遮罩,不支持3D |
| 依赖组件 | 需要Image | 无 |
| 增加的批次 | 增加两个批次,用于写入和清空模板缓存,即增加两个材质。如果嵌套,每层加两个批次 | 不增加批次 |
| 对批次的影响 | 外部元素不能和内部元素合批,内部元素可合批 ||
| 对批次的影响 | 相邻mask内元素也不能合批 | 相邻mask内元素可以合批 |
| 性能 | 性能更差 | 性能更优 |

案例测试

一下为一些基本请求的测试,参考层级结构和结果看看实际合批情况,和上文都符合了。

可行的优化方法

  • 使用图集,尽量满足合批原理,减少材质贴图种类。
  • 像道具图标这种用不了时,可考虑动态图集
  • 不同UI字体不可合批,可考虑使用图片替代字体
  • 避免频繁修改ui结构,这个流程最常见的就是动画控制。位置,大小,透明度,颜色都会导致重新合批。
  • 避免同一个canvasUI元素过多
  • 使用canvas隔离合批
  • 优先使用rectmask2D,减少使用mask
  • 控制canvas的透明度,而不是图形的颜色
  • 禁用画布组件来取代隐藏根物体节点(存疑,因为禁用后可减少子物体update)
相关推荐
nnsix5 分钟前
Unity Physics.Raycast的 QueryTriggerInteraction枚举作用
unity·游戏引擎
地狱为王14 分钟前
Cesium for Unity叠加行政区划线
unity·gis·cesium
小贺儿开发9 小时前
Unity3D 八大菜系连连看
游戏·unity·互动·传统文化
在路上看风景9 小时前
25. 屏幕像素和纹理像素不匹配
unity
ۓ明哲ڪ11 小时前
Unity功能——创建新脚本时自动添加自定义头注释
unity·游戏引擎
熬夜敲代码的小N11 小时前
Unity大场景卡顿“急救包”:从诊断到落地的全栈优化方案
java·unity·游戏引擎
派葛穆12 小时前
Unity-realvirtual-S7通讯快速配置(未完结)
unity·游戏引擎
w-白兰地1 天前
【Addressable远端加载资源】
unity·addressable·资源加载
小张不爱写代码1 天前
[Unity 技巧] 如何自定义 Inspector 变量显示名称 (CustomLabel)
unity·游戏引擎
Sator11 天前
Unity开发中常用的随机方法扩展
unity