IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Tutoriels Direct3D 10 : Shaders

logo msdn


précédentsommaire

III-13. Tutoriel 13 : Geometry Shaders

tuto13

III-13-a. Résumé

Ce tutoriel va explorer une partie du pipeline graphique qui n'a pas encore été abordé dans les tutoriels précédent. Nous allons évoquer quelques fonctionnalités basique des geometry shader.

Le résultat de ce tutoriel sera que le modèle comportera une seconde couche extraite du modèle. Notons que le modèle original sera toujours préservé au centre.

III-13-b. Source

 
Sélectionnez
SDK root\Samples\C++\Direct3D10\Tutorials\Tutorial13

III-13-c. Geometry Shader

Le bénéfice des geometry shader (GS) est qu'ils permettent de manipuler les mailles sur la base par-primitive. Au lieu de lancer un calcul sur chaque sommet individuellement, il y a l'option pour exploiter sur une base par-primitive. C'est-à-dire, des sommets peuvent être passés dedans comme sommet simple, une ligne segment (deux sommets), ou comme triangle (trois sommets).

En permettant la manipulation à un niveau par-primitive, de nouvelles idées peuvent être approchées, et il y a plus d'accès aux données à tenir compte pour cela. Dans ce tutoriel, vous verrez que nous avons calculé la normale pour le visage. En sachant la position de chacun des trois sommets, nous pouvons trouver la normale du visage.

En plus de permettre l'accès à toutes les primitives, le geometry shader peut créer de nouvelles primitives à la volée. Précédemment dans Direct3D, le pipeline graphique pouvait seulement manipuler le contenu existant, et il pourrait amplifier ou desamplifier des données. Le geometry shader dans Direct3D 10 peut lire dedans une simple primitive (avec les primitives bord-adjacents facultatifs) et émettre zéro, une, ou de multiples primitives basés sur ça.

Il est possible d'émettre un type différent de géométrie que la source d'entrée. Par exemple, il est possible de lire différents sommets, et de générer des triangles multiples basées sur eux. Ceci permet un éventail de nouvelles idées pouvant être exécuté sur le pipeline graphique sans intervention du CPU.

Le geometry shader existe entre le vertex shader et le pixel shader dans le pipeline graphique. Puisque de nouvelles géométries peuvent être créés potentiellement par le geometry shader, nous devons nous assurer qu'ils sont également correctement transformés dans l'espace de projection avant que nous les passions dans le pixel shader. cela peut être fait par le vertex shader avant qu'il entre dans le geometry shader ou il peut être fait dans le geometry shader lui même.

En conclusion, le rendement du Geometry Shader peut être rerouté à un buffer. Vous pouvez lire dans un groupe de triangles, produire de nouvelles géométries, et les stocker dans un nouveau buffer. Cependant, le concept du flux de sortie est au delà de la portée des tutoriels, et il est mieux expliqué dans les exemples trouvés dans le SDK.

Plusieurs des échantillons trouvé dans le SDK Direct3D 10 illustrent les techniques spécifiques qui peuvent être réalisées avec le geometry shader. Si vous souhaitez un exemple simple pour commencer, vous pouvez essayer ParticlesGS. ParticlesGS simule et affiche un système de particules dynamique (création, explosion et destruction de particules) entièrement sur le GPU.

III-13-c-1. Formater un Geometry Shader

Contrairement au Vertex shader et au Pixel shader, le geometry shader ne produit pas nécessairement un nombre statique de sorties par entrée. En soi, le format pour déclarer le shader est différent des deux autres.

Le premier paramètre est maxvertexcount. Ce paramètre décrit le nombre maximum de sommets qui peuvent être sorti chaque fois que le shader est lancé. Ceci est suivi du nom du geometry shader, qui a été convenablement appelé GS.

