効果での状態の整理 (Direct3D 10)

Direct3D 10 では、特定のパイプライン ステージの効果の状態は、次の構造によって編成されます。

パイプラインの状態 構造体
入力アセンブラー D3D10_INPUT_ELEMENT_DESC
ラスタライズ D3D10_RASTERIZER_DESC
出力結合 D3D10_BLEND_DESCD3D10_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 インターフェイスが返されます。 この時点で、コンパイルされた効果は中間形式になります。

コンパイルされたシェーダーの詳細を確認するには、シェーダー リフレクションを使用する必要があります。 これは基本的に、ランタイムにシェーダーの逆コンパイルを依頼し、シェーダー コードに関する情報を返すように求めるのと同じです。

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 つのパスが必要です)。 各エフェクト パス (レンダー ループ内の 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)」を参照してください

効果 (Direct3D 10)