在OpenGL中任何事物都在3D空間中,可是屏幕和窗口是一個2D像素陣列,因此OpenGL的大部分工做都是關於如何把3D座標轉變爲適應你屏幕的2D像素。3D座標轉爲2D座標的處理過程是由OpenGL的圖形渲染管線完成的。圖像渲染管線能夠被劃分爲兩個主要部分:第一個部分把你的3D座標轉換爲2D座標,第二部分是把2D座標轉變爲實際的有顏色的像素。小程序
渲染管線接收一組3D座標,而後把它們轉變爲你屏幕上的有色2D像素。渲染管線能夠被劃分爲幾個階段,每一個階段須要把前一階段的輸出做爲輸入。全部這些階段都是高度專門化的,它們能簡單地並行執行。因爲它們的並行執行的特徵,當今大多數顯卡都有成千上萬的小處理核心GPU,在GPU上爲每個階段運行各自的小程序,從而在圖形輸送管道中快速處理你的數據。這些小程序叫作着色器。有些着色器容許開發者本身配置,用咱們本身寫的着色器替換默認存在的。這樣咱們就能夠更細緻地控制渲染管線的特定部分,由於它們運行在GPU上,因此它們也會節約寶貴的CPU時間。着色器是用OpenGL着色器語言(OpenGL Shading Language)GLSL寫成的。數組
下圖顯示了渲染管線中各個階段主要完成的工做,藍色部分表明的是咱們能夠定義本身的着色器。測試

在上圖中,咱們以數組的形式傳遞3個3D座標做爲渲染管線的輸入,用它來表示一個三角形,這個數組叫作頂點數據(Vertex Data);這裏頂點數據是幾個頂點的集合。每一個頂點是用頂點屬性(vertex attributes)表示的,它能夠包含任何咱們但願用的數據,下面咱們來看看渲染管線中各個階段主要完成的工做:blog
- 渲染管線的第一個部分是頂點着色器(vertex shader),它把一個單獨的頂點做爲輸入。頂點着色器主要的目的是把3D座標轉爲另外一種3D座標(投影座標),同時頂點着色器容許咱們對頂點屬性進行一些基本處理。
- 圖元組裝(primitive assembly)階段把頂點着色器的表示爲基本圖形的全部頂點做爲輸入,把全部點組裝爲特定的基本圖形的形狀;上圖中是一個三角形。
- 圖元組裝階段的輸出會傳遞給幾何着色器(geometry shader)。幾何着色器把基本圖形造成的一系列頂點的集合做爲輸入,它能夠經過產生新頂點構造出新的(或是其餘的)基本圖形來生成其餘形狀。
- 細分着色器(tessellation shaders)擁有把給定基本圖形細分爲更多小基本圖形的能力。這樣咱們就能在物體更接近玩家的時候經過建立更多的三角形的方式建立出更加平滑的視覺效果。
- 細分着色器的輸出會進入光柵化(rasterization)階段,這裏它會把基本圖形映射爲屏幕上相應的像素,生成供像素着色器(fragment shader)使用的fragment(OpenGL中的一個fragment是OpenGL渲染一個獨立像素所需的全部數據。)。在像素着色器運行以前,會執行裁切(clipping)。裁切會丟棄超出你的視圖之外的那些像素,來提高執行效率。
- 像素着色器的主要目的是計算一個像素的最終顏色,這也是OpenGL高級效果產生的地方。一般,像素着色器包含用來計算像素最終顏色的3D場景的一些數據(好比光照、陰影、光的顏色等等)。
- 在全部相應顏色值肯定之後,最終它會傳到另外一個階段,咱們叫作alpha測試和混合(blending)階段。這個階段檢測像素的相應的深度(和stencil)值,使用這些來檢查這個像素是否在另外一個物體的前面或後面,如此作到相應取捨。這個階段也會查看alpha值(alpha值是一個物體的透明度值)和物體之間的混合(blend)。因此即便在像素着色器中計算出來了一個像素所輸出的顏色,最後的像素顏色在渲染多個三角形的時候也可能徹底不一樣。
雖然渲染管線有多個階段,每一個階段都須要對應的着色器,但其實對於大多數場合,咱們必須作的只是頂點和像素着色器,幾何着色器和細分着色器是可選的,一般使用默認的着色器就好了。如今的OpenGL中,咱們必須定義至少一個頂點着色器和一個像素着色器(由於GPU中沒有默認的頂點/像素着色器)。ip