Prise en main avec la phase de rastériseur

Cette section décrit la définition de la fenêtre d’affichage, du rectangle de ciseaux, de l’état du rastériseur et du multi-échantillonnage.

Définir la fenêtre d’affichage

Une fenêtre d’affichage mappe les positions de vertex (dans l’espace de clip) en positions cibles de rendu. Cette étape met à l’échelle les positions 3D en espace 2D. Une cible de rendu est orientée avec les axes Y pointant vers le bas ; Cela nécessite que les coordonnées Y soient retournées pendant l’échelle de la fenêtre d’affichage. En outre, les étendues x et y (plage des valeurs x et y) sont mises à l’échelle pour s’adapter à la taille de la fenêtre d’affichage selon les formules suivantes :

X = (X + 1) * Viewport.Width * 0.5 + Viewport.TopLeftX
Y = (1 - Y) * Viewport.Height * 0.5 + Viewport.TopLeftY
Z = Viewport.MinDepth + Z * (Viewport.MaxDepth - Viewport.MinDepth) 

Tutoriel 1 crée une fenêtre d’affichage 640 × 480 à l’aide de D3D11_VIEWPORT et en appelant ID3D11DeviceContext::RSSetViewports.

    D3D11_VIEWPORT vp[1];
    vp[0].Width = 640.0f;
    vp[0].Height = 480.0f;
    vp[0].MinDepth = 0;
    vp[0].MaxDepth = 1;
    vp[0].TopLeftX = 0;
    vp[0].TopLeftY = 0;
    g_pd3dContext->RSSetViewports( 1, vp );

La description de la fenêtre d’affichage spécifie la taille de la fenêtre d’affichage, la plage à laquelle mapper la profondeur (à l’aide de MinDepth et MaxDepth) et l’emplacement de la fenêtre d’affichage en haut à gauche de la fenêtre d’affichage. MinDepth doit être inférieur ou égal à MaxDepth ; la plage pour MinDepth et MaxDepth est comprise entre 0,0 et 1,0, inclus. Il est courant que la fenêtre d’affichage mappe à une cible de rendu, mais ce n’est pas nécessaire ; en outre, la fenêtre d’affichage n’a pas besoin d’avoir la même taille ou la même position que la cible de rendu.

Vous pouvez créer un tableau de fenêtres d’affichage, mais une seule peut être appliquée à une sortie primitive à partir du nuanceur geometry. Une seule fenêtre d’affichage peut être définie comme étant active à la fois. Le pipeline utilise une fenêtre d’affichage par défaut (et un rectangle en ciseaux, décrit dans la section suivante) pendant la rastérisation. La valeur par défaut est toujours la première fenêtre d’affichage (ou rectangle de ciseaux) dans le tableau. Pour effectuer une sélection par primitive de la fenêtre d’affichage dans le nuanceur geometry, spécifiez la sémantique ViewportArrayIndex sur le composant de sortie GS approprié dans la déclaration de signature de sortie GS.

Le nombre maximal de fenêtres d’affichage (et de rectangles en ciseaux) qui peuvent être liés à l’étape de rastériseur à un moment donné est de 16 (spécifié par D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE).

Définir le rectangle de ciseaux

Un rectangle à ciseaux vous offre une autre possibilité de réduire le nombre de pixels qui seront envoyés à l’étape de fusion de sortie. Les pixels en dehors du rectangle en ciseaux sont ignorés. La taille du rectangle en ciseaux est spécifiée en entiers. Un seul rectangle en ciseaux (basé sur ViewportArrayIndex dans la sémantique des valeurs système) peut être appliqué à un triangle pendant la rastérisation.

Pour activer le rectangle de ciseaux, utilisez le membre ScissorEnable (dans D3D11_RASTERIZER_DESC1). Le rectangle de ciseaux par défaut est un rectangle vide ; autrement dit, toutes les valeurs rect sont 0. En d’autres termes, si vous ne configurez pas le rectangle de ciseaux et que le ciseau est activé, vous n’envoyez pas de pixels à l’étape de fusion de sortie. La configuration la plus courante consiste à initialiser le rectangle en ciseaux à la taille de la fenêtre d’affichage.

Pour définir un tableau de rectangles en ciseaux sur l’appareil, appelez ID3D11DeviceContext::RSSetScissorRects avec D3D11_RECT.

  D3D11_RECT rects[1];
  rects[0].left = 0;
  rects[0].right = 640;
  rects[0].top = 0;
  rects[0].bottom = 480;

  g_pd3dContext->RSSetScissorRects( 1, rects );

Cette méthode prend deux paramètres : (1) le nombre de rectangles dans le tableau et (2) un tableau de rectangles.

