當前位置:網站首頁>Unity3d:UGUI源碼,Rebuild優化
Unity3d:UGUI源碼,Rebuild優化
2022-07-23 12:39:58【四夕立羽】
Image怎麼繪制的
Unity中渲染的物體都是由網格(Mesh)構成的,而網格的繪制單元是圖元(點、線、三角面)
繪制信息都存儲在Vertexhelper類中,除了頂點外,還包括法線、UV、顏色、切線。
Rebuild概念
Canvas負責將子節點的UI元素的網格合並,並生成相應的渲染指令再發送到Unity的圖形管道的過程。所以Canvas就是渲染UI的組件,當UI發生變化就要執行一次Batch,它是影響性能更大的元凶。注意Canvas的Batch只會影響其子節點,但不會影響其子Canvas。
Rebuild的程序流程
- Image,Text都是繼承Graphic,Graphic有ICanvasElement接口,實現rebuild函數
public interface ICanvasElement
{
/// <summary>
/// Rebuild the element for the given stage.
/// </summary>
/// <param name="executing">The current CanvasUpdate stage being rebuild.</param>
/// // 根據CanvasUpdate的不同階段重建元素
void Rebuild(CanvasUpdate executing);
- CanvasUpdateRegistry監聽Canvas的willRenderCanvases事件,這個事件會在渲染前進行每幀調用
public class CanvasUpdateRegistry
{
//布局重建隊列,當UI元素的布局需要更新時將其加入隊列
private readonly IndexedSet<ICanvasElement> m_LayoutRebuildQueue = new IndexedSet<ICanvasElement>();
//圖形重建隊列,當UI元素的圖像需要更新時將其加入隊列
private readonly IndexedSet<ICanvasElement> m_GraphicRebuildQueue = new IndexedSet<ICanvasElement>();
protected CanvasUpdateRegistry()
{
//監聽了Canvas的willRenderCanvases事件,這個事件會在渲染前進行每幀調用
Canvas.willRenderCanvases += PerformUpdate;
}
- PerformUpdate收集布局重建隊列,圖形重建隊列調用ICanvasElement.Rebuild完成重建
何時加入重建
通過設置“髒數據”實現的,包括布局(Layout)、材質(Material)和頂點(Vertices)三部分,設置布局為髒,將進行布局重建,設置頂點或材質為髒,則進行圖形重建。布局重建會將自身加入m_LayoutRebuildQueue中,圖形重建則會將自身加入m_GraphicRebuildQueue中,等待被調用。
SetLayoutDirty:加入到布局重建隊列
SetVerticesDirty,SetMaterialDirty:材質,頂點變換加入到圖形重建隊列
布局重建:比特置或者大小 ;
圖像重建:頂點變化,材質變化(大小,旋轉以及文字變化、圖片的修改)
優化
主要目標,把Profile裏Canvas.SendWillRenderCanv參數調小。通過限制頂點數量,頂點變化等。
text屬性改變(“123”–>“1234”),觸發SetLayoutDirty:在做倒計時相關,按照每1s改變,不要實時改變
改文字,圖片顏色,觸發SetVerticesDirty(頂點改變),所以改圖片顏色最好是改材質球顏色
layout組件引起重建問題
text 描邊,陰影性能問題
一個字符產生4個頂點,
如果再加上Shadow則相當於又把Text複制了一遍產生8個,
Outline則會將Text複制4遍產生20個頂點。
用相應的shader替換text漸變
Image格式選擇
Image:頂點數量取决於Image Type的選擇。
①Simple 4 個頂點;
②Sliced 勾選FillCenter的頂點數是 36 個,不勾選是 32 個;
③Tiled 取决於Rectranform 設置的大小和原圖大小,鋪開了 N 張圖就是 4*N 個;
④Filled 選擇比較多,但最少也有4個。
所以對於Image首選Simple模式其次則是Sliced模式且不勾選FillCenter動靜分離 :Canvas.SendWillRenderCanvases()與Canvas.BuildBatch()的計算是以Canvas為根節點進行的,不同Canvas不會影響另外一個Canvas。但是,大量的動靜分離反而影響Canvas的合批,所以可以針對性的對戰鬥UI,主界面做分離
源碼中查看影響重建因素
觸發SetLayoutDirty
Graphic:
- protected override void OnRectTransformDimensionsChange():當UI的RectTransform更改時的回調,只要繼承UIBehavior即可獲取回調
Image:
- protected override void OnCanvasHierarchyChanged():父畫布的狀態改變
Text:
- text屬性改變:在做倒計時相關,按照每1s改變,不要實時改變
- public bool supportRichText:設置是否開啟富文本時,開關規則(只要狀態跟上次不同,SetLayoutDirty一下,而不是開啟後實時Dirty)
- public bool resizeTextForBestFit:設置是否允許文本自動調整大小時,開關規則
- public int resizeTextMinSize:允許的最小文本大小
- public int resizeTextMaxSize:設置最大文本大小
- public TextAnchor alignment:文本相對其 RectTransform 的定比特。
- public int fontSize:文本大小
- public HorizontalWrapMode horizontalOverflow:水平溢出模式
- public VerticalWrapMode verticalOverflow:垂直溢出模式
- public float lineSpacing:行間距,指定為字體行高的一個因子。值為 1 時將生成標准行間距
- public FontStyle fontStyle:字體樣式
觸發SetVerticesDirty:頂點變化
Graphic:
- public virtual Color color:顏色,所以改圖片顏色最好是改材質球顏色
- protected override void OnRectTransformDimensionsChange():當UI的RectTransform更改時的回調,只要繼承UIBehavior即可獲取回調
Image:
- public Type type:Simple,Sliced等
- public bool preserveAspect:是否保持高寬比,開關規則
- public bool fillCenter
- public FillMethod fillMethod:填充模式
- public float fillAmount
- public bool fillClockwise
- public int fillOrigin
- public bool useSpriteMesh:圖片透明部分裁剪
- protected override void OnCanvasHierarchyChanged():父畫布改變
RawImage:
- public Texture texture
- public Rect uvRect
Shadow:
- public Color effectColor
- public Vector2 effectDistance
- public bool useGraphicAlpha
Text:
- public virtual string text
- public bool supportRichText
- public bool resizeTextForBestFit
- public int resizeTextMinSize
- public int resizeTextMaxSize
- public TextAnchor alignment
- public bool alignByGeometry:使用區段的字形幾何執行水平對齊,而不是字形指標。
這可以導致更好的擬合左和右對齊,但可能會導致不正確的定比特當試圖覆蓋多個字體(如專業輪廓字體)上 - public int fontSize
- public HorizontalWrapMode horizontalOverflow
- public VerticalWrapMode verticalOverflow
- public float lineSpacing
- public FontStyle fontStyle
觸發SetMaterialDirty:材質改變
Graphic:
- public virtual Material material
Mask:
- public bool showMaskGraphic:
- protected override void OnEnable()
- protected override void OnDisable()
- protected override void OnValidate():編輯器用
MaskableGraphic:
- public bool maskable
- protected override void OnTransformParentChanged()
- protected override void OnCanvasHierarchyChanged()
- public virtual void RecalculateMasking():為此元素和所有子元素重新計算遮罩。
觸發SetAllDirty,全改變
Image間接繼承自Graphic,當它的Sprite發生變化時,會調用SetAllDirty函數
SetAllDirty改變時機
Graphic:
- protected override void OnTransformParentChanged() 父物體改變
- protected override void OnEnable()
- protected override void Reset():賦值默認值,只在編輯器下有用,可無視
- protected override void OnDidApplyAnimationProperties():動畫屬性改變
- protected override void OnValidate():脚本加載或Inspector中的任何值被修改時會調用,只在編輯器下有用,可無視
Image:
- static void RebuildImage(SpriteAtlas spriteAtlas) 圖集改變
- sprite屬性改變
- overrideSprite 臨時修改圖片
- public override void SetNativeSize() 設置大小
Text:
- public void FontTextureChanged():字體紋理被修改:TTF動態字體,Text每次賦值的時候Unity會生成貼圖,以及保存每個字的UV信息,那麼顯示字體的時候根據UV信息去生成的貼圖裏取最終渲染在屏幕上。
- font屬性更改
版權聲明
本文為[四夕立羽]所創,轉載請帶上原文鏈接,感謝
https://cht.chowdera.com/2022/204/202207230540018823.html
邊欄推薦
猜你喜歡
隨機推薦
- 【STM32學習】(21)STM32實現步進電機
- 繪制帶有查詢條件變量的table【grafana】
- 認識接口
- LABVIEW:創建一個VI
- 界面開發框架DevExtreme Gantt控件——可導出PDF、排序任務
- MySQL命令行導出導入數據庫和數據錶
- 有數大數據基礎平臺之智能運維平臺EasyEagle介紹:集群隊列篇
- 你記住JS中offsetWidth、clientWidth、width、scrollWidth、clientX、screenX、offsetX、pageX嗎?
- 【Azure 事件中心】Azure Event Hub 新功能嘗試 -- 异地灾難恢複 (Geo-Disaster Recovery)
- unity 照片牆
- 影響持續交付的因素有哪些?
- 【快速上手教程7】瘋殼·開源編隊無人機-地面站上比特機的使用和介紹
- Redis配置詳解
- docker安裝MySQL、redis
- 【嵌入式】限幅電路和鉗比特電路 利用二極管的單向導電性
- [知識圖譜]cql與py2neo學習筆記
- C語言學習
- 列轉行與數據集連接在業務場景的組合應用
- MySQL5.6/ 5.7 SSL配置
- 【深度學習】損失函數(平均絕對誤差,均方誤差,平滑損失,交叉熵,帶權值的交叉熵,骰子損失,FocalLoss)
- *精度優化*優化策略1:網絡+SAM優化器
- AXI協議詳解
- js--Date對象&三元錶達式
- leetcode-買賣股票的最佳時機含手續費
- unity中3dUI或者模型始終面向攝像機,跟隨攝像機視角旋轉丨視角跟隨丨固定視角
- JVM初探
- 移動端測試之appium環境部署【未完待續】
- 關於後臺掛載,進程管理的學習
- 讀《高效閱讀法-最劃算的自我投資》有感
- shell基本命令
- 從鍵盤輸入一串字符,輸出不同的字符以及每個字符出現的次數。(輸出不按照順序)運用String類的常用方法解題
- 2019_AAAI_ICCN
- 影響接口查詢速度的情况
- 《STL適配器》stack和queue
- 淺析緩存的讀寫策略
- 類和對象(1)
- 實驗二 YUV
- 大咖訪談 | 開源社區裏各種奇怪的現狀——夜天之書陳梓立tison
- synchronized是如何實現的
- 【arXiv2022】GroupTransNet: Group Transformer Network for RGB-D Salient Object Detection