Direct3D 10 でのシェーダーの使用
パイプラインには 3 つのシェーダー ステージがあり、それぞれが HLSL シェーダーでプログラムされます。 すべての Direct3D 10 シェーダーは HLSL で記述され、シェーダー モデル 4 を対象とします。
Direct3D 9 と Direct3D 10 の違い:
- 中間アセンブリ言語で作成できる Direct3D 9 シェーダー モデルとは異なり、シェーダー モデル 4.0 シェーダーは HLSL でのみ作成されます。 デバイスで使用できるバイトコードへのシェーダーのオフライン コンパイルは引き続きサポートされており、ほとんどのシナリオで推奨されます。
この例では、頂点シェーダーのみを使用します。 すべてのシェーダーは共通のシェーダー コアから構築されているため、頂点シェーダーの使用方法の学習は、ジオメトリシェーダーまたはピクセル シェーダーの使用とよく似ています。
HLSL シェーダーを作成したら (この例では頂点シェーダー HLSLWithoutFX.vsh を使用します)、それを使用する特定のパイプライン ステージ用に準備する必要があります。 これを行うには、次の操作を行う必要があります。
これらの手順は、パイプライン内のシェーダーごとに繰り返す必要があります。
シェーダーをコンパイルする
最初の手順では、シェーダーをコンパイルして、HLSL ステートメントを正しくコーディングしたことを確認チェック。 これを行うには、D3D10CompileShader を呼び出し、次に示すようにいくつかのパラメーターを指定します。
IPD3D10Blob * pBlob;
// Compile the vertex shader from the file
D3D10CompileShader( strPath, strlen( strPath ), "HLSLWithoutFX.vsh",
NULL, NULL, "Ripple", "vs_4_0", dwShaderFlags, &pBlob, NULL );
この関数は、次のパラメーターを受け取ります。
シェーダーを含むファイルの名前 ( と名前文字列の長さ (バイト単位)。 この例では、頂点シェーダーのみを使用します (HLSLWithoutFX.vsh ファイルでは、ファイル拡張子 .vsh は頂点シェーダーの省略形です)。
シェーダー関数名。 この例では、単一の入力を受け取り、出力構造体を返す Ripple 関数から頂点シェーダーをコンパイルします (関数は HLSLWithoutFX サンプルのものです)。
VS_OUTPUT Ripple( in float2 vPosition : POSITION )
シェーダーによって使用されるすべてのマクロへのポインター。 マクロの定義に役立つD3D10_SHADER_MACROを使用します。すべてのマクロ名 (各名前はスペースで区切られた名前) と定義文字列 (各マクロ本体がスペースで区切られた) を含む名前文字列を作成するだけです。 両方の文字列は NULL で終了する必要があります。
シェーダーをコンパイルするために含める必要がある他のファイルへのポインター。 これには、ユーザーが実装した 2 つのメソッドである Open と Close の ID3D10Include インターフェイスが使用されます。 この作業を行うには、Open メソッドと Close メソッドの本体を実装する必要があります。Open メソッドで、必要なインクルード ファイルを開くために使用するコードを追加します。Close 関数では、ファイルの使用が完了したらファイルを閉じるコードを追加します。
コンパイルするシェーダー関数の名前。 このシェーダーは、Ripple 関数をコンパイルします。
コンパイル時にターゲットにするシェーダー プロファイル。 関数を頂点、ジオメトリ、またはピクセル シェーダーにコンパイルできるため、プロファイルはコンパイラに対して、シェーダーの種類とコードを比較するシェーダー モデルを指示します。
シェーダー コンパイラ フラグ。 これらのフラグは、コンパイルされた出力に格納する情報と、出力コードを最適化する方法 (速度、デバッグなど) をコンパイラに通知します。使用可能なフラグの一覧については、「 Effect Constants (Direct3D 10)」 を参照してください。 このサンプルには、プロジェクトのコンパイラ フラグ値を設定するために使用できるコードが含まれています。これは主に、デバッグ情報を生成するかどうかの問題です。
コンパイルされたシェーダー コードを含むバッファーへのポインター。 バッファーには、コンパイラ フラグによって要求された埋め込みデバッグおよびシンボル テーブル情報も含まれます。
コンパイル中に発生したエラーと警告の一覧を含むバッファーへのポインター。これは、シェーダーのコンパイル中にデバッガーを実行している場合にデバッグ出力に表示されるメッセージと同じです。 エラー がバッファーに返されないようにする場合、NULL は許容される値です。
シェーダーが正常にコンパイルされると、シェーダー コードへのポインターが ID3D10Blob インターフェイスとして返されます。 これは、ポインターが DWORD の配列で構成されるメモリ内の場所へのポインターであるため、BLOB インターフェイスと呼ばれます。 インターフェイスは、次の手順で必要になるコンパイル済みシェーダーへのポインターを取得できるように提供されています。
2006 年 12 月の SDK 以降、DirectX 10 HLSL コンパイラが DirectX 9 と DirectX 10 の両方の既定のコンパイラになりました。 詳細については、 エフェクト コンパイラ ツール に関するページを参照してください。
コンパイル済みシェーダーへのポインターを取得する
いくつかの API メソッドでは、コンパイルされたシェーダーへのポインターが必要です。 この引数は通常、バイト コードのシーケンスとして表されるコンパイルされたシェーダーを指しているため、 pShaderBytecode と呼ばれます。 コンパイルされたシェーダーへのポインターを取得するには、まず D3D10CompileShader または同様の関数を呼び出してシェーダーをコンパイルします。 コンパイルが成功した場合、コンパイルされたシェーダーは ID3D10Blob インターフェイスで返されます。 最後に、 GetBufferPointer メソッドを使用してポインターを返します。
シェーダー オブジェクトを作成する
シェーダーがコンパイルされたら、CreateVertexShader を呼び出してシェーダー オブジェクトを作成します。
ID3D10VertexShader ** ppVertexShader
ID3D10Blob pBlob;
// Create the vertex shader
hr = pd3dDevice->CreateVertexShader( (DWORD*)pBlob->GetBufferPointer(),
pBlob->GetBufferSize(), &ppVertexShader );
// Release the pointer to the compiled shader once you are done with it
pBlob->Release();
シェーダー オブジェクトを作成するには、コンパイルされたシェーダーへのポインターを CreateVertexShader に渡します。 最初にシェーダーを正常にコンパイルする必要があったため、マシンにメモリの問題がない限り、この呼び出しはほぼ確実に成功します。
必要な数のシェーダー オブジェクトを作成し、単にそれらに対するポインターを保持できます。 この同じメカニズムは、シェーダー プロファイル (コンパイル メソッドを呼び出すとき) とインターフェイス名 (create メソッドを呼び出すとき) が一致することを前提として、ジオメトリ シェーダーとピクセル シェーダーに対して機能します。
シェーダー オブジェクトを設定する
最後の手順では、シェーダーをパイプライン ステージに設定します。 パイプラインには 3 つのシェーダー ステージがあるため、ステージごとに 1 つずつ、3 つの API 呼び出しを行う必要があります。
// Set a vertex shader
pd3dDevice->VSSetShader( g_pVS10 );
VSSetShader の呼び出しは、手順 1 で作成した頂点シェーダーへのポインターを受け取ります。 これにより、デバイスのシェーダーが設定されます。 頂点シェーダー ステージは頂点シェーダー コードで初期化されるようになりました。残っているのは、シェーダー変数を初期化することです。
3 つのシェーダー ステージすべてに対して繰り返す
これらの同じ一連の手順を繰り返して、頂点シェーダーまたはピクセル シェーダー、またはピクセル シェーダーに出力するジオメトリ シェーダーを構築します。