État d’organisation dans un effet (Direct3D 10)

Avec Direct3D 10, l’état d’effet de certaines étapes de pipeline est organisé selon les structures suivantes :

État du pipeline Structure
Assembleur d'entrée D3D10_INPUT_ELEMENT_DESC
Rasterization D3D10_RASTERIZER_DESC
Fusion de sortie D3D10_BLEND_DESC et D3D10_DEPTH_STENCIL_DESC

 

Pour les phases de nuanceur, où le nombre de modifications d’état doit être plus contrôlé par une application, l’état a été divisé en état de mémoire tampon constant, état de l’échantillonneur et état de ressource du nuanceur. Cela permet à une application soigneusement conçue de mettre à jour uniquement l’état en cours de modification, ce qui améliore les performances en réduisant la quantité de données à transmettre au GPU.

Comment organiser l’état du pipeline dans un effet ?

La réponse est que l’ordre n’a pas d’importance. Les variables globales n’ont pas besoin d’être situées en haut. Toutefois, tous les exemples du KIT de développement logiciel (SDK) suivent le même ordre, car il est recommandé d’organiser les données de la même façon. Il s’agit donc d’une brève description de l’ordre des données dans les exemples du Kit de développement logiciel (SDK) DirectX.

Variables globales

Tout comme la pratique C standard, les variables globales sont déclarées en premier, en haut du fichier. Le plus souvent, il s’agit de variables qui seront initialisées par une application, puis utilisées dans un effet. Parfois, ils sont initialisés et jamais modifiés, d’autres fois ils sont mis à jour chaque image. Tout comme les règles d’étendue de fonction C, les variables d’effet déclarées en dehors de l’étendue des fonctions d’effet sont visibles dans l’ensemble de l’effet ; toute variable déclarée à l’intérieur d’une fonction d’effet n’est visible qu’au sein de cette fonction.

Voici un exemple de variables déclarées dans 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;
};

La syntaxe des variables d’effet est plus détaillée dans Syntaxe des variables d’effet (Direct3D 10). La syntaxe des échantillonneurs de texture d’effet est plus détaillée dans Type d’échantillonneur (DirectX HLSL).

Nuanceurs

Les nuanceurs sont de petits programmes exécutables. Vous pouvez considérer les nuanceurs comme un état de nuanceur encapsulant, car le code HLSL implémente la fonctionnalité de nuanceur. Le pipeline utilise trois types de nuanceurs différents.

  • Nuanceurs de vertex : fonctionnent sur les données de vertex. Un sommet dans donne un sommet.
  • Nuanceurs geometry : fonctionnent sur des données primitives. Une primitive dans peut donner 0, 1, ou beaucoup de primitives.
  • Nuanceurs de pixels : fonctionnent sur les données de pixels. Un pixel dans génère 1 pixel de sortie (sauf si le pixel est éliminé d’un rendu).

Les nuanceurs sont des fonctions locales et suivent les règles de fonction de style C. Lorsqu’un effet est compilé, chaque nuanceur est compilé et un pointeur vers chaque fonction de nuanceur est stocké en interne. Une interface ID3D10Effect est retournée lorsque la compilation réussit. À ce stade, l’effet compilé est dans un format intermédiaire.

Pour en savoir plus sur les nuanceurs compilés, vous devez utiliser la réflexion du nuanceur. Cela revient essentiellement à demander au runtime de décompiler les nuanceurs et de vous renvoyer des informations sur le code du nuanceur.

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;
}

La syntaxe des nuanceurs d’effets est plus détaillée dans Syntaxe de fonction d’effet (Direct3D 10).

Techniques et passes

Une technique est une collection de passes de rendu (il doit y avoir au moins une passe). Chaque passage d’effet (qui est similaire dans l’étendue à une seule passe dans une boucle de rendu) définit l’état du nuanceur et tout autre état de pipeline nécessaire au rendu de la géométrie.

Voici un exemple d’une technique (qui comprend une passe) de BasicHLSL10.fx.

technique10 RenderSceneWithTexture1Light
{
    pass P0
    {
        SetVertexShader( CompileShader( vs_4_0, RenderSceneVS( 1, true, true ) ) );
        SetGeometryShader( NULL );
        SetPixelShader( CompileShader( ps_4_0, RenderScenePS( true ) ) );
    }
}

La syntaxe des nuanceurs d’effets est plus détaillée dans Syntaxe de la technique d’effet (Direct3D 10).

Effets (Direct3D 10)