1. 程式人生 > >OpengGl學習03 渲染管線

OpengGl學習03 渲染管線

渲染管線(rendering pipeline):它是一系列資料處理過程,並且將應用程式的資料轉換到最終渲染的影象。流程如下:


OpenGL首先接收使用者提供的幾何資料(頂點和幾何圖元),並且將他們輸入到一些列著色器階段中進行處理,包括:頂點著色、細分著色(它本身包含兩個著色器),以及最後的幾何著色,然後它將被送入光柵化單元(rasterizer)。光柵化單元負責對所有剪下區域(clipping region)內的圖元生成片元資料,然後對每個生成的片元都執行一個片元著色器

(1)準備向OpenGL傳輸資料: OpenGL需要將所有的資料都儲存到快取物件(buffer object)中,他相當於OpenGL服務端維護的一塊記憶體區域。我們可以使用多種方式來建立這樣的資料快取,最常見的就是glBufferData()命令。

(2)將資料傳輸到OpenGL:當將快取初始化完畢之後,我們可以通過OpenGL的一個繪製命令來請求渲染幾何圖元。如glDrawArray()就是一個常用的繪製命令。OpenGL的繪製通常是將頂點資料傳輸到OpenGL服務端,我們可以將一個頂點是為一個需要統一處理的資料包。這個包的資料可以是我們需要的任何資料(也就是說,我們自己負責定義構成頂點的所有資料)。其他的資料可能用來定義一個畫素的最終顏色。

(3)頂點著色:對於繪製命令傳輸的每個頂點,OpenGL都會呼叫一個頂點著色器來處理頂點相關的資料。根據其他光柵化之前的著色器的活躍與否,頂點著色器可能會非常簡單,例如,只是將資料複製並傳遞到下一個著色階段,這叫做傳遞著色器(pass-through-shader);它也可能非常複雜,例如,執行大量的計算來得到頂點在螢幕上的位置(一般情況下,我們會用到變換矩陣(transformation matrix)的概念),或者通過光照的計算來判斷定點的顏色,或者其他一些技法的實現。通常來說,一個複雜的應用程式可能包含多個頂點著色器,但是在同一時刻只能有一個頂點著色器起作用。

(4)細分著色:頂點著色器處理每個頂點的關聯資料之後,如果同時激活了細分著色器(tessellation shader),那麼它將進一步處理這些資料。細分著色器會使用Patch來描述一個物體的形狀,並且使用相對簡單的Patch幾何體連線來完成細分工作,其結果是幾何圖元的數量增加,並且模型的外觀會變得更為平順。細分著色器階段會用到兩個著色器來分別管理Patch資料並生成最終的形狀。

(5)幾何著色:允許在光柵化之前對每個幾何圖元做更進一步的處理,例如建立新的圖元。這個著色器階段也是可以選的。

(6)圖元裝配:前面所有的著色階段所處理的都是頂點資料,此外,這些頂點之間如何構成幾何圖元的所有資訊也會被傳遞到OpenGL當中。圖元裝配階段將這些頂點與相關的幾何圖元之間組織起來,準備下一步的剪下和光柵化工作。

(7)剪下:頂點可能會落在視口(viewport)之外——也就是我們可以進行繪製的視窗區域——此時與頂點相關的圖元會做出改動,以保證相關的畫素不會在視口外繪製。這一過程叫做剪下(clipping),它是由OpenGL自動完成的。

(8)光柵化:剪下之後,會將更新後的圖元傳遞到光柵化單元,生成對應的片元。我們可以將一個片元視為一個“候選的畫素”,也就是可以放置在幀快取中的畫素,但是它也可能被最終剔除,不再更新對應的畫素位置。之後的兩個階段會執行片元的處理,即片元著色和逐片元的操作。

(9)片元著色:使用著色器來計算片元的最終顏色和它的深度值。片元著色器非常強大,我們可以使用紋理對映的方式,對頂點處理階段所計算的顏色進行補充。如果我們覺得不應該繼續繪製某個片元,我們還可以終止這個片元的處理,這個叫做片元的丟棄(discard)。頂點著色器與片元著色器的區別:頂點著色器(包括細分和幾何著色)決定了一個圖元應該位於螢幕的什麼位置,而片元著色使用這些資訊來決定某個片元的顏色應該是什麼。

(10)逐片元的操作:在這個階段,我們會使用深度測試(depth test 通常也稱作z-buffering)和模板測試(stencil test)的方式來決定一個片元是否可見。如果一個片元通過了素有的測試,那麼它就可以直接繪製到幀快取中了,它對應的畫素的顏色值(可能包括深度值)會被更新,如果開啟了融合(blending)模式,那麼片元的顏色會與該畫素當前的顏色相疊加,形成一個新的顏色值並寫入幀快取中。