Le pipeline utilise un index rectangle en ciseaux par défaut lors de la rastérisation (la valeur par défaut est un rectangle de taille nulle avec le découpage désactivé). Pour remplacer cela, spécifiez la sémantique SV_ViewportArrayIndex à un composant de sortie GS dans la déclaration de signature de sortie GS. Cela oblige la phase GS à marquer ce composant de sortie GS en tant que composant généré par le système avec cette sémantique. L’étape de rastériseur reconnaît cette sémantique et utilise le paramètre auquel elle est attachée en tant qu’index rectangle à ciseaux pour accéder au tableau de rectangles en ciseaux. N’oubliez pas d’indiquer à la phase de rastériseur d’utiliser le rectangle à ciseaux que vous définissez en activant la valeur ScissorEnable dans la description du rastériseur avant de créer l’objet rastériseur.

Définir l’état du rastériseur

À compter de Direct3D 10, l’état de rastériseur est encapsulé dans un objet d’état de rastériseur. Vous pouvez créer jusqu’à 4 096 objets d’état rastériseur qui peuvent ensuite être définis sur l’appareil en passant un handle à l’objet d’état.

Utilisez ID3D11Device1::CreateRasterizerState1 pour créer un objet d’état de rastériseur à partir d’une description de rastériseur (voir D3D11_RASTERIZER_DESC1).

    ID3D11RasterizerState1 * g_pRasterState;

    D3D11_RASTERIZER_DESC1 rasterizerState;
    rasterizerState.FillMode = D3D11_FILL_SOLID;
    rasterizerState.CullMode = D3D11_CULL_FRONT;
    rasterizerState.FrontCounterClockwise = true;
    rasterizerState.DepthBias = false;
    rasterizerState.DepthBiasClamp = 0;
    rasterizerState.SlopeScaledDepthBias = 0;
    rasterizerState.DepthClipEnable = true;
    rasterizerState.ScissorEnable = true;
    rasterizerState.MultisampleEnable = false;
    rasterizerState.AntialiasedLineEnable = false;
    rasterizerState.ForcedSampleCount = 0;
    g_pd3dDevice->CreateRasterizerState1( &rasterizerState, &g_pRasterState );

Cet exemple d’ensemble d’états accomplit peut-être la configuration la plus basique du rastériseur :

  • Mode remplissage uni
  • Supprimer ou supprimer des visages arrières; Supposons que l’ordre de bobage dans le sens inverse des aiguilles d’une montre pour les primitives
  • Désactiver le biais de profondeur, mais activer la mise en mémoire tampon de profondeur et activer le rectangle de ciseaux
  • Désactiver le multi-échantillonnage et l’anti-aliasing de ligne

En outre, les opérations de rastériseur de base incluent toujours les éléments suivants : découpage (au frustum de la vue), division de la perspective et mise à l’échelle de la fenêtre d’affichage. Une fois l’objet d’état rastériseur créé, définissez-le sur l’appareil comme suit :

    g_pd3dContext->RSSetState(g_pRasterState);

Échantillonnage multiple

Le multiéchantillonnage échantillonne tout ou partie des composants d’une image à une résolution plus élevée (suivi d’un sous-échantillonnage vers la résolution d’origine) pour réduire la forme d’aliasing la plus visible provoquée par le dessin des bords de polygones. Même si le multi-échantillonnage nécessite des exemples de sous-pixels, les GPU modernes implémentent le multi-échantillonnage afin qu’un nuanceur de pixels s’exécute une fois par pixel. Cela fournit un compromis acceptable entre les performances (en particulier dans une application liée au GPU) et l’anti-aliasing de l’image finale.

Pour utiliser le multi-échantillonnage, définissez le champ Enable dans la description de rastérisation, créez une cible de rendu multi-échantillonnée, puis lisez la cible de rendu avec un nuanceur pour résoudre les exemples en une seule couleur de pixel ou appelez ID3D11DeviceContext::ResolveSubresource pour résoudre les exemples à l’aide de la vidéo carte. Le scénario le plus courant consiste à dessiner vers une ou plusieurs cibles de rendu multi-échantillonnée.

Le multi-échantillonnage est indépendant de l’utilisation ou non d’un exemple de masque, de l’alpha-to-coverage ou des opérations de gabarit (qui sont toujours effectuées par échantillon).

Le test de profondeur est affecté par le multi-échantillonnage :

  • Lorsque le multi-échantillonnage est activé, la profondeur est interpolée par échantillon et le test de profondeur/gabarit est effectué par échantillon ; la couleur de sortie du nuanceur de pixels est dupliquée pour tous les exemples passants. Si le nuanceur de pixels génère une profondeur, la valeur de profondeur est dupliquée pour tous les exemples (même si ce scénario perd l’avantage du multi-échantillonnage).
  • Lorsque le multi-échantillonnage est désactivé, le test de profondeur/gabarit est toujours effectué par échantillon, mais la profondeur n’est pas interpolée par échantillon.

Il n’existe aucune restriction pour le mélange de rendu multi-échantillonné et non multi-échantillonné au sein d’une seule cible de rendu. Si vous activez le multi-échantillonnage et dessinez vers une cible de rendu non multi-échantillonnée, vous produisez le même résultat que si le multi-échantillonnage n’était pas activé ; l’échantillonnage est effectué avec un seul échantillon par pixel.

Étape du rastériseur