視圖(Viewport,或者視口)變換
現在的實時渲染場景中包含的對象(模型)可以有很多個,但是只有被攝像機(或者說觀察者,也即是設定的視角覆蓋)的區域才會被渲染。這個攝像機在世界空間里有一個用來擺放的位置和面向的方向。
為了實現接下來的投影、裁剪處理,攝像機和模型都需要進行視圖變換這個操作,目的是將攝像機放置在坐標原點上,使其正對的方向為 Z 軸(負向),Y 軸指向上(上圖是從攝像機正上方俯視,所以沒法給出 Y 軸),X 軸指向右。
頂點著色
所謂著色就是指確定光照在物料上所呈現效果的操作,這類操作既可能運行于幾何階段的模型頂點上,也可能運行于光柵階段的各個像素上,也就是所謂的頂點著色和像素著色。
在頂點著色的時候,各個頂點需要存放若干個相關的物料數據,例如頂點位置、法線、色彩以及其他任何進行著色處理計算相關的數字信息。
頂點著色的計算結果(可以是色彩、向量、紋理坐標以及任何其他著色數據)會被發送到光柵化階段進行插值處理。
投影
在完成了著色處理后,渲染系統會把可視體轉換為一個位于(-1, -1, -1)到(1, 1, 1)的單元立方體(unit-cube)中,這個立方體被稱作正則觀察體(canonical view volume),使用到的投影方式一般有兩種:平行投影和透視投影。
前一種主要在 CAD 等軟件中使用,后一種因為模擬了我們人類的視覺體驗,所以在游戲或者虛擬現實中經常使用:
上圖分別是一部 iPhone 6s Plus 以平行投影和透視投影的方式呈現在屏幕上的效果。
三角形裁剪
只有在可視體內的圖元會被傳送到在屏幕上繪制這些圖元的光柵階段,在進行裁剪動作的時候,如果圖元有頂點落在可視體之外,裁剪的時候就會將可視體之外的這部分剪切掉并且在可視體與圖元相交的位置生成新的頂點,而位于立方體外部的舊圖元就會被拋棄掉。
屏幕映射
經過上一步裁剪后的位于可視體內的圖元會被傳遞到屏幕映射階段,此時的坐標信息依然是三維的。圖元的 X、Y 坐標被變換到屏幕坐標系,屏幕坐標再加上 Z 軸坐標就被稱作窗口坐標。
我們假定場景要渲染到一個最小角落坐標為(x1, y1)和最大角落坐標為 (x2, y2)的窗口中,也就是 x1 《 x2,y1 《 y2。此時,屏幕映射執行的是一個縮放處理后的轉換操作。Z 軸坐標并不受此操作的影響。
現在,新的 x 軸、 y 軸坐標就是屏幕坐標,有對應的屏幕像素位置,不再是之前投影處理后的那個立方體所采用的映像坐標系統。
光柵處理階段要干些什么呢?
在獲得了經過變換和投影處理的頂點及其相關聯的著色信息后,光柵化處理階段的目的就是計算并設置好被對象覆蓋區域的像素顏色。這個處理被稱作光柵化或者掃描轉換,也就是把二維坐標上包含深度(Z 軸)信息和各種相關著色信息的頂點到屏幕上像素的轉換。
這個處理階段一般可以拆分為 4 個工位:
1、三角形設定
2、三角形遍歷
3、像素著色
4、輸出合并
三角形設定
這一步會進行三角形表面的微分以及其他關于三角形表面數據的計算,計算出來的數據會被用于掃描轉換以及幾何階段所產生的各種著色數據的插值處理。在GPU上這一步會采用固定硬件功能單元來實現。
三角形遍歷
這一步用作確定像素的中心是否被三角形覆蓋 ,如果該像素被三角形覆蓋的話,就會生成對應的片元(fragment)。
查找哪些樣本或者像素是否位于三角形內通常被稱作三角形遍歷或者掃描轉換。
每個三角形對應片元的屬性都是由該三角形的三個頂點數據插值而成,例如片元的深度值以及來自幾何階段的著色數據。
像素著色
所有的逐像素(per-pixel)著色計算都在這一步執行,使用的輸入數據是之前插值的著色數據。像素著色發送到下一個工位的計算的結果可能是一個色彩值也可能是多個色彩值。
和三角形設定以及三角形遍歷不同采用固定硬件功能單元不同的是,現在的像素著色都是由可編程的GPU內核執行。
在像素著色所依賴的眾多技術中最為重要的就是貼圖(texturing),所謂貼圖就是把一張或者多張圖片“貼”到對象上。
輸出合并
在這一步執行的操作主要是將之前步驟生成的色彩信息進行合并形成最終輸出的像素色彩。
用于存放像素色彩信息的緩存被稱作色彩緩存,一般情況下是以紅、綠、藍三個色元的方式存放,此外還有一個用于存放像素對應深度信息值的深度緩存(一般采用 Z-Buffer)。
在GPU中實現這一步的功能單元有幾種叫法,例如 ROP、Output Merger 或者 Back-End。
在這個階段,Output Merger 會根據深度緩存(depth buffer 或者 Z-buffer)存放的深度信息判斷是否更新色彩緩存中的色彩值。
例如當前像素計算出來的深度值(例如是 0.1)比深度緩存中對應像素的值小(例如是 0.2),則表示當前像素的三角形比色彩緩存存放的像素所對應的三角形更靠近“攝像頭”,于是GPU會對該圖元的色彩進行計算并把新計算出來的色彩值和深度值更新到色彩緩存和深度緩存中,否則的話就不會更新當前像素的緩存。
在整個場景完成渲染后,色彩緩存中存放的都是從攝像機視角位置看到的可視圖元色彩值。
這樣處理的好處是三角形可以使用任意次序來渲染,但是如果圖元或者說三角形是部分透明的話,則必須依照從遠到近的三角形層次進行渲染。這是 Z-Buffer 的主要缺點之一。
像素除了色彩緩存和深度緩存外,還有其他利用通道或者緩存的技術來用于過濾和捕捉片元(fragmet)信息。