効果での状態の整理 (Direct3D 11)
Direct3D 11 では、特定のパイプライン ステージの効果の状態が構造体別に整理されます。 構造を次に示します。
パイプラインの状態 | 構造体 |
---|---|
ラスタライズ | D3D11_RASTERIZER_DESC |
出力結合 | D3D11_BLEND_DESC と D3D11_DEPTH_STENCIL_DESC |
シェーダー | 下記参照 |
状態の変更の数をアプリケーションによって制御する必要があるシェーダー ステージでは、状態は定数バッファー状態、サンプラー状態、シェーダー リソース状態、および順序なしのアクセス ビューステート (ピクセルシェーダーとコンピューティング シェーダーの場合) に分割されています。 これにより、変更されている状態のみを慎重に更新するように設計されたアプリケーションが可能になります。これにより、GPU に渡す必要があるデータの量を減らすことでパフォーマンスが向上します。
では、パイプラインの状態を効果で整理するにはどうすればよいでしょうか。
答えは、順序は関係ありません。 グローバル変数を先頭に配置する必要はありません。 ただし、SDK 内のすべてのサンプルは同じ順序に従います。同じ方法でデータを整理することをお勧めします。 そのため、これは DirectX SDK サンプルのデータ順序の簡単な説明です。
グローバル変数
標準の C プラクティスと同様に、グローバル変数は最初にファイルの先頭に宣言されます。 ほとんどの場合、これらはアプリケーションによって初期化され、その後効果で使用される変数です。 初期化されて変更されない場合もあれば、フレームごとに更新される場合もあります。 C 関数のスコープ ルールと同様に、効果関数のスコープ外で宣言された効果変数は、効果全体で表示されます。効果関数内で宣言された変数は、その関数内でのみ表示されます。
BasicHLSL10.fx で宣言された変数の例を次に示します。
// Global variables
float4 g_MaterialAmbientColor; // Material's ambient color
Texture2D g_MeshTexture; // Color texture for mesh
float g_fTime; // App's time in seconds
float4x4 g_mWorld; // World matrix for object
float4x4 g_mWorldViewProjection; // World * View * Projection matrix
// Texture samplers
SamplerState MeshTextureSampler
{
Filter = MIN_MAG_MIP_LINEAR;
AddressU = Wrap;
AddressV = Wrap;
};
効果変数の構文の詳細については、「 効果変数構文 (Direct3D 11)」を参照してください。 効果テクスチャ サンプラーの構文については、「 サンプラーの種類 (DirectX HLSL)」で詳しく説明されています。
シェーダー
シェーダーは小さな実行可能プログラムです。 HLSL コードではシェーダー機能が実装されているため、シェーダーはシェーダーの状態をカプセル化していると考えることができます。 最大 5 種類のシェーダーのグラフィックス パイプライン。
- 頂点シェーダー - 頂点データを操作します。 内の 1 つの頂点によって、1 つの頂点が生成されます。
- ハル シェーダー - パッチ データを操作します。 コントロール ポイント フェーズ: 1 つの呼び出しで 1 つのコントロール ポイントが生成されます。フォークフェーズと結合フェーズごとに: 1 つのパッチによって、ある程度のパッチ定数データが生成されます。
- ドメイン シェーダー - プリミティブ データを操作します。 1 つのプリミティブで 0、1、または多数のプリミティブが生成される場合があります。
- ジオメトリ シェーダー - プリミティブ データを操作します。 の 1 つのプリミティブでは、0、1、または多数のプリミティブが生成される場合があります。
- ピクセル シェーダー - ピクセル データを操作します。 の 1 ピクセルの場合、1 ピクセルが出力されます (ピクセルがレンダリングから除外されない限り)。
コンピューティング シェーダー パイプラインでは、次の 1 つのシェーダーが使用されます。
- コンピューティング シェーダー - あらゆる種類のデータを操作します。 出力はスレッド数に依存しません。
シェーダーはローカル関数であり、C スタイルの関数ルールに従います。 エフェクトがコンパイルされると、各シェーダーがコンパイルされ、各シェーダー関数へのポインターが内部的に格納されます。 コンパイルが成功すると、ID3D11Effect インターフェイスが返されます。 この時点で、コンパイルされた効果は中間形式になります。
コンパイルされたシェーダーの詳細を確認するには、シェーダー リフレクションを使用する必要があります。 これは基本的に、ランタイムにシェーダーの逆コンパイルを要求し、シェーダー コードに関する情報を返すように求めることに似ています。
struct VS_OUTPUT
{
float4 Position : SV_POSITION; // vertex position
float4 Diffuse : COLOR0; // vertex diffuse color
float2 TextureUV : TEXCOORD0; // vertex texture coords
};
VS_OUTPUT RenderSceneVS( float4 vPos : POSITION,
float3 vNormal : NORMAL,
float2 vTexCoord0 : TEXCOORD,
uniform int nNumLights,
uniform bool bTexture,
uniform bool bAnimate )
{
VS_OUTPUT Output;
float3 vNormalWorldSpace;
....
return Output;
}
struct PS_OUTPUT
{
float4 RGBColor : SV_Target; // Pixel color
};
PS_OUTPUT RenderScenePS( VS_OUTPUT In,
uniform bool bTexture )
{
PS_OUTPUT Output;
if( bTexture )
Output.RGBColor = g_MeshTexture.Sample(MeshTextureSampler, In.TextureUV) * In.Diffuse;
....
return Output;
}
エフェクト シェーダーの構文の詳細については、「 Effect Function Syntax (Direct3D 11)」を参照してください。
グループ、手法、パス
グループは、手法のコレクションです。 手法は、レンダリング パスのコレクションです (少なくとも 1 つのパスが必要です)。 各エフェクト パス (レンダー ループ内の 1 つのパスに似ています) は、シェーダーの状態と、ジオメトリをレンダリングするために必要なその他のパイプライン状態を定義します。
グループは省略可能です。 すべてのグローバル手法を含む名前のないグループが 1 つあります。 他のすべてのグループに名前を付ける必要があります。
BasicHLSL10.fx からの 1 つの手法 (1 つのパスを含む) の例を次に示します。
technique10 RenderSceneWithTexture1Light
{
pass P0
{
SetVertexShader( CompileShader( vs_4_0, RenderSceneVS( 1, true, true ) ) );
SetGeometryShader( NULL );
SetPixelShader( CompileShader( ps_4_0, RenderScenePS( true ) ) );
}
}
fxgroup g0
{
technique11 RunComputeShader
{
pass P0
{
SetComputeShader( CompileShader( cs_5_0, CS() ) );
}
}
}
効果シェーダーの構文の詳細については、「 効果手法の構文 (Direct3D 11)」を参照してください。
関連トピック