Unity 编辑器优化 – UGUI

Unity UI性能的四类问题

  1. Canvas Re-batch 时间过长
  2. Canvas Over-dirty, Re-batch次数过多
  3. 生成网格顶点时间过长
  4. Fill-rate overutilization

Canvas画布

Canvas负责管理UGUI元素,负责UI渲染网格的生成与更新,并向GPU发送DrawCall指令;

对于每个Canvas对象,在绘制前都要进行一个合批的过程,如果Canvas中所有UI元素每帧都保持不变,那么只需要在绘制前合批一次,并保存下结果,并在之后的每帧渲染中继续使用这个保存的结果;如果UI元素发生了变化,这时候画布元素需要重新匹配几何体,画布会表记为dirty,这时候被标记为dirty的Canvas会触发Re-batch,也就是重新需要进行合批;

Canvas Re-batch过程

  1. 根据UI元素深度关系进行排序
  2. 检查UI元素的覆盖关系
  3. 检查UI元素材质并进行合批

合批过程是在多线程上进行的,因此在移动平台上由于手机CPU的核数不同也会造成合批性能的差异;

UGUI渲染细节

  • UGUI中渲染是在Transparent半透明渲染队列中完成的,半透明队列的绘制顺序是从后往前画,由于UI元素做Alpha Blend操作,我们在做UI时很难保障每一个像素不被重画,UI的Overdraw太高,这会造成片元着色器利用率过高,造成GPU负担;
  • UI SpriteAtlas图集利用率不高的情况下,大量完全透明的像素被采样也会导致像素被重绘,造成片元着色器利用率过高;同时纹理采样器浪费了大量采样在无效的像素上,导致需要采样的图集像素不能尽快的被采样,造成纹理采样器的填充率过低,同样也会带来性能问题。

Re-Build过程

Re-build是Re-batch过程中完成的,用于重新计算布局与渲染网格重建;

每当Canvas组件调用WillRenderCanvases事件时都会调用PerformUpdate::CanvasUpdateRegistry接口,其工作为:

  1. 通过ICanvasElement.Rebuild方法重新构建Dirty的Layout组件;
  2. 通过ClippingRegistry.Cullf方法,任何已注册的裁剪组件Clipping Compnents(如Masks)的对象进行裁剪剔除操作;
  3. 任何Dirty的Graphics Compnents都会被要求重新生成图形元素;
  • Layout Rebuild
    • UI元素位置、大小、颜色发生变化时
    • 优先计算靠近Root节点,并根据层级深度排序的Transform操作时
  • Graphic Rebuild
    • 顶点数据被标记成Dirty时
    • 材质或贴图数据被标记成Dirty时

使用Canvas的基本准则

  • 将所有可能打断合批的UI图层移到最下边的图层,尽量避免UI元素出现重叠区域;
  • 可以拆分使用多个同级或嵌套的Canvas来减少Canvas的Rebatch复杂度;
  • 拆分动态和静态对象放到不同Canvas下;
  • 不使用Layout组件,减少Layout Rebuild;
  • Canvas的RenderMode尽量Overlay模式,减少Camera调用的开销;

UGUI射线(Raycaster)优化

  • 必要的需要交互UI组件才开启“Raycast Target”;
  • 开启“Raycast Targets”的UI组件越少,层级越浅,性能越好;
  • 对于复杂的控件,尽量在根节点开启“Raycast Target”;
  • 对于嵌套的Canvas,OverrideSorting属性会打断射线,可以降低层级遍历的成本;

字体

  • 避免字体框重叠,造成合批打断

字体网格重建(Re-build)时机

  1. UIText组件发生变化时
  2. 父级对象发生变化时
  3. UIText组件或其父对象enable/disable时

动态字体与字体图集

  • 运行时,根据UIText组件内容,动态生成字体图集,只会保存当前Actived状态的UIText控件中的字符;
  • 不同的字体库维护不同的Texture图集;
  • 字体Size、大小写、粗体、斜体等各种风格都会保存在不同的字体图集中(有无必要,影响图集利用效率,一些利用不多的特殊字体可以采用图片代替或使用Custom Font,Font Assets Creater创建静态字体资源);
  • 当前Font Texture不包含UIText需要显示的字体时,当前Font Texture需要重建;
  • 如果当前图集太小,系统也会尝试重建,并加入需要使用的字形,文字图集只增不减;
  • 利用Font.RequestCharacterInTexture可以有效降低启动时间;

UI控件优化注意事项

  • 不需要交互的UI元素一定要关闭Raycast Target选项;
  • 如果是较大的背景图的UI元素建议也要使用Sprite的九宫格拉伸处理,充分减小UI Sprite大小,提高UI Atlas图集利用率;
  • 对于不可见的UI元素,一定不要使用材质的透明度控制显隐,因为那样UI网格依然在绘制,也不要采用active/deactive UI控件进行显隐,因为那样会带来gc和重建开销,尽量通过激活关闭Canvas控件的方式控制;
  • 使用全屏的UI界面时,要注意隐藏其背后的所有内容,给GPU休息机会;
  • 在使用非全屏但模态对话框时,建议使用OnDemandRendering接口,对渲染进行降频;
  • 优化裁剪UI Shader,根据实际使用需求移除多余特性关键字;
  • 滚动视图Scroll View优化
    • 使用RectMask2d组件裁剪
    • 使用基于位置的对象池作为实例化缓存
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