跳轉到內容

GLSL 程式設計/光柵化

來自華夏公益教科書

光柵化是 OpenGL(ES)2.0 管線 的一個階段,它確定由一個圖元(例如三角形)覆蓋的畫素,併為每個覆蓋的畫素插值頂點著色器的輸出變數(即變化變數和深度)。這些插值的變化變數和插值深度隨後傳遞給片段著色器。(從更廣泛的意義上說,“光柵化”還包括執行片段著色器和 每個片段操作。)

通常,GLSL 程式設計師不需要了解光柵化階段的更多細節,而只需要瞭解上一段描述的這些內容。然而,瞭解一些細節對於理解透視正確插值等功能以及頂點著色器計算的頂點位置第四個分量的作用很有幫助。對於計算機圖形學中的一些高階演算法,也需要了解光柵化過程的一些細節。

光柵化的主要兩個部分是

  • 確定被一個圖元(例如三角形)覆蓋的畫素
  • 對所有覆蓋的畫素進行變化變數和深度的線性插值
被三角形覆蓋的畫素。

確定覆蓋的畫素

[編輯 | 編輯原始碼]

在 OpenGL(ES)中,幀緩衝區的一個畫素被定義為被一個圖元覆蓋,如果畫素的中心被該圖元覆蓋,如右圖所示。

當一個畫素的中心恰好在圖元邊界上時,有一些特定的規則。這些規則確保兩個相鄰三角形(即共享一條邊的三角形)永遠不會共享任何畫素(除非它們實際上重疊),並且不會漏掉邊上的任何畫素;也就是說,邊上每個畫素都被這兩個相鄰三角形中的一個覆蓋,而不是同時被兩個覆蓋。這對於避免孔洞和(在半透明三角形的情況下)對同一個畫素進行多次光柵化非常重要。但是,這些規則是特定於 GPU 實現的,因此在這裡不做討論。

用於插值變化變數的三角形區域。

變化變數的線性插值

[編輯 | 編輯原始碼]

一旦確定了所有覆蓋的畫素,就需要為每個畫素插值變化變數。為了簡單起見,我們只討論三角形的情況。(一條線就像一個有兩個頂點位於相同位置的三角形。)

對於每個三角形,頂點著色器計算三個頂點的位置。在右圖中,這些位置被標記為 ,和 。頂點著色器還計算每個頂點上變化變數的值。我們把其中一個變量表示為 ,和 。請注意,這些值指的是在不同頂點計算的同一個變化變數。我們要插值變化變數的畫素中心的座標在圖中用 表示。

我們想從三個頂點上的值 ,和 計算畫素中心 的一個新的插值值 。有多種方法可以做到這一點。一種方法是使用重心座標 ,和 ,它們以這種方式計算

三角形面積 , , 也在圖中顯示。在三維空間(或二維空間加上一個額外的第三維)中,三個點 , , 之間的三角形面積可以計算為向量叉積長度的一半

使用重心座標 ,在點 進行插值,根據三個頂點上的值 是很容易的。

透過這種方式,所有變化的變數都可以對所有覆蓋的畫素進行線性插值。

透視不正確紋理座標插值(標記為“仿射”)和透視正確插值(標記為“正確”)的比較。

透視正確插值變化的變數

[edit | edit source]

如果將上一節中描述的插值應用於使用透視投影的場景,可能會導致某些失真。為了透視正確插值,視點到距離放在三個頂點位置的第四個分量中 (),並且使用以下公式進行插值

因此,頂點位置的第四個分量對於透視正確插值變化的變數很重要。因此,透視除法(將第四個分量設定為 1)在頂點著色器中不執行也很重要,否則在透視投影的情況下插值將不正確。(此外,在某些情況下剪裁會失敗。)

需要注意的是,實際的 OpenGL 實現不太可能實現完全相同的過程,因為存在更有效的技術。但是,所有透視正確的線性插值方法都會得出相同的插值結果。

進一步閱讀

[編輯 | 編輯原始碼]

有關 OpenGL ES 光柵化的所有詳細資訊,在“Khronos OpenGL ES API 登錄檔”中的“OpenGL ES 2.0.x 規範”第 3 章中進行了完整詳細的定義。 “Khronos OpenGL ES API 登錄檔”


< GLSL 程式設計

除非另有說明,否則本頁上的所有示例原始碼均歸屬公共領域。
華夏公益教科書