シェーダー ステージ (Direct3D 10)

Direct3D 10 のパイプラインには、3 つのプログラム可能なシェーダー ステージ (パイプライン機能図の長円のブロック) があります。

  • 頂点シェーダー ステージ
  • ジオメトリ シェーダー ステージ
  • ピクセル シェーダー ステージ

シェーダー モデル 4.0 共通シェーダー コアで構築された各シェーダー ステージには、それぞれ固有の機能があります。

頂点シェーダー ステージ

頂点シェーダー (VS) ステージでは、入力アセンブラーからの頂点が処理され、トランスフォーム、スキニング、モーフ、頂点単位のライティングなど、頂点単位の処理が実行されます。頂点シェーダーは、常に 1 つの入力頂点を処理し、1 つの出力頂点を生成します。パイプラインを実行するには、頂点シェーダー ステージが常にアクティブでなければなりません。頂点の変更やトランスフォームが不要な場合は、パススルー頂点シェーダーを作成し、パイプラインに設定する必要があります。

頂点シェーダーの各入力頂点は、最大 16 の 32 ビット ベクトル (それぞれ最大 4 成分) で構成でき、各出力頂点も同様に 16 の 32 ビット、4 成分ベクトルで構成できます。すべての頂点シェーダーには、1 つのスカラー値を構成可能な 1 つの入力と 1 つの出力が最低でも必要です。

頂点シェーダー ステージでは、入力アセンブラーからの 2 つのシステム生成値を使用できます。それらは VertexID と InstanceID です (システム値とセマンティクスについての説明を参照してください)。VertexID と InstanceID はどちらも頂点レベルで有意であり、ハードウェアによって生成された ID を渡すことができるのは、それらを認識する最初のステージのみなので、これらの ID 値は頂点シェーダー ステージにしか渡すことができません。

頂点シェーダーは常にすべての頂点に対して実行され、これには隣接性がある入力プリミティブ トポロジの隣接頂点も含まれます。頂点シェーダーが実行された回数は、VSInvocations パイプライン統計を使用して、CPU からクエリできます。

頂点シェーダーでは、スクリーン空間の微分を必要としないロードおよびテクスチャー サンプリング処理を実行できます (HLSL 組み込み関数のSample (DirectX HLSL テクスチャー オブジェクト)SampleCmpLevelZero (DirectX HLSL テクスチャー オブジェクト)、および SampleGrad (DirectX HLSL テクスチャー オブジェクト) を使用)。

ジオメトリ シェーダー ステージ

ジオメトリ シェーダー (GS) ステージでは、アプリケーション指定のシェーダー コードが、入力となる複数の頂点に対して実行されます。また、出力では頂点を生成することができます。1 つの頂点を処理する頂点シェーダーとは異なり、ジオメトリ シェーダーの入力はプリミティブ全体 (線の 2 つの頂点、三角形の 3 つの頂点、点の 1 つの頂点など) の複数の頂点です。また、ジオメトリ シェーダーでは、エッジ隣接プリミティブの頂点データを入力として受け取ることができます (線の場合は追加の 2 つの頂点、三角形の場合は追加の 3 つの頂点)。次の図は、隣接頂点がある三角形と直線を示したものです。

Ee415747.d3d10_gs(ja-jp,VS.85).png

TV 三角形頂点
AV 隣接頂点
LV 線頂点

ジオメトリ シェーダー ステージでは、IA によって自動的に生成されたシステム生成値である SV_PrimitiveID を使用できます。これにより、必要に応じて、プリミティブ単位のデータをフェッチまたは計算することができます。

ジオメトリ シェーダー ステージでは、複数の頂点を出力して、選択された 1 つのトポロジを形成できます (GS ステージの出力トポロジには、TriStrip、LineStrip、および PointList があります)。生成されるプリミティブの数は、ジオメトリ シェーダーの呼び出し内で自由に変えることができますが、生成可能な頂点の最大数は、静的に宣言する必要があります。ジオメトリ シェーダーの呼び出しから生成されるストリップの長さは任意で、新しいストリップは RestartStrip HLSL 組み込み関数を使用して作成できます。

