Unity UI性能的四类问题
- Canvas Re-batch时间过长
- Canvas Over-dirty,Re-batch次数过多
- 生成网格顶点时间过长
- Fill-rate overutilization (UIshader中GPU片元着色器的利用率过高)
Canvas画布
- Canvas负责管理UGUI元素,负责UI渲染网格的生成与更新,并向GPU发送DrawCall指令
- 这些工作全是在引擎native层,由C++负责完成的。
- 对于每个Canvas对象,在绘制之前,都要进行一个合批的过程。
- 如果Canvas底下的所有UI元素,每一帧都保持不变,那么只需在绘制前合批一次,并保存下结果,并在之后的每帧渲染中继续使用这个保存的结果;如果UI元素发生了变化,这时画布需要重新匹配几何体,而画布被标记成dirty,这时被标记成dirty的Canvas会触发Re-batch,也就是重新需要合批
- Canvas Re-batch(合批)的过程
- 1.根据UI元素深度关系进行排序
- 2.检查UI元素的覆盖关系
- 3.检查UI元素材质并进行合批
UGUI渲染细节
Re-Build过程
- Re-Build是Re-batch过程中完成的,主要逻辑在C#层,用来重新计算Layout布局与渲染网格重建,每当Canvas组件调用WillRenderCanvases事件时,都会调用CanvasUpdateRegistry中的PerformUpdate方法,这个方法主要完成三个工作
- 通过ICCanvasElement.Rebuild方法重新构建Dirty的Layout组件
- 通过ClippingRegistry.Cullf方法,对任何已注册的裁剪组件Clipping Components的对象进行裁剪剔除操作,如已注册了Mask的UI元素
- 任何Dirty的Graphics Components都会被要求重新生成图形元素
- Layout组件和Graphics组件什么时候被标记成dirty:
- Layout Rebuild
- UI元素位置、大小、颜色发生变化时
- 优先计算靠近Root节点,并根据层级深度排序的transform操作时
会被标记成dirty并触发Layout Rebuild过程
- Graphic Rebuild
- 顶点数据被标记成Dirty时
- 材质或贴图数据被标记成Dirty时
会触发Rebuild过程
- Layout Rebuild
UGUI性能优化
- 使用Canvas的基本准则:
- 默认情况下,UGUI是通过Canvas的Graphic Raycaster组件来处理输入、触摸以及鼠标悬停事件。每个Canvas都会绑定一个Graphic Raycaster组件,并每帧检测鼠标鼠标的位置。Unity5.4之后,对于没有鼠标的设备不会进行每帧检测。如果不需要交互的Canvas对象可以禁用Graphic Raycaster组件