1. 程式人生 > 其它 >shader入門精要筆記(2)

shader入門精要筆記(2)

CPU和GPU之間的通訊

渲染流水線的起點是CPU(應用階段)應用階段可分為:1.把資料載入到視訊記憶體中。2.設定渲染狀態。3.呼叫Draw Call

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

所有的渲染所需的資料來自硬碟,然後載入到系統記憶體中,之後網格和紋理等資料又被載入到視訊記憶體中,顯示卡對於視訊記憶體的訪問速度更快,大多數顯示卡對於RAM沒有直接的訪問權利。載入到視訊記憶體的資料為:頂點位置資訊,法線方向,頂點顏色,紋理座標等。吧資料載入到視訊記憶體中後,RAM中的資料便可移除,對於一些資料我們可能不希望被移除,因為從硬碟到RAM的過程很耗時。而這需要通過CPU來設定渲染狀態,指導CPU如何工作。

2.設定渲染狀態

(使用什麼紋理,開不開啟混合,使用哪個頂點著色器,哪個片元著色器)泛指如何進行渲染

3.呼叫Draw Call

Draw Call 就是一個命令,它由CPU發起,GPU接收,這個命令只會指向需要被渲染的圖元列表,不會包涵材質資訊(已經在渲染狀態中設定好了)如果給定一個 Draw Call時,GPU就會根據渲染狀態(材質,紋理,著色器)和所有被輸入的頂點資料來進行計算,最終輸入到螢幕上的畫素。計算過程即為GPU流水線。

GPU流水線:當GPU收到CPU的渲染命令,進行的一系列流水先操作,最終把圖元渲染到螢幕上。具體流程如下:頂點資料 》{( 頂點著色器 》 曲面細分著色器 》幾何著色器 》 裁剪 》螢幕對映 )幾何階段 } 在幾何階段 ,頂點著色器,曲面細分著色器,幾何著色器是可程式設計的,其中曲面細分著色器,幾何著色器是該shader是可選的。裁剪是流水線可以配置但不可程式設計的。螢幕對映是由GPU固定實現的,開發者沒有任何控制權。

由幾何階段 》 (三角形設定 》 三角形遍歷 》片元著色器 》逐片元操作)光柵化階段 》 螢幕影象 。在光柵化階段,三角形設定,三角形遍歷是由GPU固定實現的,開發者沒有任何控制權。片元著色器是可程式設計的且是該shader是可選的。逐片元操作是流水線可以配置但不可程式設計的。

概念:1.頂點著色器(完全可程式設計,實現頂點變換,頂點著色等功能)2.曲面細分著色器(可選的著色器,用於細分圖元)3.幾何著色器(可選著色器,用於逐圖元操作或產生更多的圖元)4.裁剪(可配置,將不在攝像機視野的頂點裁剪掉,剔除某些三角面的面片)自定義:通過指令控制裁剪區域,通過指令控制裁剪正面還是背面。 5.螢幕對映(無法控制,負責把每個圖元座標轉換到螢幕座標系中)6.三角形設定和三角形遍歷(固定函式)7.片元著色器(完全可程式設計,逐片元的著色操作)8.逐片元操作(可配置性極高:修改顏色,深度緩衝,進行混合)

詳細解釋:1.頂點著色器:它是流水線的第一個階段,從CPU輸入,它對頂點進行處理,輸入進來的每一個頂點都會呼叫一次頂點著色器,但是頂點著色器不能夠建立和銷燬任何頂點,而且無法得到頂點和頂點之間的關係,無法得知兩個頂點是否屬於同一個三角網格,由於其相互獨立性,GPU可以快速優化每一個頂點。頂點著色器主要完成的工作為座標變換和逐頂點光照,其還可以輸入後續階段所需的資料。

座標變換:對頂點座標(位置)進行某種變換,可以進行頂點動畫,其必須完成的工作是把頂點座標從模型空間轉換到齊次裁剪空間下來:o.pos = mul(UNITY_MVP,v.position);由硬體做透視除法後,最終得到歸一化的裝置座標。頂點著色器有不同的輸出方式,常見輸出方式為:經過光柵化後交給片元著色器進行處理。

