Direct3D 轉換管線
本文提供 Direct3D 應用程式開發人員的技術說明,說明如何透過 Direct3D 矩陣的直接操作來設定 Direct3D 轉換管線的參數。
概觀
Direct3D 使用三個轉換在像素座標(螢幕空間)中變更您的 3D 模型座標。 這些轉換為世界轉換、檢視轉換和投影轉換。
世界轉換控制如何將模型座標轉換成全局座標。 世界轉換可以包含翻譯、旋轉和縮放比例,但不適用於光線。 如需使用世界轉換的詳細資訊,請參閱 世界轉換。
檢視轉換可控制從全局座標轉換到「相機空間」,決定世界相機位置。 如需使用檢視轉換的範例,請參閱 檢視轉換。
投影轉換會將相機空間的幾何變更為「裁剪空間」,並套用透視失真。 「裁剪空間」一詞是指幾何在此轉換期間如何裁剪至檢視磁片區。 如需使用投影轉換的範例,請參閱 投影轉換。
最後,裁剪空間中的幾何會轉換成圖元座標, (螢幕空間) 。 此轉換是由檢視區設定所控制。
裁剪和轉換頂點必須放在同質空間 (簡單來說,座標系統包含第四個元素的空間) ,但大部分應用程式的最終結果必須是非同質三維 (3D) 座標在「螢幕空間」中定義的非同質三維 (3D 座標。這表示輸入頂點和裁剪磁片區都必須轉譯成同質空間,才能執行裁剪,然後轉譯回要顯示的非同質空間。
三個 Direct3D 轉換世界、檢視和投影轉換是由 Direct3D 矩陣所定義。 Direct3D 矩陣是 D3DMATRIX 結構所定義的 4x4 同質矩陣。 雖然 Direct3D 矩陣不是標準物件,但它們不是以 COM 介面表示,但您可以建立和設定它們,就像任何其他 Direct3D 物件一樣。 如需 Direct3D 矩陣的詳細資訊,請參閱 轉換。
轉換管線
如果模型座標中的頂點是由 Pm = (Xm、Ym、Zm、1) 提供,則下圖中顯示的轉換會套用至計算螢幕座標 Ps = (Xs、Ys、Zs、Ws) 。
以下是上圖所示階段的描述:
世界矩陣 Mworld 會將頂點從模型空間轉換成世界空間。 此矩陣由下列方式設定:
d3dDevice->SetTransform (D3DTRANSFORMSTATE_WORLD, matrix address)
Direct3D 實作假設此矩陣的最後一個資料行是 (0、0、0、1) 。 如果使用者指定具有不同最後一個資料行的矩陣,則不會傳回任何錯誤,但光源和照明將會不正確。
檢視矩陣 Mview 會將頂點從世界空間轉換成相機空間。 此矩陣由下列方式設定:
d3dDevice->SetTransform (D3DTRANSFORMSTATE_VIEW, matrix address)
Direct3D 實作假設此矩陣的最後一個資料行是 (0、0、0、1) 。 如果使用者指定具有不同最後一個資料行的矩陣,但光源和照明將會不正確,則不會傳回任何錯誤。
投影矩陣 Mproj 會將頂點從相機空間轉換成投影空間。 此矩陣由下列方式設定:
d3dDevice->SetTransform (D3DTRANSFORMSTATE_PROJECTION, matrix address)
投影矩陣的最後一個資料行應該 (0、0、1、0) 或 (0、0、a、0) ,以取得正確的光源和光源效果;慣用 (0、0、1、0) 表單。
投影空間中所有點 Xp = (Xp、Yp、Zp、Wp) 的裁剪音量定義為:
-Wp < Xp <= Wp -Wp < Yp <= Wp 0 < Zp <= Wp
不符合這些方程式的所有點都會被裁剪。
如果檢視磁片區定義為:
- 在接近裁剪平面的相機空間中旋轉螢幕視窗寬度
- 在接近裁剪平面的相機空間中,螢幕視窗高度
- 與相機空間中 Z 軸接近裁剪平面的 Zn 距離
- 在相機空間中沿著 Z 軸與遠距裁剪平面的 Zf 距離
然後,可以撰寫透視投影矩陣,如下所示:
其中 Mij 是 Mproj 的成員。
針對正交投影,我們有:
Direct3D 假設透視投影矩陣的格式如下:
如果透視投影矩陣沒有這種形式,將會有一些成品。 例如,資料表霧將無法運作。
Direct3D 可讓使用者變更剪輯音量,如下所示:
這可以重寫為:
其中:
Cx, Cy - dvClipX, dvClipY from D3DVIEWPORT9 Cw, Ch - dvClipWidth, dvClipHeight from D3DVIEWPORT9 Zmin, Zmax - dvMinZ, dvMaxZ from D3DVIEWPORT9
此轉換可以提供更高的精確度,相當於調整和移動裁剪磁片區。
對應的 Mclip 矩陣為:
頂點會由:
dvClipWidth = 2 dvClipHeight = 2 dvClipX = -1 dvClipY = 1 dvMinZ = 0 dvMaxZ = 1
如果您不想調整剪輯磁片區,您可以將檢視區參數設定為預設值:
(Xc, Yc, Zc, Wc) = (Xp, Yp, Zp, Wp) * Mclip
如果使用者在 DrawPrimitive 呼叫中指定D3DDP_DONOTCLIP旗標,則裁剪階段是選擇性的。 在此情況下,可以合併所有矩陣 (包括 Mvs) 。
檢視區刻度矩陣 Mvs 會縮放檢視區視窗內的座標,並將 Y 軸從上下翻轉:
其中:
dwX, dwY - viewport offsets in pixels from D3DVIEWPORT9 dwWidth, dwHeight - viewport width and height in pixels from D3DVIEWPORT9
最後,螢幕座標會計算並傳遞至轉譯器:
使用秘訣
以下是如何使用 Direct3D 轉換管線的一些秘訣:
世界和檢視矩陣的最後一個資料行應該 (0、0、0、1) 或光源不正確。
設定檢視區參數以建置身分識別 Mclip 矩陣,除非您確實瞭解所需的內容。
dvClipWidth = 2 dvClipHeight = 2 dvClipX = -1 dvClipY = 1 dvMinZ = 0 dvMaxZ = 1