1.頂點著色器
頂點著色器是流水線的第一個階段,它的輸入來自于CPU。頂點著色器的處理單位是頂點,也就是說輸入進來的每個頂點都會調(diào)用一次頂點著色器。
頂點著色器需要完成的工作主要有:坐標變換和逐頂點光照。當然,除了這兩個主要任務外,頂點著色器還可以輸出后續(xù)階段所需的數(shù)據(jù)。
坐標變換,顧名思義,就是對頂點的坐標進行某種變換。例如我們可以通過改變頂點位置來模擬水面,布料等。
一個最基本的頂點著色器必須完成的一個工作是:把頂點坐標從模型空間轉(zhuǎn)換到齊次剪裁空間。類似下面代碼:
o.pos=mul(UNITY_MVP,v.position);
2.裁剪
由于我們的場景可能會很大,而攝像機的視野范圍很有可能不會覆蓋所有的場景物體,一個很自然的想法就是,那些不在攝像機視野范圍內(nèi)的物體不需要被處理,而裁剪就是為了完成這個目的而被提出來的。
一個圖元和攝像機的關(guān)系有3種:
完全在視野內(nèi)
部分在視野內(nèi)
完全在視野外
部分在視野內(nèi)的圖元需要裁剪,例如一條線段的一個頂點在視野內(nèi),而另一個頂點在視野外,那么視野外部的頂點應該使用一個新的頂點來代替,這個新的頂點位于這條線段和視野邊界的交點處。
3.屏幕映射
這一步輸入的坐標仍然是三維坐標系。屏幕映射的任務是把每個圖元的x和y坐標轉(zhuǎn)換到屏幕坐標系下,屏幕坐標系是一個二維坐標系,它和我們用于顯示畫面的分辨率有很大關(guān)系。
屏幕映射得到的屏幕坐標決定了這個頂點對應屏幕上哪個像素以及距離這個像素有多遠。
opengl的屏幕坐標原點是左下角,而directx是左上角,如果你發(fā)現(xiàn)你得到的圖像是倒轉(zhuǎn)的,那么很有可能就是這個原因造成的。
4.三角形設(shè)置
由這一步就進入了光柵化階段,從上一個階段輸出的信息是屏幕坐標下的頂點位置以及和它們相關(guān)的額外信息,如深度值、法線方向、視角方向等,光柵化有兩個最重要的目標:計算每個圖元覆蓋了哪些像素,以及為這些像素計算他們的顏色。光柵化的第一個流水線階段是三角形設(shè)置,這個階段會計算光柵化一個三角網(wǎng)格所需的信息。
具體來說,上一個階段輸出的都是三角網(wǎng)格的頂點,即我們得到的是三角網(wǎng)格每條邊的兩個端點。但如果要得到整個三角網(wǎng)格對像素的覆蓋情況,我們就必須計算每條邊上的像素坐標。為了能夠計算邊界像素的坐標信息,我們就需要得到三角形邊界的表示方式。這樣一個計算三角形網(wǎng)格表示數(shù)據(jù)的過程就叫做三角形設(shè)置,它的輸出是為了下一個階段做準備。
5.三角形遍歷
三角形遍歷階段將會檢查每個像素是否被一個三角形網(wǎng)格所覆蓋。如果被覆蓋的話,就會生成一個片元,而這樣一個找到哪些像素被三角網(wǎng)格覆蓋的過程就是三角形遍歷,這個階段也被稱為掃描變換。
三角形遍歷階段會根據(jù)上一個階段的計算結(jié)果來判斷一個三角網(wǎng)格覆蓋了哪些像素,并使用三角網(wǎng)格3個頂點的頂點信息對整個覆蓋區(qū)域的像素進行插值。
6.片元著色器
片元著色器是另一個非常重要的可編程著色器階段,片元著色器的輸入是上一個階段對頂點信息插值得到的結(jié)果,更具體來說,是根據(jù)那些從頂點著色器輸出的數(shù)據(jù)插值得到的。而它的輸出是一個或多個顏色值。
這一階段可以完成很多重要的的渲染技術(shù),其中最重要的技術(shù)之一就是紋理采樣。為了在片元著色器中進行紋理采樣,我們通常會在頂點著色器階段輸出每個頂點對應的紋理坐標,然和經(jīng)過光柵化階段對三角網(wǎng)格的3個頂點對應的紋理坐標進行插值后,就可以得到其覆蓋的片元的紋理坐標了。