Direct3D 10 でのシェーダーの使用

パイプラインには、3 つのシェーダー ステージがあり、それぞれが HLSL シェーダーでプログラミングされます。Direct3D 10 シェーダーはすべて HLSL で記述され、シェーダー モデル 4 をターゲットとします。

Direct3D 9 と Direct3D 10 の違い

中間アセンブリ言語で作成できる Direct3D 9 シェーダー モデルとは異なり、シェーダー モデル 4.0 のシェーダーは、HLSL のみで作成されます。デバイスで消費できるバイトコードへのシェーダーのオフライン コンパイルは、変わらずサポートされています。ほとんどの場合で推奨されます。

この例では、頂点シェーダーのみ使用しています。すべてのシェーダーは共通のシェーダー コアからビルトされているため、頂点シェーダーの使い方は、ジオメトリ シェーダーやピクセル シェーダーの使い方とよく似ています。

いったん HLSL シェーダーを作成すると (この例では、頂点シェーダー HLSLWithoutFX.vsh を使用)、これを使用する特定のパイプライン ステージ用に準備する必要があります。これには、次を行う必要があります。

  • シェーダーのコンパイル
  • シェーダー オブジェクトの作成
  • シェーダー オブジェクトの設定
  • 3 つのシェーダー ステージすべてに繰り返す

これらの手順は、パイプラインのシェーダーごとに繰り返す必要があります。

シェーダーのコンパイル

この最初の手順は、シェーダーをコンパイルし、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 ); 

この関数は、次のパラメーターを取得します。

  • シェーダーを含むファイル名 (およびバイト単位の名前文字列の長さ)。この例では、頂点シェーダーのみを使用しています (ファイルの拡張子 .vsh が頂点シェーダーの略である HLSLWithoutFX.vsh ファイル の)。

  • シェーダー関数名。この例では、Ripple 関数からの頂点シェーダーをコンパイルします。この関数は単一の入力を取得して、出力 struct を返します (関数は HLSLWithoutFX サンプルのもの)。

     VS_OUTPUT Ripple( in float2 vPosition : POSITION ) 
    
  • シェーダーによって使用されるすべてのマクロへのポインター。D3D10_SHADER_MACRO を使用すると、マクロを簡単に定義できます。すべてのマクロ名を含む名前文字列を作成するだけです (各名前はスペースで区切る)。両方の文字列は NULL で終了する必要があります。

  • シェーダーをコンパイルするために含める必要があるその他のファイルへのポインター。このポインターは、ID3D10Include インターフェイスを使用します。このインターフェイスは次の 2 つのユーザー実装メソッドを持ちます。Open と Close。これを有効にするには、Open メソッドと Close メソッドの本体を実装する必要があります。Open メソッドでは、必要なあらゆるインクルード ファイルを開くために使用するコードを追加し、Close 関数は作業の終わったファイルを閉じるコードを追加します。

  • コンパイルするシェーダー関数の名前。このシェーダーは、Ripple 関数をコンパイルします。

  • コンパイル時にターゲットとするシェーダー プロファイル。関数を頂点、ジオメトリ、またはピクセル シェーダーにコンパイルできるため、プロファイルによってコンパイラは、どのタイプのシェーダーおよびどのシェーダー モデルをコードと比較するのかを知ります。

  • シェーダー コンパイル フラグ。これらのフラグは、コンパイラに対して、どのような情報をコンパイル済み出力として扱うのか、およびどのような点 (速度やデバッグなど) を考慮して出力コードを最適化するのかを指定します。使用可能なフラグのリストについては、「エフェクト定数 (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 に渡します。まずは、シェーダーを正常にコンパイルしなければならないため、この呼び出しは確実に渡されます。ただし、マシンにメモリー上の問題がある場合を除きます。

シェーダー オブジェクトは好きなだけ作成でき、シェーダー オブジェクトへのポインターを追跡できます。シェーダー プロファイル (コンパイル メソッドの呼び出し時の) とインターフェイス名 (作成メソッドの呼び出し時の) を 一致させていれば、これと同じメカニズムは、ジオメトリ シェーダーとピクセル シェーダーにも有効です。

シェーダー オブジェクトの設定

最後の手順は、シェーダーをパイプライン ステージに設定することです。パイプラインには 3 つのシェーダー ステージがあるため、ステージごとに 1 つ、合わせて 3 つの API 呼び出しを作成する必要があります。

     // Set a vertex shader     pd3dDevice->VSSetShader( g_pVS10 ); 

VSSetShader の呼び出しでは、手順 1 で作成した頂点シェーダーへのポインターが取得されます。これはシェーダーをデバイスに設定します。頂点シェーダーのステージは、その頂点シェーダー コードで初期化されています。残りはすべてシェーダー変数を初期化します。

3 つのシェーダー ステージすべてに繰り返す

頂点シェーダーまたはピクセル シェーダー、または、ピクセル シェーダーに出力するジオメトリ シェーダーをビルトするには、上記と同じ手順を繰り返します。

関連トピック

シェーダーのコンパイル