UI 优化

官方解释

Statistics 窗口官方解释

UI合批规则:https://blog.csdn.net/sinat_25415095/article/details/112388638

Unity四种合批技术详解:https://blog.csdn.net/ww1351646544/article/details/139678759

一、UI组成

  • UI组成:UGUI中的每个组件都是由3D网格,材质球,贴图组成(可以将其看成扁的3D物体),每创建一个组件,就会构建一个网格(从Canvas的CanvasRender组成),然后将材质球与这个网格绑定,所有操作都在Canvas中完成,如果需要在Canvas创建n个组件,那么我们就要准备n个材质球,准备n张图片,调用n个drawCall,显然不现实,所有我们需要进行合批的操作。

二、UI合批

2.1 定义

合批也叫Batch,Unity为了减少渲染调用次数,提高性能,会将相同渲染特性的UI元素合并成一个大网格进行渲染(DrawCall)。而将UI元素的网格合并就叫UI合批。

2.2 合批规则

UI合批的基本规则是两个控件使用的材质球(Shader)和贴图要完全相同,UGUI中Canvas是可以嵌套子Canvas,但是合批是以Canvas(不包含子Canvas)为单位的(子Canavs则会是另一个批次)。

合批步骤:

  1. 找Canvas集合:将所有Canvas找出来,然后剔除不必渲染的Canvas(透明度为0,长宽为0,在RectMask2D下且在RectMask2D的区域外)
  2. 计算UI深度值Depth:
    1. 从Hierarchy中从上往下的顺序依次遍历Canvas下所有UI元素。
    2. 如果当前UI不渲染,Depth = -1
    3. 如果当前UI要渲染,但当前UI下没有其他UI元素与其相交,则Depth = 0
    4. 如果当前UI要渲染,当前UI下由其他UI元素(LowerUI)与其相交,如果当前UI和LowerUI可以合批(材质和贴图完全相同),则当前UI.Depth = LowerUI.Depth, 如果不能合批的话,当前UI.Depth = LowerUI.Depth + 1;
    5. 如果当前UI要渲染,下面有n个元素与其相交,按步骤算出n个Depth,然后取n个Depth最大值,即当前UI.Depth = max (Depth1, Depth2, Depth3)

UI下面:只Hierechy窗口UI下的元素, 相交:两个UI元素的网格有相交(非Rect有相交)

  1. 各个UI的Depth计算完毕后,依次按照Depth、material ID、texture ID、RendererOrder(即UI层级队列顺序,即Hierarchy面板上的顺序)排序(条件的优先级依次递减,且均为从小到大排序)。然后剔除Depth = -1的UI元素,得到Batch前的UI 元素队列,这个队列被称之为VisiableList
  2. 判断VisableList中相邻的元素是否能够合批(相同材质和贴图,不需要考虑Depth是否相同),然后一个批次一个批次的合并网格,提交给GPU进行渲染。

2.3 UI重构

合批是将同一个Canvas下多个UI的网格合并在一起,如果其中任何一个元素的材质,网格顶点,位置(Transform)甚至颜色或者在该Canvas下动态创建或删除UI元素都会导致该Canvas重新计算合批(仅一个Canvas,子Canvas或者父Canvas不会重新计算),重新生成网格,这个重新计算生成网格的过程被称为UI重构(Rebuild)。

具体触发重构可以参考UGUI源码

三、优化方案

UI优化是提升游戏或者应用性能的重要方案,UGUI的优化集中在减少DrawCall、优化内存使用、提升渲染效率等,常用的UGUI方案有UI动静分离、拆分UI、预加载UI、图集拼接优化、网格重构优化等。

  • UI动静分离:又称为动静合批,“动”指的是元素移动、放大、缩小的UI重构概率比较高的UI元素,而“静”表示界面上不会移动、旋转、缩放等UI重构基本上没有的UI元素,通过设置静态Canvas和动态Canvas,可以大幅度减少Draw Call的数量。
  • 拆分UI:当界面元素过多时,在实例化和初始化时,消耗的CPU会比较大,所有可以将界面需要二次显示的内容进行拆分,使打开界面的时候可以加快。
  • 预加载UI:UI实例化到场景的过程:网格合并,组件初始化,渲染初始化,图片加载,界面逻辑调用等,需要消耗大量CPU,可以通过预加载将资源加载到内存、UI实例化和UI初始化的CPU消耗放到Loading等待时间线上,如登录过程,场景切换的时间等都可以提前加载资源。
  • 打包图集:又称纹理图集打包或精灵图集打包,是一种将多个小纹理合并成一个大纹理的优化技术,UI元素用同一个纹理就可以减少批次的调用次数。
  • Scroll View优化:Scroll组件需要频繁移动,导致每帧都要重构,如果界面上有大量元素,则非常消耗性能,所有可以通过循环利用优化,只实例化需要显示的实例数量,数据达到共享,达到减少CPU浪费。
  • 对象池技术:在频繁创建和销毁UI对象使,使用对象池来重复利用已创建的UI对象,减少内存分配和垃圾回收开销