Shader diversi per oggetti diversi DirectX 11


13

Sto imparando Direct3D 11e in tutti i tutorial di base che ho trovato sulla scrittura degli shader, gli shader Vertex e Pixel sono scritti in modo da trasformare l'intera scena allo stesso modo. Tutorial come render cubo con trama ...

Ma mi chiedo, come si differenziano gli oggetti? E se volessi, ad esempio, simulare la superficie dello specchio su un oggetto e utilizzare diversi shader per rendere il resto della scena? Penso che la maggior parte dei giochi debba usare molti shader di vertici e pixel per ottenere vari look e trasformazioni.

Grazie.

Risposte:


23

Sì, un motore di gioco avrà in genere una varietà di shader diversi. Il modello tipico è:

  1. Durante l'inizializzazione del motore e il caricamento del mondo di gioco, prepara tutti gli shader che utilizzerai per il rendering. Con "preparazione" intendo caricarli in memoria, compilarli se necessario ed eseguire tutte le ID3D11Device::CreatePixelShaderchiamate e simili per ottenere gli oggetti D3D shader allocati e pronti all'uso. Conservare gli oggetti in un array o in qualche altra struttura di dati.

    Di solito avrai una relazione uno a uno tra shader di vertici e pixel shader progettati per funzionare insieme. Li considero come un singolo oggetto, che chiamo semplicemente "shader", anche se contiene davvero uno shader di vertice e uno di pixel (e forse anche shader di geometria / scafo / dominio).

  2. Ogni fotogramma, una volta trovato l'elenco di oggetti (mesh) da renderizzare, ordinali per shader. L'idea è di ridurre al minimo il numero di volte in cui si cambia shader in una cornice, riunendo tutti gli oggetti con un determinato shader. Questo perché cambiare shader è un'operazione piuttosto costosa (anche se puoi sicuramente farlo diverse centinaia o migliaia di volte per frame, quindi non è poi così costoso).

    In effetti, puoi fare un ulteriore passo avanti e ordinare le mesh in base allo shader per primo e al materiale per secondo. Per "materiale" intendo una combinazione di uno shader e un insieme di trame e parametri per esso. Gli shader di solito hanno alcune trame e parametri numerici (memorizzati in buffer costanti) che li alimentano, quindi ad esempio un materiale in mattoni e materiale in asfalto potrebbero usare lo stesso codice shader, solo con trame diverse.

  3. Per disegnare, basta passare sopra gli shader, impostare ogni shader in ID3D11DeviceContext , impostare eventuali parametri (buffer costanti, trame, ecc.), Quindi disegnare gli oggetti. Nello pseudocodice, tra cui la distinzione shader / materiali che ho citato:

    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(...)

C'è molto altro da dire sulla gestione di oggetti, mesh, shader, layout di input, buffer costanti, ecc., Ma questo dovrebbe essere sufficiente per iniziare. :)


Proponete l'ordinamento per shader e poi per materiale. Hai dei dati concreti sul costo del passaggio tra shader e materiali di commutazione? Oh, e per DX9, una combinazione VS / PS è chiamata "programma". Non sono così sicuro se usano ancora quella terminologia in DX11.
Panda Pajama,

1
@PandaPajama Questa è una buona domanda. No, non ho né conosco alcuna misurazione recente del costo effettivo di commutazione di materiali o shader. Questo approccio è stato la "saggezza comune" per anni, ma vale la pena fare alcune misurazioni reali per vedere come le cose sono cambiate ... forse lo farò se riuscissi a trovare il tempo. :)
Nathan Reed il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.