1. 程式人生 > >《Unity Shader入門精要》總結 #第二章 渲染流水線

《Unity Shader入門精要》總結 #第二章 渲染流水線

這個基本上是昨天看完今天覆習的,理論篇。

1、渲染流水線

概念性的三個階段:應用階段->(輸出渲染圖元)->幾何階段->(輸出螢幕空間的頂點資訊)->光柵化階段

-應用階段

CPU負責實現,開發者有絕對掌控權。

三個主要任務:

       -準備場景資料(eg.攝像機位置、視錐體、場景中哪些模型、哪些光源,etc)

       -culling粗粒度剔除

       -設定好模型的渲染狀態(材質、紋理、shader,etc)

最重要的輸出的幾何資訊:渲染圖元

-幾何階段

通常GPU實現,決定繪製圖元是什麼、怎樣繪製、哪裡繪製

負責和每個渲染圖元打交道,進行逐頂點、逐多邊形的操作

一個重要任務:

        -頂點座標變換到螢幕空間

輸出:螢幕空間的二維頂點座標、每個頂點對應的深度值、著色

-光柵化階段

通常GPU實現,利用上階段資料產生螢幕畫素,渲染出最終影象

決定哪些畫素被繪製在螢幕上,對上一階段的逐頂點資料進行差值,進行逐畫素處理

兩個重要目標:

-計算每個圖元覆蓋了哪些畫素

        -位畫素計算它們的顏色

2、CPU和GPU間的通訊

主要涉及到三個階段:

        -把資料載入到視訊記憶體中

        -設定渲染狀態

        -呼叫Draw Call

2.1 資料載入到視訊記憶體

資料流向:硬碟(HDD)->系統記憶體(RAM)->視訊記憶體(VRAM)【大多顯示卡對RAM無直接訪問權】

需要通過CPU指導GPU如何進行渲染工作

2.2 設定渲染狀態

網格如何進行渲染(eg. 使用哪個頂點/片源著色器、光源屬性、材質,etc)

2.3 呼叫Draw Call

指向需要被渲染的圖元列表,不包含任何材質資訊

3、GPU流水線

3.1 流水線實現:

頂點資料->頂點著色器->(曲面細分著色器)->(幾何著色器)->裁剪->螢幕對映

              ->三角形設定->三角形遍歷->片元著色器->逐片元操作->螢幕影象

完全可程式設計控制 可配置但不可程式設計 無任何控制權

---------------------------------------------------------------------------------------------------

頂點著色器:完全可程式設計。實現頂點空間變換、頂點著色等

曲面細分著色器:可選,細分圖元

幾何著色器:可選,執行逐圖元操作/產生更多圖元

裁剪:將不在視野內頂點剪裁,剔除某些三角圖源面片

螢幕對映:每個圖元座標轉換到螢幕座標系

---------------------------------------------------------------------------------------------------

三角形設定、三角形遍歷:固定函式

偏遠著色器:完全可程式設計,實現逐片著色操作

逐片元操作:eg. 修改顏色、深度緩衝、混合

---------------------------------------------------------------------------------------------------

-頂點著色器

處理單位:頂點。輸入進來的每個頂點都呼叫一次vertex shader。

無法知道頂點間的關係(eg.是否屬於同一三角網格),但由於獨立GPU處理速度很快

完成的工作任務:

-座標變換

           -逐頂點光照(計算頂點顏色?)

           -輸出後續階段所需資料

-座標變換

改變頂點位置-頂點動畫

最基本的工作:把頂點座標從模型空間轉換到齊次裁剪空間

如:o.pos = mul(UNITY_MVP, v.position);[注:MVP,MV應該是指Model View Matrix, P應該是指Projection Matrix,望指正]

       (頂點座標轉換到齊次裁剪座標系,硬體做透視除法,最終得到歸一化裝置座標)

       (PS:OpenGL也是Unity用的NDC,z分量[-1,1],DirectX在[0,1])

輸出路徑經光柵化後交給片元著色器進行處理,還可以把資料傳送給曲面細分著色器或幾何著色器

-裁剪

剪裁不在攝像機視野範圍的物體

圖元與視野的三種關係:完全在視野內、部分在視野內、完全在視野外

可以自定義裁剪操作進行配置

-螢幕對映

把圖元的x,y座標轉換到螢幕座標系下,決定了這個頂點對應螢幕上哪個畫素以及距離這個畫素有多遠。對輸入z的座標不作任何處理。

螢幕座標系與z座標構成了視窗座標系,一起傳入到光柵化階段

【PS:OpenGL左下角是最小的視窗座標值,DirectX是左上角】

---------------------------------------------------------------------------------------------------

-三角形設定

光柵階段,上一階段輸出的資訊時螢幕座標系下的頂點位置+深度值(z)、法線方向、視角方向

是一個計算三角網格表示資料的過程