ジオメトリ シェーダーの出力は、ラスタライザー ステージに渡すか、ストリーム出力ステージでメモリー内の頂点バッファーに渡すか、またはこれら両方に渡すことができます。メモリーに渡された出力は、個別の点/線/三角形のリストに展開されます (ラスタライザーに渡されるときと同じように正確に展開されます)。

ジオメトリ シェーダーがアクティブな場合、前にパイプラインから渡された、またはパイプラインで生成されたプリミティブごとに 1 回ずつ呼び出されます。ジオメトリ シェーダーの呼び出しのたびに、入力となるプリミティブのデータが 1 つの点、1 つの線、または 1 つの三角形のいずれになるか確認されます。前にパイプラインで生成された三角形ストリップでは、ストリップ内の三角形ごとにジオメトリ シェーダーが呼び出されます (ストリップが三角形リストに展開されている場合と同様になります)。個々のプリミティブ内の各頂点のすべての入力データが利用可能なほか (三角形の場合は 3 つの頂点)、隣接頂点のデータも利用可能です (該当する場合/可能な場合)。

ジオメトリ シェーダーは、頂点を出力ストリーム オブジェクトに追加することで 1 つの頂点ごとにデータを出力します。ストリームのトポロジは、固定された宣言によって決定され、GS ステージの出力として PointStream、LineStream、または TriangleStream のいずれかを選択します。利用可能なストリーム オブジェクトには PointStream、LineStream、および TriangleStream の 3 種類があり、これらはすべてテンプレート化されたオブジェクトです。出力のトポロジはそれぞれのオブジェクト タイプによって決定され、ストリームに追加される頂点のフォーマットはテンプレート タイプによって決定されます。ジオメトリ シェーダー インスタンスの実行は、ストリームに追加されるデータがシリアルであることを除き、他の呼び出しから分割することはできません。ジオメトリ シェーダーの特定の呼び出しの出力は、他の呼び出しから独立しています (ただし、順序は考慮されます)。三角形ストリップを生成するジオメトリ シェーダーは、すべての呼び出しで新しいストリップを開始します。

ジオメトリ シェーダー出力が、システム解釈値 (たとえば、SV_RenderTargetArrayIndex や SV_Position) として識別されると、ハードウェアは、データ自体を次のシェーダー ステージに入力として渡すほか、このデータを参照し、その値に応じて特定の動作を実行します。ジオメトリ シェーダーから出力されたこのようなデータが、頂点単位ではなく (SV_ClipDistance[n] や SV_Position など)、プリミティブ単位で (SV_RenderTargetArrayIndex や SV_ViewportArrayIndex など) ハードウェアに対して有意な場合、プリミティブに対して生成された最初の頂点からプリミティブ単位のデータが取得されます。

ジオメトリ シェーダーが終了し、プリミティブが不完全な場合、部分的に終了したプリミティブをジオメトリ シェーダーによって生成することができます。不完全なプリミティブは、自動的に破棄されます。これは、部分的に終了したプリミティブを IA が処理する方法に似ています。

ジオメトリ シェーダーは、スクリーン空間の微分を必要としないロードおよびテクスチャー サンプリング処理を実行できます (SampleLevel、SampleCmpLevelZero、SampleGrad)。

ジオメトリ シェーダーには次のアルゴリズムを実装できます。

  • ポイント スプライトの展開
  • 動的なパーティクル システム
  • Fur/Fin の生成
  • シャドウ ボリュームの生成
  • 単一パスのキューブマップへのレンダリング
  • プリミティブ単位のマテリアル スワッピング
  • プリミティブ単位のマテリアル セットアップ - これにはプリミティブ データとしての重心座標の生成も含まれます。これにより、ピクセル シェーダーでカスタム属性の補間 (高次の法線補間など。「CubeMapGS サンプル」を参照) を実行できます。

ピクセル シェーダー ステージ

