Render Pipeline
2.1渲染管線架構

2.2 Application Stage
Application階段都是在CPU上面。加速算法,幾何處理都是在這個上面。
CPU經常需要采用多線程來進行處理。
碰撞檢測就經常需要在這個階段進行執(zhí)行。
加速算法等(在19章)也會在這個階段實現(xiàn)。
2.3 Geomerty Processing
幾何階段,大部分的三角以及頂點處理都在這個地方。

有下面幾個階段:
頂點Shader,投影,裁剪,屏幕映射
2.3.1 頂點Shading
頂點Shader的主要作用是計算頂點的位置,也會輸出程序想要輸出的數(shù)據,類似于法線以及貼圖坐標。
傳統(tǒng)的很多shader經常對每個頂點位置計算光線,以及法線,而且在頂點上儲存顏色。這些顏色通過頂點進行插值。利用當代GPU的優(yōu)點有更多shader是每像素計算的,就要看程序員是的判斷了?,F(xiàn)在的頂點shader更多致力于計算每個頂點相關的數(shù)據,例如頂點動畫。
我們在討論如何計算頂點位置的時候坐標系是我們所需要的。模型需要經過多個空間坐標系。一開始模型在自己的模型坐標系,多個實例可以共享一個模型。
然后模型轉換到世界坐標系,世界坐標是唯一的,所有的模型在這同一個空間。
之前提到的,攝像機把所看到的全部渲染出來,攝像機在世界坐標中有一個位置,為了更好裁剪視口,攝像機有視口坐標系。

接下去我們看第二種頂點shader的輸出結果。為了產生真實場景,光有形狀是不夠的,我們還得有材質,燈光和材質能夠被任意形式表現(xiàn),從簡單的顏色到物理屬性度可以描述。
這種燈光對材質的表現(xiàn)稱作shading。渲染方程對一個物體的不同點進行渲染,有些渲染在頂點上而另外一些則在想租上。很多材質數(shù)據可以存在頂點上,比如:點位置、發(fā)現(xiàn)、顏色或者其他的數(shù)學屬性需要被渲染方程所用到的。頂點渲染結果發(fā)送到光柵化以及片元處理階段,頂點渲染在GPU頂點shader中的形式更深層次的在第三以及第五章。
作為頂點渲染的一部分,投影以及裁剪,將視口縮放到一個cube中,目前有兩種形式,一種是正交(orthographic)另一種是透視視圖。

正交只是一種平行投影的類型。其他領域也可以看到使用的領域。
投影被描述成一個矩陣(Section 4.7)所以有時候會和剩余的集合變換連載一起。
將正交視口縮放到視覺空間只是一個縮放過程。
透視投影更加復雜一點,在這種類型的投影中,遠離攝像機的東西看起來更小。平行線會匯聚于一點,這個視覺體積被稱作平截頭。最后也會變成一個單位cube。正交和透視能被4×4矩陣描述。在這樣的變換之后,就會進入裁剪坐標系,頂點shader必須輸出坐標以確保后續(xù)裁剪得以進行。
然而這些舉證變化一個體積到另一個還叫投影是因為,z坐標在圖片中不儲存但是還是會存在z-buffer中,所以模型被投影到了二維空間。
2.3.2 可選頂點處理
剛剛提到的頂點處理在每個管線中都有,上述管線執(zhí)行完之后又一些可選階段在GPU上,順序是這樣的:tessellation, geometry shading, 以及 stream output。他們的使用依賴于硬件的實現(xiàn),并不是所有GPU都有他們的。他們之間無依賴,而且一般用得也比較少,在第三章會每個都講一下
第一個可選階段是tessellation。想想你有一個彈性球物體,如果你用一組三角形進行描述,你會陷入性能以及表現(xiàn)的問題。如果你的球5米遠的時候看起來不錯,但是接近的時候三角輪廓就能看出來了,但是如果你添加面的話那么你的性能就會有問題。曲面細分就可以幫助你實時細化面。
我們聊了一些三角形的,不光是三角形,還能處理點、線、或者其他物體。曲面細分包含了一組shader。Hull shader、tessellator以及domain shader。攝像機距離決定了多細致。
接下去是幾何shader。這個shader出現(xiàn)早于曲面細分shader,而且在GPU上更多可以找到。這個shader更加簡單不過限制也更多。集合shder有很多用途,其中一個就是粒子生成。想象模擬一個煙花爆炸。每個煙花可以被一個點替代,單頂點。幾何shader可以把每個店轉換成一個方形,轉換成更復雜的幾何體讓我們來渲染。
最后一個階段叫做stream output,流輸出,這個階段使得GPU作為一個幾何引擎,并不是將我們的幾何頂點輸出用于渲染而是用于計算。這些數(shù)據會被用于CPU,或者GPU自身。這個階段一般用于例子模擬,例如我們的煙花例子。
這三個階段的順序是曲面細分、幾何shader、流輸出,每一個都是可選的。接下去我們已經有了頂點數(shù)據。到下一步了。
2.3.3 裁剪
只有那些整個火部分在視口體的集合體會被渲染到屏幕上。到下一個階段,而在視口外的集合體就不會被渲染,一部分在視口里面的幾何體會被裁剪。幾何體總是被單位cube裁剪。

2.3.4 屏幕映射
只有裁剪后的幾何體會到達這個階段,剛剛進入這個階段的時候還是三維的,x以及y坐標會轉換到幾何坐標。

DX和OpenGL中的坐標系不太一樣,z坐標的話,OpenGL是(-1+1),DX是(0,1)。視口坐標以及z值被傳到了柵格化階段。
OpenGL把左下角作為坐標系,而DX則是右上角,所以需要注意。
2.4 柵格化
將變化以及投影的頂點將shading數(shù)據聯(lián)系在一起,下面的目標就是找到所有的像素。這個將面片內所有像素找到的過程叫做柵格化??梢苑殖蓛蓚€步驟:片元組裝以及遍歷三角形。

