Différents shaders pour différents objets DirectX 11

13

J'apprends Direct3D 11, et dans tous les didacticiels de base que j'ai trouvés sur l'écriture des shaders, les shaders Vertex et Pixel sont écrits pour transformer la scène entière de la même manière. Tutoriels comme rendre cube avec texture ...

Mais je me demande, comment différenciez-vous les objets? Que faire si vous voulez, par exemple, simuler la surface miroir d'un objet et utiliser différents shaders pour restituer le reste de la scène? Je pense que la plupart des jeux doivent utiliser de nombreux shaders de vertex et de pixels pour obtenir divers aspects et transformations.

Je vous remercie.

jantobola
la source

Réponses:

23

Oui, un moteur de jeu aura généralement une variété de shaders différents. Le modèle typique est:

  1. Tout en initialisant le moteur et en chargeant le monde du jeu, préparez tous les shaders que vous utiliserez pour le rendu. Par «préparer», je veux dire les charger en mémoire, les compiler si nécessaire et faire tous les ID3D11Device::CreatePixelShaderappels et similaires pour obtenir les objets de shader D3D alloués et prêts à l'emploi. Conservez les objets dans un tableau ou une autre structure de données.

    Habituellement, vous aurez une relation un à un entre les vertex shaders et les pixel shaders conçus pour fonctionner ensemble. Je les considère comme un seul objet, que j'appelle juste un "shader", même s'il contient vraiment un vertex shader et un pixel shader (et peut-être aussi des shaders de géométrie / coque / domaine).

  2. Chaque image, une fois que vous avez trouvé la liste des objets (mailles) à rendre, triez-les par shader. L'idée est de minimiser le nombre de fois que vous changez de shader dans un cadre, en dessinant tous les objets avec un shader donné ensemble. En effet, le changement de shaders est une opération assez coûteuse (bien que vous puissiez certainement le faire plusieurs centaines ou mille fois par image, ce n'est donc pas si cher).

    En fait, vous pouvez aller plus loin et trier les maillages par shader en premier et par matériau en second. Par "matériel", je veux dire une combinaison d'un shader et d'un ensemble de textures et de paramètres pour cela. Les shaders ont généralement des textures et des paramètres numériques (stockés dans des tampons constants) qui les alimentent.Par exemple, un matériau en brique et en asphalte peut utiliser le même code de shader, uniquement avec des textures différentes.

  3. Pour dessiner, faites une boucle sur les shaders, définissez chaque shader dans le ID3D11DeviceContext, définissez les paramètres (tampons constants, textures, etc.), puis dessinez les objets. Dans le pseudocode, y compris la distinction shaders / matériaux, j'ai mentionné:

    for each shader:
        // Set the device context to use this shader
        pContext->VSSetShader(shader.pVertexShader);
        pContext->PSSetShader(shader.pPixelShader);
    
        for each material that uses this shader:
            // Set the device context to use any constant buffers, textures, samplers,
            // etc. needed for this material
            pContext->VSSetConstantBuffers(...);
            pContext->PSSetConstantBuffers(...);
            pContext->PSSetShaderResources(...);
            pContext->PSSetSamplers(...);
    
            for each mesh that uses this material:
                // Set any constant buffers containing parameters specific to the mesh
                // (e.g. world matrix)
                pContext->VSSetConstantBuffers(...);
    
                // Set the context to use the vertex & index buffers for this mesh
                pContext->IASetInputLayout(mesh.pInputLayout);
                pContext->IASetVertexBuffers(...);
                pContext->IASetIndexBuffer(...);
                pContext->IASetPrimitiveTopology(...)
    
                // Draw it
                pContext->DrawIndexed(...)

Il y a beaucoup plus à dire sur la gestion des objets, des maillages, des shaders, des dispositions d'entrée, des tampons constants, etc., mais cela devrait suffire pour vous aider à démarrer. :)

Nathan Reed
la source
Vous proposez un tri par shader puis par matière. Avez-vous des données fiables sur le coût du changement de shaders par rapport au changement de matériaux? Oh, et pour DX9, une combinaison VS / PS est appelée "programme". Je ne suis pas sûr qu'ils utilisent toujours cette terminologie dans DX11.
Panda Pyjama
1
@PandaPajama C'est une bonne question. Non, je n'ai ni ne connais de mesures récentes du coût réel de changement de matériaux ou de shaders. Cette approche a été la «sagesse commune» pendant des années, mais cela vaut la peine de faire des mesures réelles pour voir comment les choses ont changé ... peut-être que je le ferai si je peux trouver le temps. :)
Nathan Reed