功能層級 9 硬體上的使用者裁剪平面
從Windows 8開始,Microsoft 高階著色器語言 (HLSL) 支援可與 Microsoft Direct3D 11 API 搭配使用的語法,以在功能層級9_x和更新版本上指定使用者裁剪平面。 您可以使用這個裁剪平面語法來撰寫著色器,然後使用該著色器物件搭配 Direct3D 11 API 在所有 Direct3D 功能層級上執行。
背景
您可以透過IDirect3DDevice9::SetClipPlane 和 IDirect3DDevice9::GetClipPlane方法存取 Microsoft Direct3D 9 API 中的使用者裁剪平面。 在 Microsoft Direct3D 10 和更新版本中,您可以透過 SV_ClipDistance 語意存取使用者裁剪平面。 但在Windows 8之前,SV_ClipDistance不適用於 Direct3D 10 或 Direct3D 11 API 中的功能層級9_x硬體。 因此,在Windows 8之前,存取具有功能層級9_x硬體的使用者裁剪平面的唯一方式是透過 Direct3D 9 API。 Direct3D Windows 市集應用程式無法使用 Direct3D 9 API。 在這裡,我們將說明您可以在功能層級上透過 Direct3D 11 API 存取使用者裁剪平面的語法9_x和更新版本。
應用程式會使用剪輯平面來定義 3D 世界內的一組不可見平面,讓裁剪 (擲回) 所有繪製的基本類型。 Windows 不會繪製任何位於任何裁剪平面負端的任何圖元。 應用程式接著可以使用裁剪平面來轉譯平面反射。
Syntax
使用此語法將裁剪平面宣告為 函式宣告中的函式屬性。 例如,我們在這裡使用頂點著色器片段上的語法:
cbuffer ClipPlaneConstantBuffer
{
float4 clipPlane1;
float4 clipPlane2;
};
[clipplanes(clipPlane1,clipPlane2)]
VertexShaderOutput main(VertexShaderInput input)
{
// the rest of the vertex shader doesn't refer to the clip plane
…
return output;
}
這個頂點著色器片段的範例代表兩個裁剪平面。 它會顯示您需要在頂點著色器的傳回值之前,立即將新的 裁剪平面 屬性放在方括弧內。 在 剪輯平面 屬性之後的括弧內,您提供最多 6 個 float4 常數的清單,以定義每個使用中剪輯平面的平面係數。 此範例也顯示,您必須讓每個平面的係數都位於常數緩衝區中。
注意
沒有語法可以動態停用裁剪平面。 您必須重新編譯沒有 裁剪平面 屬性的相同著色器,或者您的應用程式可以將常數緩衝區中的係數設定為零,讓平面不再影響任何幾何。
此語法適用于任何 4.0 或更新版本的頂點著色器目標,包括vs_4_0_level_9_1和vs_4_0_level_9_3。
在功能層級 9 和更高層級的裁剪空間中建立裁剪平面
在這裡,我們會示範如何在 功能層級 9_x和更新版本的剪輯空間中建立剪輯平面。
背景讀取
Frank D. Luna 將說明 3D 遊戲程式設計與 DirectX 10 簡介。Luna 會說明圖形數學背景 (章節 1、2 和 3 章) ,以及您在頂點著色器中發生的各種空間和空間轉換, (5.6 和 5.8 節) 。
10Level9 功能層級
在 Direct3D 10 和更新版本中,您可以裁剪任何有意義的空間,通常是在世界空間或檢視空間中。 但 Direct3D 9 使用裁剪空間,這是預先檢視方塊分割投影空間。 當頂點著色器將它們傳遞至 圖形管線中後續的階段時,向量會處於剪輯空間中。
當您撰寫 Windows 市集應用程式時,必須使用 10Level9 功能層級 (功能層級 9_x) ,讓應用程式可以在功能層級9_x和更高的硬體上執行。 因為您的應用程式支援功能層級9_x和更新版本,所以您也必須使用在剪輯空間中套用裁剪平面的常見功能。
當您使用vs_4_0_level_9_1或更新版本編譯頂點著色器時,該頂點著色器可以使用 剪輯平面 屬性。 Direct3D 10 或更新版本物件具有發出頂點的點乘積,其中包含屬性中指定的每個 float4 全域常數。 Direct3D 9 物件有足夠的中繼資料,導致 10Level9 執行時間發出 IDirect3DDevice9::SetClipPlane的適當呼叫。
裁剪平面數學
裁剪平面是由具有 4 個元件的向量所定義。 前三個元件會定義 x、y、z 向量,從我們想要裁剪的空間來源開始。 這個向量表示垂直于向量的平面,並透過原點執行。 Windows 會將所有圖元保留在平面的向量端,並裁剪平面後方的所有圖元。 第四個 w 元件會將平面推回,並讓 Windows 在負數下裁剪較少 (導致 Windows 沿著向量線裁剪更多) 。 如果 x、y、z 元件組成單位 (標準化) 向量,則 w 會將平面推回單位。
圖形處理單位 (GPU) 執行的數學是頂點向量 (x、y、z、1) 和裁剪平面向量之間的簡單點乘積。 此數學運算會在裁剪平面向量上建立投影長度。 負點產品會顯示頂點位於平面的裁剪端。
在檢視空間中裁剪
以下是檢視空間中的頂點:
以下是檢視空間中的裁剪平面:
以下是檢視空間中頂點和裁剪平面的點乘積:
ClipDistance = v •C = vₓCₓ +vyCy + vzCz + w
此數學運算適用于 Direct3D 10 或更新版本物件,但不適用於 Direct3D 9 物件。 針對 Direct3D 9,我們必須先將投影轉換轉換成剪輯空間。
投影矩陣
投影矩陣會從檢視空間轉換頂點, (其中原點是檢視器的眼睛,+x 是右邊的,+y 是向上,而 +z 會直接) 到剪輯空間中。 投影矩陣會讀取硬體裁剪和 點陣化階段的頂點。 以下是標準透視矩陣, (其他投影需要不同的數學) :
- *r* 視窗寬度/高度的比率 *α* 檢視角度 *f* 從檢視器到遠平面 *n* 距離從檢視器到接近平面
下一個矩陣是先前矩陣的簡化版本。 我們顯示簡化的矩陣,以便稍後在矩陣乘法中使用它。
現在,我們將檢視空間頂點轉換成矩陣乘以裁剪空間:
在我們的矩陣乘法運算中,我們的 x 和 y 元件只會稍微調整,但 z 和 w 元件相當繁衍。 我們的剪輯平面不會提供我們更多想要的內容。
裁剪空間裁剪平面
在這裡,我們想要建立剪輯空間剪輯平面,其點乘以我們的剪輯空間頂點產品提供我們與v 相同的值 ?[檢視空間中的裁剪]區段中的 C。
v •C = v P •CP
vₓCₓ +vyCy + vzCz + Cw = v ₓPₓCPₓ +vy + P y VzAyCZBCPz + vz + CPw
現在我們可以將上述數學運算分成四個不同的方程式:
我們的檢視空間剪輯平面和投影矩陣衍生,並提供我們的剪輯空間裁剪平面。
相關主題