Le nom de fonction est suivi des paramètres passés dans la fonction. Le premier contient le mot-clé triangle, qui spécifie que le Geometry Shader opérera sur des triangles en entrée. Le suivant est le format de sommet, et l'identifiant (avec le nombre signifiant la taille du tableau, 3 pour des triangles, 2 pour un segments). Le second est le format et flux de sortie. TriangleStream signifie que la sortie sera dans les triangles (bandes de triangle pour être exactes), puis le format est spécifié dans les chevrons. En conclusion, l'identifiant pour le flux est dénotée.

 
Sélectionnez
    [maxvertexcount(12)]
    void GS( triangle GSPS_INPUT input[3], inout TriangleStream<GSPS_INPUT> TriStream )

Si des sommets commencent à être émis à un TriangleStream, il supposera qu'ils tous sont liés ensemble comme une bande. Pour finir une bande, appelez RestartStrip dans le flux. Pour créer une liste de triangle, vous devez veiller que vous appelez bien RestartStrip après chaque triangle.

III-13-c-2. Explosion du modèle

Dans ce tutoriel, nous couvrons les fonctions de base des geometry shader. Pour illustrer cela, nous allons créer un effet d'explosion sur notre modèle. Cet effet est créé par extrusion de chaque sommet dans la direction de la normale du triangle considéré.

Notez qu'un effet similaire a été implémenté dans des tutoriels précédent, par lequel nous expulsions chaque sommet par sa normale, commandé par le glisseur puffiness. Ce tutoriel démontre l'usage des information d'un triangle complet pour générer la face normale. la différence d'utiliser la face normale est que vous verrez des lacunes entre les triangles éclatés. Parce que les sommets entre différents triangles sont partagés, ils seront donc passés par deux fois dans le geometry shader. De plus, puisque chaque fois qu'une extrusion est effectuée dans la normale du triangle, par opposition au sommet, les deux sommets finaux peuvent finir vers le haut dans différentes positions.

III-13-c-3. Calculer la face normale

Pour calculer la normale pour n'importe quel plan, nous avons besoin d'abord de deux vecteurs qui résident sur le plan. Puisque nous nous sommes donnés un triangle, nous pouvons soustraire deux sommets quelconques du triangle pour obtenir les vecteurs relatifs. Une fois que nous avons les vecteurs, nous prenons le produit en croix pour obtenir la normale. Nous devons également normaliser la normale, puisque nous reverrons l'échelle plus tard.

 
Sélectionnez
    //
    // Calculer la face normale
    //
    float3 faceEdgeA = input[1].Pos - input[0].Pos;
    float3 faceEdgeB = input[2].Pos - input[0].Pos;
    float3 faceNormal = normalize( cross(faceEdgeA, faceEdgeB) );

Une fois que nous avons la normale de la face, nous pouvons expulser chaque point du triangle dans cette direction. Pour faire ainsi, nous employons une boucle, qui fera trois tour et opérera sur chaque sommet. La position du sommet est expulsée par la normale, multipliée par un facteur. Puis, puisque le Vertex shader n'a pas transformé les sommets à l'espace approprié de projection, nous devons également faire cela dans le Geometry shader. En conclusion, une fois que nous empaquetons le reste des données, nous pouvons apposer ce nouveau sommet à notre TriangleStream.

 
Sélectionnez
    for( int v=0; v<3; v++ )
    {
        output.Pos = input[v].Pos + float4(faceNormal*Explode,0);
        output.Pos = mul( output.Pos, View );
        output.Pos = mul( output.Pos, Projection );
        
        output.Norm = input[v].Norm;
        
        output.Tex = input[v].Tex;
        
        TriStream.Append( output );
    }

Une fois que les trois sommets ont été émis, nous pouvons couper la bande et recommencer. Dans ce tutoriel, nous voulons expulser chaque triangle séparément, ainsi nous finissons avec une liste de triangle.

 
Sélectionnez
    TriStream.RestartStrip();

Ce nouveau flux de triangle est alors envoyé au Pixel shader, qui opérera sur ces données et les dessinera à la cible d'affichage.


précédentsommaire

Cet article est une traduction d'un article original de Microsoft en anglais. Les éventuels problèmes résultant d'une mauvaise traduction ne sont pas imputables à Microsoft. Lire l'article original Ici.