[OpenGL]概念--渲染管線
在OpenGL中任何事物都在3D空間中,但是螢幕和視窗是一個2D畫素陣列,所以OpenGL的大部分工作都是關於如何把3D座標轉變為適應你螢幕的2D畫素。3D座標轉為2D座標的處理過程是由OpenGL的圖形渲染管線完成的。影象渲染管線可以被劃分為兩個主要部分:第一個部分把你的3D座標轉換為2D座標,第二部分是把2D座標轉變為實際的有顏色的畫素。
渲染管線接收一組3D座標,然後把它們轉變為你螢幕上的有色2D畫素。渲染管線可以被劃分為幾個階段,每個階段需要把前一階段的輸出作為輸入。所有這些階段都是高度專門化的,它們能簡單地並行執行。由於它們的並行執行的特徵,當今大多數顯示卡都有成千上萬的小處理核心GPU,在GPU上為每一個階段執行各自的小程式,從而在圖形輸送管道中快速處理你的資料。這些小程式叫做著色器。有些著色器允許開發者自己配置,用我們自己寫的著色器替換預設存在的。
在上圖中,我們以陣列的形式傳遞3個3D座標作為渲染管線的輸入,用它來表示一個三角形,這個陣列叫做頂點資料(Vertex Data);這裡頂點資料是幾個頂點的集合。每個頂點是用頂點屬性(vertex attributes)表示的,它可以包含任何我們希望用的資料,下面我們來看看渲染管線中各個階段主要完成的工作:
- 渲染管線的第一個部分是頂點著色器(vertex shader),它把一個單獨的頂點作為輸入。頂點著色器主要的目的是把3D座標轉為另一種3D座標(投影座標),同時頂點著色器允許我們對頂點屬性進行一些基本處理。
- 圖元組裝(primitive assembly)階段把頂點著色器的表示為基本圖形的所有頂點作為輸入,把所有點組裝為特定的基本圖形的形狀;上圖中是一個三角形。
- 圖元組裝階段的輸出會傳遞給幾何著色器(geometry shader)。幾何著色器把基本圖形形成的一系列頂點的集合作為輸入,它可以通過產生新頂點構造出新的(或是其他的)基本圖形來生成其他形狀。
- 細分著色器(tessellation shaders)
- 細分著色器的輸出會進入光柵化(rasterization)階段,這裡它會把基本圖形對映為螢幕上相應的畫素,生成供畫素著色器(fragment shader)使用的fragment(OpenGL中的一個fragment是OpenGL渲染一個獨立畫素所需的所有資料)。在畫素著色器執行之前,會執行裁切(clipping)。裁切會丟棄超出你的檢視以外的那些畫素,來提升執行效率。
- Fragment Shader(片元著色器,又叫畫素著色器)的主要目的是計算一個畫素的最終顏色,這也是OpenGL高階效果產生的地方。通常,畫素著色器包含用來計算畫素最終顏色的3D場景的一些資料(比如光照、陰影、光的顏色等等)。
- 在所有相應顏色值確定以後,最終它會傳到另一個階段,我們叫做alpha測試和混合(blending)階段。這個階段檢測畫素的相應的深度(和stencil)值,使用這些來檢查這個畫素是否在另一個物體的前面或後面,如此做到相應取捨。這個階段也會檢視alpha值(alpha值是一個物體的透明度值)和物體之間的混合(blend)。所以即使在畫素著色器中計算出來了一個畫素所輸出的顏色,最後的畫素顏色在渲染多個三角形的時候也可能完全不同。
雖然渲染管線有多個階段,每個階段都需要對應的著色器,但其實對於大多數場合,我們必須做的只是頂點和畫素著色器,幾何著色器和細分著色器是可選的,通常使用預設的著色器就行了。現在的OpenGL中,我們必須定義至少一個頂點著色器和一個畫素著色器(因為GPU中沒有預設的頂點/畫素著色器)。
渲染管線簡要流程
二維頂點畫素化