UGUI合批原理筆記

作者:@qingqing-zhao
本文為作者原創(chuàng),轉(zhuǎn)載請注明出處:https://www.cnblogs.com/zhaoqingqing/archive/2018/09/25/9658403.htmlhttps://www.cnblogs.com/zhaoqingqing/p/9658403.html

可以通過Frame debugger查看每個drawcall繪制了哪些東西

UGUI源碼下載地址:https://bitbucket.org/Unity-Technologies/ui/downloads/

本文測試環(huán)境:unity2018.2.9f1,基于Unity Editor (PC平臺)

合批的過程

網(wǎng)格更新機制

  • Cavans.SendWillRenderCanvas

    • m_LayoutRebuildQueue
    • m_GraphicRebuildQueue
  • Canvas.BuildBatch 更新所有DrawCall

    • WaitingForJob 子線程網(wǎng)格合并
    • PutGeometryJobFence
    • BatchRendere.Flush UI如果開多線程渲染,BatChRender.Flush會增高,主線程在等待子線程的結(jié)果時Flush會等待。

哪些因素的改變會引起合批

從源碼中可以看到,這些數(shù)據(jù)的改變會引起合批

源碼地址: UI / UnityEngine.UI / UI / Core / Utility / VertexHelper.cs

private List<Vector3> m_Positions = ListPool<Vector3>.Get();//頂點位置的拷貝或指定新頂點位置的數(shù)組
private List<Color32> m_Colors = ListPool<Color32>.Get();//顏色
private List<Vector2> m_Uv0S = ListPool<Vector2>.Get();//基本紋理坐標
private List<Vector2> m_Uv1S = ListPool<Vector2>.Get();//第二套紋理坐標
private List<Vector2> m_Uv2S = ListPool<Vector2>.Get();//第三套紋理坐標
private List<Vector2> m_Uv3S = ListPool<Vector2>.Get();
private List<Vector3> m_Normals = ListPool<Vector3>.Get();//法線
private List<Vector4> m_Tangents = ListPool<Vector4>.Get();//切線
private List<int> m_Indices = ListPool<int>.Get();//mesh的索引

Mesh的API:http://wiki.ceeger.com/script/unityengine/classes/mesh/mesh

http://wiki.ceeger.com/script/unityengine/classes/mesh/mesh.getindices

怎么避免合批

盡量減少“動態(tài)”長文本(運行時修改文本內(nèi)容)

Image或Text,如果不需要點擊,則不要勾選Raycasts

降低界面的更新頻率

避免圖集分離,使用相同的圖集。

同一圖集的Image元素應盡量保證在Hierarchy中連續(xù),避免中間插入其他圖集,或插入文本。

避免圖片疊加在一起(遮擋,旋轉(zhuǎn))

如果sprite是中心鏤空且切圖為九宮格時,可以去除fill center,以減少over draw

透明Image,用來做響應點擊事件,同樣存在開銷

避免或減少Mask的使用,1個Mask至少增加兩個DC

避免頻繁刪除/增加UI對象,UI層次結(jié)構(gòu)變化會引起Canvas的更新

避免頻繁動態(tài)的更新UI元素的Vertex, Rect, Color, Material, Texture等,可能引起Canvas數(shù)據(jù)更新和Batch更新計算,有可能引起VBO Update(重新提交頂點數(shù)據(jù))。

盡可能使用少的UI Material和貼圖(使用圖集),使得可以Batching。

同一父節(jié)點下所有子節(jié)點,保持相同的層次結(jié)構(gòu)(如List控件下的item),便于底層相同depth下UI元素Batch。

避免UI元素數(shù)目過多和層次結(jié)構(gòu)過于復雜影響B(tài)atch更新速度。

固定的Text考慮與背景圖層合在一張圖上(可能不便本地化,但可以減少drawcall)。

使用緩存池,對緩存頻繁使用的元素。

部分內(nèi)容參考:http://gad.qq.com/article/detail/25947

HUD處理(動靜分離)

Canvas重建就是為了合并DC,將經(jīng)常變化的文字放在獨立的Canvas,手動分離Canvas(會增加DC,不能和其它文字合并),但文字變化時其它Canvas就不需要重建。

示例:名字和血條分開在兩個不同的節(jié)點下。這樣當血條變化時,就不會引起名字的更新。如下圖所示:

2、設置scale為0,而不是設置active = false/true,或者添加Alpha Group,設置alpha=0/1

不勾選FillCenter

鏤空九宮格不勾選FillCenter,在Scene的Overdraw下可以查看到,不勾選FillCenter,overdraw會減少。

少用Effect功能

少用Outline,Tiled Sprite

outline額外生成7倍頂點

在一個空場景中,給Text添加outline之后,頂點數(shù)大約是未添加之前的7.5倍。

去掉outline之后,頂點數(shù)下降了很多。

Image不使用Tiled

type=simple時的頂點數(shù)

使用Tiled之后,頂點數(shù)也上漲很多。

參考資料

Unity官方論壇發(fā)布 Unity UI性能優(yōu)化技巧

UGUI優(yōu)化:批次合并源碼分析及工具

工具:UI層級輔助工具,用于顯示UI的層級、批次等數(shù)據(jù),便于UI性能優(yōu)化。使用者可以結(jié)合以上規(guī)則,分析當前UI元素排列順序、材質(zhì)貼圖設置,優(yōu)化UI Batching,減少UI Drawcall。

Unity UI優(yōu)化小結(jié)

重建 是UGUI優(yōu)化的關鍵 -- Unite2017嘉賓楊懷忠分享《UGUI深度優(yōu)化》

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容