ピクセル シェーダー ステージ (PS) では、ピクセル単位のライティングやポストプロセッシングなど、多彩なシェーディング テクニックを使用することができます。ピクセル シェーダーは、定数変数、テクスチャー データ、補間された頂点単位の値などのデータを結合して、ピクセル単位の出力を生成するプログラムです。ラスタライザー ステージでは、プリミティブによってカバーされたピクセルごとにピクセル シェーダーが 1 回呼び出されます。また、NULL シェーダーを指定して、シェーダーの実行を無効にすることもできます。

テクスチャーのマルチサンプリング時には、カバーされたピクセルごとに 1 回ピクセル シェーダーが呼び出され、カバーされた各マルチサンプルについて深度/ステンシル テストが発生します。深度/ステンシル テストに合格したサンプルは、ピクセル シェーダーの出力カラーで更新されます。

ピクセル シェーダーの組み込み関数は、スクリーン空間 x および y に対して数量の微分を生成するか、または使用します。微分の最も一般的な用途は、テクスチャー サンプリングの詳細レベルの計算や、異方性フィルタリングにおける異方性の軸に沿ったサンプルの選択などです。通常、ハードウェアの実装では、複数のピクセル (たとえば 2x2 グリッド) に対して同時にピクセル シェーダーが実行され、ピクセル シェーダーで計算された数値の微分を、同じ実行時点における値のデルタとして隣接ピクセルで適切に近似させることができます。

入力

パイプラインがジオメトリ シェーダーなしに構成されているとき、ピクセル シェーダーは 16 の 32 ビット、4 成分の入力に制限されます。それ以外の場合、ピクセル シェーダーは 32 ビット、4 成分の入力を 32 まで取得できます。

ピクセル シェーダーの入力データには (パースペクティブ補正あり/なしで補間可能な) 頂点属性が含まれます。また、ピクセル シェーダーの入力データをプリミティブ単位の定数として処理することもできます。ピクセル シェーダー入力は、宣言された補間モードに基づいて、ラスター化されるプリミティブの頂点属性から補間されます。プリミティブがラスター化前にクリッピングされる場合、クリッピング処理時に補間モードも受け入れられます。

頂点属性は、ピクセル シェーダーの中心の位置で補間 (または評価) されます。ピクセル シェーダー属性の補間モードは、引数または入力構造体として、入力レジスタ宣言に要素単位で宣言します。属性は、線形補間することも、重心サンプリングによって補間することもできます。重心評価はマルチサンプリング時のみに関連し、ピクセルがプリミティブによってカバーされ、ピクセルの重心がカバーされない場合に対応します。重心評価は、(カバーされていない) ピクセルの重心のできるだけ近くで行われます。

入力も、他のパイプライン ステージによって使用されるパラメーターをマークする System-Value セマンティクスで宣言することができます。たとえば、ピクセルの位置は、SV_Position セマンティクスでマークする必要があります。IA ステージでは、(SV_PrimitiveID を使用して) ピクセル シェーダーにスカラーを 1 つ生成できます。また、ラスタライザー ステージでも、(SV_IsFrontFace を使用して) ピクセル シェーダーにスカラーを 1 つ生成できます。

出力

ピクセル シェーダーは、32 ビット、4 成分のカラーを 8 つまで出力できます。ピクセルが破棄された場合、カラーを出力することはできません。ピクセル シェーダー出力レジスタの成分は、使用する前に宣言する必要があります。各レジスタには異なる出力書き込みマスクを指定できます。

深度バッファーに深度データを書き込むかどうかは、(出力結合ステージの) depth-write-enable ステートを使用して制御します (または、破棄命令を使用して、そのピクセルのデータを破棄します)。ピクセル シェーダーは、オプションの 32 ビット、1 成分、浮動小数点の深度値を深度テスト用に出力することもできます (SV_Depth セマンティクスを使用します)。深度値は、oDepth レジスタに出力され、深度テストのために、補間された深度値と置き換えられます (深度テストが有効であることを前提とします)。固定機能深度またはシェーダー oDepth の使用を動的に変更することはできません。

ピクセル シェーダーは、ステンシル値を出力できません。

関連項目

パイプライン ステージ (Direct3D 10)