機能レベル 9 ハードウェア上のユーザー クリップ プレーン
Windows 8以降、Microsoft High Level Shader Language (HLSL) では、Microsoft Direct3D 11 API で使用して、機能レベルの9_x以降のユーザー クリップ プレーンを指定できる構文がサポートされています。 このクリップ プレーン構文を使用してシェーダーを記述し、Direct3D 11 API でそのシェーダー オブジェクトを使用して、すべての Direct3D 機能レベルで実行できます。
背景
Microsoft Direct3D 9 API のユーザー クリップ プレーンには 、IDirect3DDevice9::SetClipPlane メソッドと IDirect3DDevice9::GetClipPlane メソッドを使用してアクセスできます。 Microsoft Direct3D 10 以降では、 SV_ClipDistance セマンティックを介してユーザー クリップ プレーンにアクセスできます。 ただし、Windows 8より前は、Direct3D 10 または Direct3D 11 API の機能レベル9_xハードウェアでは、SV_ClipDistanceを使用できませんでした。 そのため、Windows 8する前に、ハードウェア9_x機能レベルでユーザー クリップ プレーンにアクセスする唯一の方法は、Direct3D 9 API を使用することでした。 Direct3D Windows ストア アプリでは、Direct3D 9 API を使用できません。 ここでは、機能レベル 9_x 以降の Direct3D 11 API を介してユーザー クリップ プレーンにアクセスするために使用できる構文について説明します。
アプリでは、クリップ 平面を使用して、描画されたすべてのプリミティブをクリップ (捨てる) 3D ワールド内の非表示の平面のセットを定義します。 Windows では、クリッププレーンの負の側にあるピクセルは描画されません。 その後、アプリはクリッププレーンを使用して平面反射をレンダリングできます。
構文
この構文を使用して、クリップ プレーンを関数宣言の関数属性として 宣言します。 たとえば、ここでは頂点シェーダー フラグメントの構文を使用します。
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;
}
頂点シェーダー フラグメントのこの例は、2 つのクリッププレーンを表します。 頂点シェーダーの戻り値の直前に、新しい clipplanes 属性を角かっこ内に配置する必要があることを示します。 clipplanes 属性の後のかっこ内に、アクティブな各クリップ プレーンの平面係数を定義する最大 6 つの float4 定数のリストを指定します。 この例では、各平面の係数を定数バッファーに配置する必要があることも示しています。
注意
クリップ プレーンを動的に無効にする構文はありません。 それ以外の場合は、 clipplanes 属性を持たない同一のシェーダーを再コンパイルする必要があります。または、アプリで定数バッファーの係数を 0 に設定して、プレーンがジオメトリに影響を与えないようにすることができます。
この構文は、vs_4_0_level_9_1とvs_4_0_level_9_3を含む 4.0 以降の頂点シェーダー ターゲットで使用できます。
フィーチャー レベル 9 以降のクリップ空間にクリップ プレーンを作成する
ここでは、 フィーチャ レベル 9_x 以降のクリップ空間にクリップ プレーンを作成する方法について説明します。
バックグラウンド読み取り
Frank D. Luna の「DirectX 10 を使用した 3D ゲーム プログラミングの概要」では、必要なグラフィックス計算の背景 (第 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 以降を使用して頂点シェーダーをコンパイルすると、その頂点シェーダーで clipplanes 属性を使用できます。 Direct3D 10 以降のオブジェクトには、出力された頂点のドット積があり、 属性で指定された 各 float4 グローバル定数が含まれています。 Direct3D 9 オブジェクトには、10Level9 ランタイムが IDirect3DDevice9::SetClipPlane への適切な呼び出しを発行するのに十分なメタデータがあります。
クリップ 平面の数式
クリップ プレーンは、4 つのコンポーネントを持つベクターによって定義されます。 最初の 3 つのコンポーネントは、クリップする空間内の原点から発生する x、y、z ベクトルを定義します。 このベクトルは、ベクトルに垂直な平面を意味し、原点を通って実行されます。 Windows では、平面のベクター側にすべてのピクセルが保持され、プレーンの背後にあるすべてのピクセルがクリップされます。 4 つ目の w コンポーネントは平面を押し戻し、ベクトル線に沿って Windows のクリップが少なくなります (負の w の場合、Windows はクリップを増やします)。 x、y、z 成分が単位 (正規化された) ベクトルを構成する場合、w は平面 w 単位を押し戻します。
グラフィックス処理装置 (GPU) がクリッピングを決定するために実行する演算は、頂点ベクトル (x、y、z、1) とクリッピング 平面ベクトルの間の単純なドット積です。 この演算により、クリップ 平面ベクトルに投影長が作成されます。 負のドット積は、平面のクリップ側にある頂点を示します。
ビュー領域でのクリッピング
ビュー空間の頂点を次に示します。
ビュー空間内のクリップ プレーンを次に示します。
ビュー空間内の頂点とクリッププレーンのドット積を次に示します。
ClipDistance = v · C = vₓCₓ +vyCy + vzCz + Cw
この数値演算は、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ₓ +vyPyCP y P y + vzAyCPz + BCPz + z zCPw
これで、前の数式演算を頂点コンポーネントで分割し、次の 4 つの独立した数式に分割できます。
ビュースペースクリッププレーンとプロジェクションマトリックスは、クリップスペースクリッププレーンを派生させ、提供します。
関連トピック