エフェクトのステートの編成 (Direct3D 10)
Direct3D 10 を使用すると、特定のパイプライン ステージのエフェクト ステートは、次の構造体によって編成されます。
パイプライン ステート | 構造体 |
---|---|
入力アセンブラー | D3D10_INPUT_ELEMENT_DESC |
ラスター化 | D3D10_RASTERIZER_DESC |
出力結合 | D3D10_BLEND_DESC および D3D10_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 10)」で詳しく説明しています。エフェクト テクスチャー サンプラーの構文については、「サンプラー型 (DirectX HLSL)」で詳しく説明しています。
シェーダー
シェーダーは、小さな実行可能プログラムです。HLSL コードではシェーダー機能が実装されるため、シェーダーをカプセル化シェーダー ステートと考えることができます。パイプラインは、3 種類のシェーダーを使用します。
- 頂点シェーダー ? 頂点データに作用します。1 つの入力頂点から 1 つの出力頂点が生成されます。
- ジオメトリ シェーダー ? プリミティブ データに作用します。1 つの入力プリミティブから 0 個、1 個、または多数の出力プリミティブを生成できます。
- ピクセル シェーダー ? ピクセル データに作用します。1 つの入力ピクセルから 1 つの出力ピクセルが生成されます (ピクセルがレンダリングからカリングされない限り)。
シェーダーは、ローカル関数で、C 言語の形式の関数ルールに従います。エフェクトのコンパイル時に、各シェーダーがコンパイルされ、各シェーダー関数へのポインターが内部保存されます。コンパイルが正常に実行されると、ID3D10Effect インターフェイスが返されます。この時点で、コンパイルされたエフェクトは、中間形式 (LINK の追加) になります。
コンパイルされたシェーダーの詳細を入手するには、シェーダー反射を使用する必要があります。これは、基本的には、シェーダーを逆コンパイルし、シェーダー コードに関する情報を返すようにランタイムに要求することと同様です。
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; }
エフェクト シェーダーの構文については、「エフェクト関数の構文 (Direct3D 10)」で詳しく説明しています。
テクニックとパス
テクニックとは、レンダリング パスの集合です (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 ) ) ); } }
エフェクト テクニックの構文については、「エフェクト テクニックの構文 (Direct3D 10)」で詳しく説明しています。