本文主要淺談一下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