Cg 程式設計/可程式設計圖形管道
這裡介紹的可程式設計圖形管道與 OpenGL (ES) 2.0 管道、WebGL 管道和 Direct3D 8.0 管道非常相似。因此,它是當今大多數臺式電腦和移動裝置的可程式設計圖形管道的最低公分母。
GPU 是高度並行的處理器。這是它們效能的主要原因。事實上,它們實現了兩種並行性:垂直並行和水平並行。

- 垂直並行描述了在管道不同階段進行並行處理。這個概念在福特汽車公司的裝配線發展中也至關重要:許多工人可以在相對簡單的任務上並行工作。這使得大規模生產(因此也使得大規模消費)成為可能。在 GPU 處理單元的上下文中,簡單任務對應於不太複雜的處理單元,這可以節省成本和功耗。

- 水平並行描述了在多個管道中處理工作的可能性。這允許比單個管道中的垂直並行實現更多的並行。同樣,這個概念也應用於福特汽車公司和其他許多行業。在 GPU 的上下文中,圖形管道的水平並行是實現現代 GPU 效能的重要特徵。
下圖展示了垂直並行(以方框表示的階段處理)和水平並行(以方框之間的多個箭頭表示的每個階段的多個處理單元)的說明。
| 頂點資料 | 例如,由 3D 建模工具提供的三角形網格 | |||
| ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ | 許多頂點並行處理 | |||
| 頂點著色器 | 一個小的 Cg 程式(或其他著色語言)應用於每個頂點 | |||
| ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ | ||||
| 圖元裝配 | 設定圖元,例如三角形、線條和點 | |||
| ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ | 許多圖元並行處理 | |||
| 光柵化 | 對圖元(例如三角形)覆蓋的所有畫素進行資料的插值 | |||
| ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ | 許多片段(對應於畫素)並行處理 | |||
| 片段著色器 | 一個小的 Cg 程式(或其他著色語言)應用於每個片段(即覆蓋的畫素) | |||
| ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ | ||||
| 每片段操作 | 對每個片段(即覆蓋的畫素)進行可配置操作 | |||
| ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ | 許多片段的結果並行寫入幀緩衝區 | |||
| 幀緩衝區 | 儲存計算出的片段顏色的畫素陣列 | |||
在下圖中,任何兩個階段之間只有一個箭頭。但是,應該理解的是,GPU 通常以大規模的水平並行實現圖形管道。只有圖形管道的軟體實現,例如 Mesa 3D (參見維基百科條目),通常實現單個管道。
OpenGL ES 1.x、核心 OpenGL 1.x 和 Direct3D 7.x 的管道是可配置的固定功能管道,即無法在這些管道中包含程式。在 OpenGL (ES) 2.0、WebGL 和 Direct3D 8.0 中,管道的兩個階段(頂點著色器和片段著色器階段)是可程式設計的,即在這些階段應用了用 Cg(或其他著色語言)編寫的程式(著色器)。在下圖中,可程式設計階段以綠色方框表示,固定功能階段以灰色方框表示,資料以藍色方框表示。
| 頂點資料 | 例如,由 3D 建模工具提供的三角形網格 | |||
| ↓ | ||||
| 頂點著色器 | 一個小的 Cg 程式應用於每個頂點 | |||
| ↓ | ||||
| 圖元裝配 | 設定圖元,例如三角形、線條和點 | |||
| ↓ | ||||
| 光柵化 | 對圖元覆蓋的所有畫素進行資料的插值(例如顏色) | |||
| ↓ | ||||
| 片段著色器 | 一個小的 Cg 程式應用於每個片段(即覆蓋的畫素) | |||
| ↓ | ||||
| 每片段操作 | 對每個片段(即覆蓋的畫素)進行可配置操作 | |||
| ↓ | ||||
| 幀緩衝區 | 儲存計算出的片段顏色的畫素陣列 | |||
頂點著色器和片段著色器階段將在特定平臺教程中更詳細地討論。光柵化階段在“光柵化”部分中進行討論,每片段操作在“每片段操作”部分中進行討論。
圖元裝配階段主要包括將圖元裁剪到視錐體(螢幕上可見的空間部分)以及可選的對正面和/或背面圖元的剔除。這些可能性將在特定平臺教程中更詳細地討論。
為了對 Cg 頂點和片段著色器進行程式設計,理解每個著色器的輸入和輸出非常重要。為此,瞭解資料如何在管道的各個階段之間進行通訊也很有用。這在下圖中進行了說明
| 頂點資料 | ||||
| ↓ | 帶有語義的頂點輸入引數(例如 POSITION、COLOR、NORMAL、TEXCOORD0、TEXCOORD1 等) | |||
| 頂點著色器 | ← | 統一引數;在某些情況下,紋理資料(影像) | ||
| ↓ | 帶有語義的頂點輸出引數(特別是 POSITION、SV_POSITION 和 PSIZE,但也包括 COLOR、TEXCOORD0、TEXCOORD1 等) | |||
| 圖元裝配 | ||||
| ↓ | 頂點輸出引數 | |||
| 光柵化 | ||||
| ↓ | 片段輸入引數(在畫素上插值),帶有語義(對應於頂點輸出引數的語義) | |||
| 片段著色器 | ← | 統一引數(每個圖元都恆定)和紋理資料 | ||
| ↓ | 帶有語義的片段輸出引數(特別是 COLOR 和 DEPTH) | |||
| 每片段操作 | ||||
| ↓ | 片段顏色和片段深度 | |||
| 幀緩衝區 | ||||
頂點輸入引數是根據頂點資料定義的。對於每個頂點輸入引數,必須定義一個語義,它指定引數如何與固定功能管道中的資料相關。語義的例子有 POSITION、COLOR、NORMAL、TEXCOORD0、TEXCOORD1 等。這使得即使使用最初為固定功能管道設計的 API 也可以使用 Cg 程式。例如,頂點位置的頂點輸入引數應該使用 POSITION 語義,以便所有 API 都可以為此輸入引數提供適當的資料。請注意,頂點位置位於物件座標系中,即這是在 3D 建模工具中指定的座標。
統一引數(或制服)對於渲染特定圖元(例如三角形)時執行的所有頂點著色器和所有片段著色器具有相同的值。但是,它們可以針對其他圖元進行更改。通常,它們對構成網格的大量圖元集具有相同的值。通常,頂點變換、光源和材料的規範等被指定為制服。
頂點輸出引數由頂點著色器計算,即每個頂點有一組這些引數的值。必須為每個引數指定一個語義,例如 POSITION、SV_POSITION、COLOR、TEXCOORD0、TEXCOORD1 等。通常,必須有一個具有 POSITION 或 SV_POSITION 語義的輸出引數,它決定了圖元在螢幕上的渲染位置(“SV” 代表“系統值”,可以具有特殊含義)。點圖元的大小可以透過具有 PSIZE 語義的輸出引數來指定。其他引數將針對圖元覆蓋的每個畫素進行插值(參見“光柵化”部分)。
片段輸入引數是從頂點輸出引數插值到圖元覆蓋的每個畫素的。類似於頂點輸出引數,必須為每個片段輸入引數指定一個語義。這些語義用於將頂點輸出引數與片段輸入引數匹配。因此,頂點著色器和片段著色器中對應引數的名稱可以不同,只要語義相同即可。
片段輸出引數由片段著色器計算。必須指定一個語義,它決定了該值在以下固定功能管道中的使用方式。大多數片段著色器都指定了一個具有 COLOR 語義的輸出引數。即使沒有指定具有 DEPTH 語義的輸出引數,片段深度也是隱式計算的。
紋理資料包括一個統一取樣器,它指定紋理取樣單元,而紋理取樣單元又指定從中獲取顏色的紋理影像。
其他資料在特定平臺的教程中進行描述。
Cg 使用的可程式設計圖形管道模型在Nvidia 的 Cg 教程的第一章中進行了描述。
< Cg 程式設計