2.裁剪:由於場景很大,攝像機視野不可能完全覆蓋場景,經過裁剪剔除不在攝像機視野內的物體。圖元與攝像機視野由三種關係:完全在視野內,部分在視野內,完全在視野外。完全在視野內的圖元被渲染,視野外被剔除,視野邊緣生成新的頂點。

3.螢幕對映:這一階段仍是三維座標系下的座標,螢幕對映的任務是把每個圖元的X和Y座標轉換到螢幕座標系,螢幕座標系是二維座標系與顯示畫面解析度有關。螢幕對映得到的螢幕座標決定了這個頂點對於螢幕上哪個畫素以及距離畫素有多遠

4.三角形設定:自此進入光柵化階段,計算目標:計算每個圖元覆蓋了哪些畫素,以及為這些畫素計算他們的顏色,作為光柵化的第一 階段,其會計算光柵化一個三角網格所需的資訊,上一階段輸出的是三角網格的頂點,而這一階段得到三角網格每條邊上的兩個端點,為了計算邊界畫素的座標資訊需要得到三角形邊界的表示方式,這樣一個過程叫做三角形設定。

5.三角形遍歷:此階段將檢查每個畫素是否會被一個三角網格所覆蓋,被覆蓋則生成一個片元,找到哪些畫素被三角網格覆蓋的過程是三角形遍歷,此階段也為掃描變換。一個片元是包涵很多狀態的集合,包括法線資訊,螢幕座標,紋理座標,深度資訊等。

6.片元著色器:是非常重要的可程式設計著色器階段,在DX中被稱為畫素著色器,其相當於又一次儲存了一系列資料(產生一系列資料資訊以此表述一個三角網格是怎樣覆蓋每個畫素的)這一階段便可進行紋理取樣通過光柵化階段對三角網格的3個頂點對應的紋理座標進行插值,得到覆蓋片元的紋理座標

7.逐片元操作:OPGL的說法,在DX中被稱為輸出合併階段,主要任務:決定每個片元的可見性。涉及深度測試,模板測試。如果一個片元經過所有的測試,需把這個片元的顏色值和已經儲存在顏色緩衝區中的顏色進行合併(或者混合)。通常其過程為:片元 》》模板測試 》》深度測試》》混合 》》顏色緩衝區。模板測試對應的便是模板緩衝,開發者可進行修改操作進行指定,如果開啟模板測試,GPU會讀取掩碼中片元設定的模板值,然後讓該值和讀取(掩碼)的參考值進行比較,函式由開發者制定,小於時捨棄,或者大於時捨棄,取決於開發者。通常高階使用(渲染陰影,輪廓渲染)。 通過模板測試後進行到深度測試,開啟深度測試後將該片元的深度值與已經存在深度緩衝區中的深度值進行比較,與上一過程類似,其由開發者進行設定。若沒有通過測試便會被捨棄,如果通過測試,開發者還可判斷是否通過此片元深度值覆蓋原有的深度值,通過開啟/關閉寫入而達到,透明效果和深度測試深度寫入關係密切。 不透明物體,開發者可以關閉混合操作,半透明則使用混合溼氣看起來是透明的。混合操作也是可以高度配置的。為了避免我們看到正在進行的光柵化的圖元,GPU會使用雙重緩衝的策略,對場景的渲染是在幕後發生的,即在後置緩衝中。一旦場景已經被渲染到了後置緩衝中,GPU就會交換後置緩衝區和前置緩衝區中的內容,而前置緩衝區是之前顯示在螢幕上的影象,因此我們看到的影象是連續的。

總結:這是渲染的基本全流程,而在Unity 中,它已經封裝好了大部分操作,我們只需修改和編寫頂點著色器和片段著色器設定一些狀態即可,掌握其背後原理明白一些錯誤原因也是尤其重要的。