天天看點

圖形渲染管線概述應用程式階段幾何階段光栅化階段

概述

圖形渲染管線(Graphics Pipeline),簡單的說就是把錄影機看到的東西,繪制成一幅2D圖像的過程。可以分為3個階段:

1. 應用程式階段

2. 幾何階段

3. 光栅化階段

圖形渲染管線概述應用程式階段幾何階段光栅化階段

[圖1-1 可程式設計渲染管線]

應用程式階段

這個階段是在CPU上執行的,例如batching,遮擋剔除(occlusion culling)等加速算法。因為視錐裁剪(frustum culling)是在vertex shader之後執行的,這就意味着在視錐體之外的頂點也會有頂點計算開銷,是以應當盡量少的向GPU傳遞無用的頂點。有很多處理這個問題的加速算法,比如八叉樹,還有上面提到的遮擋剔除算法。

在這個階段的最後CPU把模型,渲染指令和貼圖發送給GPU,進入幾何階段。

幾何階段

Vertex Shader

通過乘以級聯的4x4變換矩陣(MATRIX_MVP)的方式,把頂點從模型空間變換到齊次裁剪空間,友善進行随後Clip/Cull/Setup操作。 以最常見的透視投影為例,在齊次裁剪空間中,把錄影機的視錐體變換成了機關立方體(x,y,z的範圍都在[-1, 1]之間)。

圖形渲染管線概述應用程式階段幾何階段光栅化階段

[圖1-2 視錐體變換過程]

除了對頂點的空間變換之外,還有頂點的UV,法線的變換等,最終将結果存到輸出寄存器中,等待傳入fragment shader中進行下一步處理。下面是它的工作流程:

圖形渲染管線概述應用程式階段幾何階段光栅化階段

[圖1-3 vertex shader的工作流程]

圖元裝配(Primitive Assembly)

接着把頂點裝配成圖元,一般都是三角形。隻有在機關立方體内的才會進入下一階段,是以,完全在立方體之外的被舍棄,部分在外面的,則會保留在立方體内的部分,并且重新産生頂點裝配成新的圖元。然後把幸存下來的圖元映射到螢幕上(x,y轉化成螢幕坐标,z不變,還是[-1, 1]),進入光栅化階段。

圖形渲染管線概述應用程式階段幾何階段光栅化階段

[圖1-4 裁剪過程]

p.s. 固定渲染管線中,T&L是同時發生在幾何階段的。把頂點和光照轉換到世界空間或者視點空間中,進行光照計算。然而在可程式設計管線中,光照可以在vertex shader中計算,也可以在光栅化之後,fragment shader中進行逐像素的計算。 是以這裡并沒有特别寫光照部分,以免産生不必要的困惑。

光栅化階段

光栅化

光栅化是把螢幕空間的二維坐标轉化成fragment(fragment可以了解為潛在的像素,通過各種測試的fragment将會被寫入後備緩存區(frame buffer),最終顯示在螢幕上)。下面這張圖展示了渲染管線的整個過程,可以看到,光栅化階段把三角形轉化成了所占區域的像素點,有點類似Flash中把向量圖打散為像素圖的過程。

圖形渲染管線概述應用程式階段幾何階段光栅化階段

[圖1-5 圖示化渲染管線]

Fragment Shader

光栅化後的fragment,讀取vertex shader中的結果作為輸入,計算這個fragment的顔色值。與vertex shader不同,fragment shader能進行貼圖操作。下面是它的工作流程:

圖形渲染管線概述應用程式階段幾何階段光栅化階段

[圖1-6 fragment shader的工作流程]

ROP(Raster Operations)

在将fragment寫入後備緩存區之前,會進行各種測試,以判斷目前fragment是要寫入還是丢棄。

圖形渲染管線概述應用程式階段幾何階段光栅化階段

[圖1-7 标準opengl和dx的光栅操作]

通過測試的fragment,深度和模闆緩存中的值将會被更新。顔色值則會有一個blend操作,将fragment的顔色值和與顔色緩存中對應位置點的像素值做混合操作,最終寫入顔色緩存中。

參考文獻:

《Real Time Rendering》

《The Cg Tutorial》

http://blog.sina.com.cn/s/blog_754853c1010126u0.html

http://blog.chinaunix.net/uid-20235103-id-2680299.html

繼續閱讀