Unity - 性能優(yōu)化實戰(zhàn)07 - UGUI優(yōu)化

一负饲、Canvas Batch

一個Canvas繪制Mesh的過程中搀庶,如果每個UI元素都繪制一次(DrawCall)蜕径,則耗時會很長。因此Canvas會先對其UI元素按照材質和渲染順序排序懂从,將能夠一起繪制的UI元素合并到一個Mesh中,然后繪制蹲蒲。這樣可以有效減少DrawCall


二番甩、ReBuild

  • ReBuild是Canvns ReBatch過程中完成的

  • ReBuild是重建UI元素時的操作,它會改變UI的Mesh信息届搁,進而觸發(fā)ReBatch缘薛。當修改了UI元素的縮放,尺寸卡睦,材質宴胧,旋轉等信息時都會觸發(fā)重建

  • 在WillRenderCanvases事件調用PerformUpdate::CanvasUpdateRegistry接口

    • 通過ICanvasElement.Rebuild方法重新構建Dirty的Layout組件
    • 通過ClippingRegistry.Cullf方法,任何已注冊的裁剪組件Clipping Compnents(Such as Masks)的對象進行裁剪剔除操作
    • 任何Dirty的 Graphics Compnents都會被要求重新生成圖形元素
  • Layout Rebuild

    • UI元素位置表锻、大小牺汤、顏色發(fā)生變化
    • 優(yōu)先計算靠近Root節(jié)點,并根據(jù)層級深度排序
  • Graphic Rebuild

    • 頂點數(shù)據(jù)被標記成Dirty
    • 材質或貼圖數(shù)據(jù)被標記成Dirty

三浩嫌、Canvas和Graphic

  • Canvas負責管理UGUI元素,負責UI渲染網(wǎng)格的生成與更新补胚,并向GPU發(fā)送DrawCall指令
  • UI組件的基類是Graphic码耐,Graphic核心是組織Mesh和Material傳到底層(CanvasRenderer)
  • CanvasRenderer將Mesh和Material傳遞給Canvas,Canvas做合批溶其。CanvasRenderer的兩個核心SetMesh和SetMaterial骚腥。每個Graphic有一個CanvasRenderer,保存了保存當前元素的Mesh和材質瓶逃。一個Graphic為dirty束铭,Canvas就要重新合批

四、UGUI渲染細節(jié)

  • UGUI中渲染是在Transparent半透明渲染隊列中完成的厢绝,半透明隊列的繪制順序是從后往前畫契沫,由于UI元素做Alpha Blend,我們在做UI時很難保障每一個像素不被重畫,UI的Overdraw太高昔汉,這會造成片元著色器利用率過高懈万,造成GPU負擔。
  • UI SpriteAtlas圖集利用率不高的情況下靶病,大量完全透明的像素被采樣也會導致像素被重繪会通,造成片元著色器利用率過高;同時紋理采樣器浪費了大量采樣在無效的像素上娄周,導致需要采樣的圖集像素不能盡快的被采樣涕侈,造成紋理采樣器的填充率過低,同樣也會帶來性能問題煤辨。

五裳涛、Unity UI性能的四類問題

1.1 Canvas Re-batch 時間過長

  • 指Canvas分析其UI節(jié)點信息木张,生成最優(yōu)批次的過程

  • 耗時:節(jié)點數(shù)量,層級深度调违,元素重疊窟哺,材質數(shù)量等

  • 觸發(fā)時機:當Canvas中的UI節(jié)點的Mesh改變時(SetActive,transform技肩,顏色……..)

  • 觸發(fā)過程:根據(jù)UI元素深度關系進行排序且轨、檢查UI元素的覆蓋關系、檢查UI元素材質并進行合批

  • 觸發(fā)結果:重新Batch一次虚婿,無論當前Mesh的改變是否影響了父節(jié)點(也就是說一個很小的變化旋奢,就會讓當前Canvas重新Batch一次)

  • 解決方案:

    1. 可以用多個同級Canvas或者Canvas套Cnavas的方法,來將復雜層級劃分到不同Canvas中去然痊,需要注意的是每個Canvas都至少有一個DrawCall(當有子UI元素時)至朗,這樣可能會增加DrawCall
    2. 使用 動靜Canvas分離的方案可以將ReBatch的范圍限制在動態(tài)Canvas中
    3. 減少層級復雜度,少用嵌套的樹形UI結構剧浸,同時將材質相同的UI盡量放到同一層級

1.2 Canvas Over-dirty, Re-batch次數(shù)過多

  • 每當UI元素的Mesh改變時锹引,都會觸發(fā)ReBatch來重新計算,因此我們要盡量減少UI元素Mesh的改變
  • 兩個按鈕中不疊加時唆香,合批為2
  • 當?shù)谝粋€按鈕文字和第二個按鈕背景重疊時嫌变,合批為4

1.3 生成網(wǎng)格頂點時間過長

  • 可以看到Cumulative Vertex Count數(shù)量,越多耗時越久

1.4 片元利用率高 - Fill-rate overutilization

  • 一個像素被多次繪制躬它,稱為片元利用率高腾啥,一次繪制中,如果一個像素被反復繪制N次冯吓,這樣會導致GPU利用率過高