上一階段輸出的是三角網格的頂點,通過兩邊頂點計算每條邊上的畫素座標,得到三角形邊界的表示方法。

-三角形遍歷

檢查每個畫素是否被三角網格覆蓋,如果覆蓋就生成片元

找到哪些畫素被三角網格覆蓋的過程,也被叫做掃描變換

輸出片元序列

片元fragment:狀態集合,包括不限於螢幕座標、深度資訊、從幾何階段輸出的頂點資訊(法線、紋理)

-片元著色器

前面的光柵化階段不會影響到每個pixel的眼素質,而是產生資料資訊來表述一個三角網格如何覆蓋每個畫素。

輸入時上一階段對頂點資訊(頂點著色器輸出)插值得到的結果,輸出一個或多個顏色值

渲染技術:紋理取樣(在頂點著色器階段輸出每個頂點對應的紋理座標,通過對三個頂點的紋理座標插值得到覆蓋的片元紋理)

侷限:影響單個片元,不可以將任何結果(導數資訊除外)發給鄰居

根據上一步茶之後的片源資訊,計算該片元的輸出顏色

-逐片元操作

Merger的作用,合併,即輸出合併階段

兩個主要任務:

 -決定每個片元的可見性,涉及到深度測試、模板測試等

        -片元通過所有測試,就把偏遠顏色值和已儲存在顏色緩衝區中的顏色進行合併/混合

-片元可見性問題

        -模板測試

         和顏色緩衝、深度緩衝類似,開啟測試GPU讀取掩碼和模板緩衝區中該片元位置的模板值,將該值與讀取的參考值進行比較。比較函式可以開發者指定(如小於或大於某值捨棄該片元)。不論是否通過測試,均可根據測試結果修改模板緩衝區(如失敗時模板緩衝區保持不變,同時將模板緩衝區對應位置值+1)

          通常用於限制渲染區域、渲染陰影、輪廓渲染等

        -深度測試

深度值大於等於當前深度緩衝區的值則捨棄它,通常只顯示出離攝像機最近的物體,而那些被其他物體遮擋的就不需要出現在螢幕上。與模板測試不同的是若沒有通過深度測試就沒權利更改深度緩衝區中的值。若通過了測試,則指定是否要用這個片元的深度值覆蓋掉原有的深度值,通過開啟、關閉深度寫入做到。(透明效果與深度測試和深度寫入關係密切)

-合併/混合

通過渲染時,顏色緩衝中往往已經有上次渲染之後的顏色結果,我們使用這次渲染得到的顏色完全覆蓋之前的結果還是進行其他處理

對於不透明物體,關閉blend操作,則片元計算得到的顏色值直接覆蓋;而半透明就需要混合操作。

開啟混合功能,則GPU取出源顏色(片元著色器)和目標顏色(存在於顏色緩衝區的顏色值),進行混合

測試順序不唯一,邏輯上測試是在片元著色器後進行,但GPU儘可能在執行片元著色器之前遍進行測試。但測試提前的話,檢測結果可能會與片元著色器中的操作衝突。若有衝突則禁用提前測試,造成效能上下降,透明度測試導致效能下降

GPU使用雙緩衝策略,場景被渲染到後置緩衝中,GPU會交換後置緩衝區和前置緩衝區中的內容,使看到影象連續

3.2 總結

unity封裝了諸多功能,但導致變成自由度下降

4、總結

4.1 OpenGL和DirectX

程式設計介面,應用程式向介面傳送渲染命令(draw call),介面依次向顯示卡驅動(顯示卡的OS)傳送渲染命令,顯示卡驅動翻譯成GPU可理解的程式碼。因為有驅動的存在,即支援OpenGL也支援DirectX

顯示卡有GPU外,還有記憶體即視訊記憶體(VRAM)

4.2 HLSL、GLSL和CG

DirectX - HLSL,OpenGL - GLSL,NVIDIA - CG(C for Graphic)

GLSL,跨平臺,編譯結果取決於硬體供應商的做法

HLSL,基本是微軟自身產品,微軟控制著色器編譯

CG,真正意義跨平臺

4.3 Draw Call

CPU呼叫影象程式設計介面

-CPU如何與GPU實現並行工作

命令緩衝區,draw call是其中一種,其餘有改變使用的著色器、使用不同的紋理等

-為什麼draw call多了影響幀速率

類比總容量一樣的數量不同的檔案壓縮,GPU渲染速度快魚CPU提交命令速度

-如何減少draw call

批處理,需要在CPU記憶體中合併網格,更適合於靜態物體

可以:避免使用大量很小網格,不可避免時考慮可否合併;避免使用過多材質

4.4 固定管線渲染

淘汰

5、Shader是什麼

GPU流水線上一些可高度程式設計的階段;

有一些特定型別的著色器(vertex shader & fragment shader);

依靠著色器可控制流水線中的渲染細節,如頂點著色器的頂點變換以及傳遞資料,片元著色器進行畫素渲染