1. 程式人生 > 其它 >淺談UGUI的渲染機制

淺談UGUI的渲染機制

本文主要淺談一下UGUI的底層渲染結構以及Canvas渲染模式的概念,關於合批的流程解析建議去看這篇


底層結構

先看到UI渲染的底層結構,UI渲染主要由三個部分組成:CanvasUpdateRegistry, Graphic, CanvasRender

  • CanvasUpdateRegistry負責通知需要渲染的UI元件
  • Graphic負責組織mesh和material然後傳給底層(CanvasRenderer類)
  • CanvasRenderer負責連線canvas和render component,把mesh繪製到Canvas上,CR並不是直接渲染,而是交給Canvas,Canvas再要做合批等操作

UI渲染結構圖:

附上我的靈魂手繪

關於裡面的一些細節:

graphic什麼時候會設成dirty?當一個canvas需要需要rebatch的時候。

那麼什麼時候需要rebatch呢?當一個canvas中包含的mesh發生改變時就觸發,例如setActive、transform的改變、 顏色改變、文字內容改變等等。

什麼時候會發生rebuild呢?當佈局和網格被重新計算的時候就是rebuild,可以理解為rebatch的後續。

那麼CanvasUpdateRegistry是怎麼通知rebuild的呢?每一幀都會觸發WillRenderCanvases註冊事件,然後由CanvasUpdateRegistry響應並執行PerformUpdate(dirty layout rebuild, dirty graphic rebuild)


渲染層級

說完底層,我們再來看看UI渲染層級是怎麼由哪些決定的。我們說的渲染層級高,意思就是會蓋在物體上面,也是最後一個被渲染的那個。

渲染層級是由以下三個層級決定的,從高到低:

  • 相機的layer和depth:culling layer可以決定相機能看到什麼layer,depth越高的相機,其視野內能看到的所有物體渲染層級越高
  • canvas的layer和order
    • Screen Space - Overlay: UI元素置於螢幕上方,畫布自動適應螢幕尺寸改變。sort order越大顯示越前面
    • Screen Spacce - Camera: 畫布自動適應螢幕尺寸改變,需要設定render camera。如果Scene中的GameObject比UI平面更靠近camera,就會遮擋到UI平面。
      • order layer越大顯示越前面;sorting layer越在下方的層顯示越前面。
    • World Space: 當UI為場景的一部分,即UI為場景的一部分,需要以3D形式展示。變數和camera screen space一樣
  • 物體的hierarchy關係:物體越在下面,顯示越在前面
    • 比如,image1會被image2給遮擋住

 


渲染器的對比

UGUI的渲染器是Canvas Render, 同樣渲染2D物體的是Sprite Render

相同點:

  • 都有一個渲染佇列來處理透明物體,從後往前渲染
  • 都可以通過圖集併合並渲染批次,減少drawcall

不同點

  • Canvas Render要與Rect Transform配合,必須在Canvas裡使用,常用於UI。Sprite Render與transform配合,常用於gameplay
  • Canvas Render基於矩形分隔的三角形網路,一張網格里最少有兩個三角形(不同的image type, 三角形的個數也會不同),透明部分也佔空間。Sprite Render的三角網路較為複雜,能剔除透明部分

 

Sprite會根據顯示內容,裁剪掉元素中的大部分透明區域,最終生成的幾何體可能會有比較複雜的頂點結構

 

Image會老老實實地為一個矩形的Sprite生成兩個三角形拼成的矩形幾何體 

 

一個DrawCall的渲染流程:

  1. CPU傳送Draw Call指令給GPU;
  2. GPU讀取必要的資料到自己的視訊記憶體;
  3. GPU通過頂點著色器(vertex shader)等步驟將輸入的幾何體資訊轉化為畫素點資料;
  4. 每個畫素都通過片段著色器(fragment shader)處理後寫入幀快取;
  5. 當全部計算完成後,GPU將幀快取內容顯示在螢幕上。

從上面的步驟可知,因為sprite的頂點資料更復雜,在第一步和第二步的效率會比image低,image會有更多的fragment shader的計算因為是針對每個畫素的計算,sprite會裁剪掉透明的部分,從而減少了大量的片段著色器運算,並降低了overdraw,sprite會有更多的vertex shader的計算

 

Reference:

  1. https://jonyzhao.gitbooks.io/gamedev/content/Unity/UGUI/UGUIRenderSystem.html
  2. https://blog.csdn.net/qq_30330655/article/details/105970901