1. 程式人生 > >深入理解渲染流水線----學習Shader的基礎(入門必備)

深入理解渲染流水線----學習Shader的基礎(入門必備)

       :今天早晨偶然看到一個名詞Unity-SRP,SRP嚇我一跳。。。一時間沒反應過來是什麼東西,好高大尚的名詞,遂決定寫這篇文章。一來想把接觸過的都總結下來,所謂的前人栽樹後人乘涼(把自己說的高尚了點。。。hhh)與君共勉;二來,一直對shader比較感興趣,作shader系列的部落格深挖一些技術知識。

       題外知識:SRP,其實就是Scriptable Render Pipeline,可程式設計指令碼渲染管線。別被這麼高階的名詞嚇到,很簡單,它就Unity中通過C#可以對渲染進行配置和執行的一種方式(Unity2018下載自帶,對於開發者來說更加方便。新版Unity的SRP這塊我再後面會詳細介紹,現在先簡單有個概念)。渲染管線:看起來應該是個名詞,指的是將一個物件顯示到螢幕上這個過程,這個流水線,我們要研究的就是這個過程中的一些技術。

       正題:渲染管線即渲染流水線,這個流水線任務是從三維的物體生成一張二維的影象,而流水線的工人是CPU和GPU。這個流水線一共分為三個階段:

      應用階段-->幾何階段-->光柵化階段

      應用階段

                      負責人:開發人員主導;

                      執行者:CPU;

                      工作:1.準備好場景資料,包括攝像機,模型,光源等  ;2.不可見的做一些剔除;3.設定模型的渲染狀態(eg:材質、紋理、shader等) 等。

                      輸出:渲染圖元(通俗點應該就是點,線,面等)

                       分為三個階段:

                        1.資料載入到視訊記憶體:所有渲染所需的資料先從硬碟載入到記憶體然後又被載入到視訊記憶體(因為顯示卡對視訊記憶體的訪問速度快)                 

                        2.設定渲染狀態(即告訴GPU該如何渲染),根據不同的渲染狀態,網格會渲染成不同結果。

                        3.呼叫DrawCall(即DC)。發起方CPU,接收方GPU。CPU告訴GPU可以開始渲染了,GPU就開始根據之前的渲染狀態和提前準備好的資料計算,輸出螢幕上的畫素。

      幾何階段

                      執行者:GPU;

                      工作:逐頂點、逐多邊形的看看需要繪製什麼,怎麼樣繪製和繪製在哪裡。

                       輸出:螢幕空間的二維頂點座標,也包含每個頂點的深度和著色等資訊。

       光柵化階段

                      執行者:GPU;

                      工作:用上個階段的資料產生畫素,渲染到螢幕上。

後兩個階段就是GPU的流水線所做的事情,下面我們具體看看GPU的流水線(將上面後兩個階段更加細分):

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

            光柵化階段: -->三角形設定-->三角形遍歷-->片元著色器-->逐片元操作-->螢幕影象

 下面具體介紹一下流水線中的這幾個階段:

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

       這些頂點相互獨立,並行處理,主要完成座標變換(注:可以改變頂點的位置,所以可以模擬水面變化等)和逐頂點光照。座標變化:頂點座標從模型空間到齊次裁剪空間。我們常看到的這一句shader程式碼就完成了這個基本操作:o.pos = mul(UNITY_MVP, v.position);(最終得到的是歸一化的裝置座標,即NDC,DirectX中這個座標的z分量是0~1,OpenGL,Unity使用的這個座標的z分量是 -1 ~1)

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

       幾何著色器:可選,逐片元著色或產生更多片元;

       裁剪:可配置,將不在攝像機視野中的頂點裁掉,剔除一些三角面片。完全不在視野中的裁剪掉,一部分在視野裡的裁掉後用新頂點(交界處)代替。

       螢幕對映:不可配置和程式設計,把圖元座標轉換到螢幕座標系中。這步輸入仍是三維的座標,將圖元的x,y轉換到螢幕座標系下(二維,和解析度有關)。opengl左下角為(0,0),DirectX左上角為 (0,0)。

       三角形設定,三角形遍歷:固定函式階段。之前的輸出都是頂點和頂點資訊,現在開始計算三角網格的邊,三角形設定開始計算光柵化一個三角形網格所需的資訊。三角遍歷會檢查每個畫素是否被一個三角網格覆蓋,如果覆蓋就生成一個片元,使用三個頂點的資訊對覆蓋區域的畫素進行插值,輸出一堆片元。片元還不是最終的畫素,裡面還有一些狀態,用來生成最終畫素的顏色。     

       片元著色器(DX中也叫畫素著色器):輸入是上個階段的頂點插值後的資訊,輸出是顏色值。可程式設計,逐片元著色。很多渲染技術在這裡。

       逐片元操作:不可程式設計,可配置。eg:修改顏色、深度緩衝、混合等。決定每個片元的可見性;如果通過了測試,將這個片元的顏色值和已經儲存在顏色緩衝區的顏色合併(混合)。如下圖:

                    片元-->模板測試-->深度測試-->混合-->顏色緩衝區

        總結:ok,就這麼多了,如果能理解了這些,我想基本上對渲染管線有個基礎的瞭解,才可以進而去學習更高階的圖形渲染技術。歡迎大家來拍磚!

參考 《Unity Shader 入門精要》馮樂樂