如何覆蓋面片有幾種方法,最簡單的方法,就是對每個像素中心取樣看看在不在面片內。你也許用過更多超采樣和反走樣的方法。另外一個方式就是只要一部分像素覆蓋就算進去。
2.4.1 三角形組裝
這個階段幫你把所有三角形數(shù)據組合在一起,這個過程是硬件所固定的。
2.4.2 遍歷三角形
每個中心被片元覆蓋的像素是一個片元。在Section5.4可以找到更簡單的方法。每個像素的數(shù)據通過三個頂點的差值可以得到,包括了片元深度,以及任何幾何階段得到的數(shù)據。McCormack et al. 提供了更多信息。
McCormack, Joel, and Robert McNamara, “Tiled Polygon Traversal Using Half-Plane Edge Functions,” in Graphics Hardware 2000, Eurographics Association, pp. 15–22, Aug. 2000. Cited on p. 22, 996, 997
以及修正遠景三角形差值。
Heckbert, Paul S., and Henry P. Moreton, “Interpolation for Polygon Texture Mapping and Shading,” State of the Art in Computer Graphics: Visualization and Modeling, Springer- Verlag, pp. 101–111, 1991. Cited on p. 22, 999
所有的取樣到的像素都被送到了下一個階段。
2.5 像素階段
所有像素都被認為包含在三角 面片或者其他的集合體中。這個階段氛圍片元shading以及merging。

這個階段是逐像素逐采樣進行計算。
2.5.1 像素渲染
任何逐像素渲染都在這里進行,使用插值shading數(shù)據。結果是一個或多個顏色傳遞到下一個階段,不像片元組裝以及遍歷三角形,GPU核心大部分都用來做這個事情了。程序員編寫像素著色器,然后用于計算。非常多的技術被用在了這個階段,其中最重要的要算texturing,貼圖了。貼圖更多信息在第六章。簡單說就是把一張或者多張圖片放到物體上,用于多種用途。一個簡單的例子就是如下圖。

二維的圖片映射到了模型的每一個片元上面,然后這會傳遞到下一個階段。
2.5.2 Merging
像素儲存的地方叫做ColorBuffer,實際上是一個顏色的陣列數(shù)組(紅色,綠色,藍色組合)。合并階段就是把像素渲染的結果放到buffer里面,這個階段也被稱作ROP,代表的是“raster operations pipeline”或者“render output unit”取決于誰問你要的。不想渲染階段,GPU這個階段不是完全可編程的,而是可配的。
這個階段也代表了如何處理可見性。也就是哪些東西要顯示到屏幕中,大部分硬件都是使用了z-buffer的處理方式。zbuffer和colorbuffer一樣大,然后每個像素都會儲存目前最近物體的深度值。意味著這個最近的物體將會被渲染。這個算法很簡單,有著O(n)的收斂。由于zbuffer只儲存了蛋哥深度值,所以無法用于透明物體,而是用在所有的不透明物體上,然后透明物體從后往前進行渲染,或者使用順序無關算法(Section5.5)半透明是zbuffer最大的軟肋。
我們剛剛提到了color buffer用于儲存顏色以及zbuffer儲存z值,然而這里還有其他的通道和buffer可以儲存片元信息。透明通道儲存了每個像素的透明信息。Section5.5.。早更老的API中透明通道通過透明測試來進行裁剪?,F(xiàn)在裁剪階段可以插入到片元著色器,這個可以保證完全透明的片元不受到zbuffer的影響(Section6.6)。
Stencil Buffer是一個不再屏幕顯示用于記錄幾何渲染位置信息的buffer。一般每像素包含8位。集合體可以用很多方法渲染到上面,然后buffer內容可以用于控制color buffer以及z buffer。舉個例子,一個圓可以渲染到stencil buffer上,然后只渲染與這個圓相交部分的集合體。所有在管線末尾的函數(shù)稱作raster oprations或者blend operations、這可以將不同的顏色混合起來,一般是半透明或者是顏色的累計,一般混合是API中可配的,但是不能完全可編程。然而一些API支持可編程混合,稱作pixel shading ordering。
framebuffer 一般由系統(tǒng)中的所有buffer組成。
當集合體到達并且通過了光柵化階段,這些可見點就會被顯示在屏幕上,為了防止人眼能夠看清楚繪制的過程,一般使用double buffering,也就是雙緩沖。也就是一個buffer不顯示,繪制,而另外一個顯示,之后交換。
更多信息看Sections5.4.2,23.6以及23.7。
2.6 縱觀管線(不贅述了……)
點、線、三角面是渲染模型的基礎。
想想你在用CAD做一個華夫餅機器,這里需要經過這么多的階段。
Application:
CAD應用程序允許用戶選擇并且移動模型。還有動畫或者移動攝像機來顯示不同角度的機器。初次之外還有燈光以及模型的幾何圖元。到了下一個階段。
Geomerty Processing:
不想翻
光柵化:
不想翻
Pixel Processing:
不想翻
總結
渲染管線是幾十年來圖形硬件進化一達到實時渲染目的的結果。需要注意的是,這并不是唯一的渲染管線類型。離線渲染經歷了不同的進化路線。電影渲染經常使用micropolygon piplines,但是ray tracing以及path traing也會被提到,在Section11.2.2 會被用于架構以及視覺設計中。
多年依賴,開發(fā)者只能用圖形API的固定管線,最后一個使用固定管線的案例的任天堂的Wii。可編程GPU使得存在了更多的操作性。第四版中我們假設所有的開發(fā)都在可編程GPU上。