淺談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越在下方的層顯示越前面。
- Screen Spacce - Camera: 畫布自動適應螢幕尺寸改變,需要設定render camera。如果Scene中的GameObject比UI平面更靠近camera,就會遮擋到UI平面。
-
- 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的渲染流程:
- CPU傳送Draw Call指令給GPU;
- GPU讀取必要的資料到自己的視訊記憶體;
- GPU通過頂點著色器(vertex shader)等步驟將輸入的幾何體資訊轉化為畫素點資料;
- 每個畫素都通過片段著色器(fragment shader)處理後寫入幀快取;
- 當全部計算完成後,GPU將幀快取內容顯示在螢幕上。
從上面的步驟可知,因為sprite的頂點資料更復雜,在第一步和第二步的效率會比image低,image會有更多的fragment shader的計算因為是針對每個畫素的計算,sprite會裁剪掉透明的部分,從而減少了大量的片段著色器運算,並降低了overdraw,sprite會有更多的vertex shader的計算
Reference:
- https://jonyzhao.gitbooks.io/gamedev/content/Unity/UGUI/UGUIRenderSystem.html
- https://blog.csdn.net/qq_30330655/article/details/105970901