六倘待、使用Canvas的基本準則

  • 將所有可能打斷合批的層移到最下邊的圖層,盡量避免UI元素出現(xiàn)重疊區(qū)域
  • 可以拆分使用多個同級或嵌套的Canvas來減少Canvas的Rebatch復雜度
  • 拆分動態(tài)和靜態(tài)對象放到不同Canvas下组贺。
  • 盡量不使用Layout組件
  • Canvas的RenderMode盡量Overlay模式凸舵,減少Camera調用的開銷

七、Raycast優(yōu)化

  • 必要的需要交互UI組件才開啟“Raycast Target”
  • 開啟“Raycast Targets”的UI組件越少失尖,層級越淺贞间,性能越好
  • 對于復雜的控件,盡量在根節(jié)點開啟“Raycast Target”
  • 對于嵌套的Canvas雹仿,OverrideSorting屬性會打斷射線增热,可以降低層級遍歷的成本

八、UI字體

  • 避免字體框重疊胧辽,造成合批打斷

  • 字體網(wǎng)格重建

    • UIText組件發(fā)生變化時
    • 父級對象發(fā)生變化時
    • UIText組件或其父對象enable/disable時
  • TrueTypeFontImporter

    • 支持TTF和OTF字體文件格式導入


  • 動態(tài)字體與字體圖集

    • 運行時峻仇,根據(jù)UIText組件內容,動態(tài)生成字體圖集邑商,只會保存當前Actived狀態(tài)的 UIText控件中的字符
    • 不同的字體庫維護不同的Texture圖集
    • 字體Size摄咆、大小寫凡蚜、粗體、斜體等各種風格都會保存在不同的字體圖集中(有無必要吭从,影響圖集利用效率朝蜘,一些利用不多的特殊字體可以采用圖片代替或使用Custom Font,F(xiàn)ont Assets Creater創(chuàng)建靜態(tài)字體資源)
    • 當前Font Texture不包含UIText需要顯示的字體時涩金,當前Font Texture需要重建
    • 如果當前圖集太小谱醇,系統(tǒng)也會嘗試重建,并加入需要使用的字形步做,文字圖集只增不減
    • 利用Font.RequestCharacterInTexture可以有效降低啟動時間

九副渴、UI控件優(yōu)化注意事項

  • 不需要交互的UI元素一定要關閉Raycast Target選 項
  • 如果是較大的背景圖的UI元素建議也要使用Sprite的九宮格拉伸處理,充分減小UI Sprite大小全度,提高UI Atlas圖集利用率
  • 對于不可見的UI元素煮剧,一定不要使用材質的透明度控制顯隱,因為那樣UI網(wǎng)格依然在繪制将鸵,也不要采用active/deactive UI控件進行顯隱勉盅,因為那樣會帶來gc和重建開銷
  • 使用全屏的UI界面時,要注意隱藏其背后的所有內容顶掉,給GPU休息機會草娜。
  • 在使用非全屏但模態(tài)對話框時,建議使用OnDemandRendering接口一喘,對渲染進行降頻。
  • 優(yōu)化裁剪UI Shader嗜暴,根據(jù)實際使用需求移除多余特性關鍵字凸克。

十、滾動視圖Scroll View優(yōu)化

  • 使用RectMask2d組件裁剪
  • 使用基于位置的對象池作為實例化緩存

參考文章

https://zhuanlan.zhihu.com/p/343524911
https://zhuanlan.zhihu.com/p/343978391

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末闷沥,一起剝皮案震驚了整個濱河市萎战,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌舆逃,老刑警劉巖蚂维,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異路狮,居然都是意外死亡虫啥,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門奄妨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來涂籽,“玉大人,你說我怎么就攤上這事砸抛∑来疲” “怎么了树枫?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長景东。 經(jīng)常有香客問我砂轻,道長,這世上最難降的妖魔是什么斤吐? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任搔涝,我火速辦了婚禮,結果婚禮上曲初,老公的妹妹穿的比我還像新娘体谒。我一直安慰自己,他們只是感情好臼婆,可當我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布抒痒。 她就那樣靜靜地躺著,像睡著了一般颁褂。 火紅的嫁衣襯著肌膚如雪故响。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天颁独,我揣著相機與錄音彩届,去河邊找鬼。 笑死誓酒,一個胖子當著我的面吹牛樟蠕,可吹牛的內容都是我干的。 我是一名探鬼主播靠柑,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼寨辩,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了歼冰?” 一聲冷哼從身側響起靡狞,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎隔嫡,沒想到半個月后甸怕,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡腮恩,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年梢杭,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片秸滴。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡式曲,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情吝羞,我是刑警寧澤兰伤,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站钧排,受9級特大地震影響敦腔,放射性物質發(fā)生泄漏。R本人自食惡果不足惜恨溜,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一符衔、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧糟袁,春花似錦判族、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至周叮,卻和暖如春辩撑,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背仿耽。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工合冀, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人项贺。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓君躺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親开缎。 傳聞我的和親對象是個殘疾皇子棕叫,可洞房花燭夜當晚...
    茶點故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內容