Diferentes sombreadores para diferentes objetos DirectX 11

13

Estoy aprendiendo Direct3D 11, y en todos los tutoriales básicos que encontré sobre la escritura de sombreadores, los sombreadores Vertex y Pixel están escritos para que transformen toda la escena de la misma manera. Tutoriales como render cube with texture ...

Pero me pregunto, ¿cómo diferencian los objetos? ¿Qué sucede si desea, por ejemplo, simular la superficie del espejo en algún objeto y usar diferentes sombreadores para representar el resto de la escena? Creo que la mayoría de los juegos deben usar muchos sombreadores de vértices y píxeles para lograr varios estilos y transformaciones.

Gracias.

jantobola
fuente

Respuestas:

23

Sí, un motor de juego en general tendrá una variedad de sombreadores diferentes. El patrón típico es:

  1. Mientras inicializa el motor y carga el mundo del juego, prepare todos los sombreadores que usará para renderizar. Por "preparar" me refiero a cargarlos en la memoria, compilarlos si es necesario y hacer todas las ID3D11Device::CreatePixelShaderllamadas similares para obtener los objetos de sombreador D3D asignados y listos para funcionar. Mantenga los objetos en una matriz o alguna otra estructura de datos.

    Por lo general, tendrá una relación uno a uno entre los sombreadores de vértices y los sombreadores de píxeles diseñados para trabajar juntos. Pienso en ellos como un solo objeto, al que simplemente llamo un "sombreador", a pesar de que realmente contiene un sombreador de vértices y un sombreador de píxeles (y tal vez sombreadores de geometría / casco / dominio también).

  2. Cada cuadro, una vez que haya encontrado la lista de objetos (mallas) para renderizar, ordénelos por sombreador. La idea es minimizar la cantidad de veces que cambia los sombreadores en un marco, dibujando todos los objetos con un sombreador dado. Esto se debe a que el cambio de sombreadores es una operación algo costosa (aunque ciertamente puede hacerlo varios cientos o mil veces por cuadro, por lo que no es realmente tan costoso).

    De hecho, puede ir un paso más allá y ordenar las mallas por sombreador primero y material segundo. Por "material", me refiero a una combinación de un sombreador y un conjunto de texturas y parámetros para él. Los sombreadores generalmente tienen algunas texturas y parámetros numéricos (almacenados en búferes constantes) que los alimentan, por lo que, por ejemplo, un material de ladrillo y material de asfalto podría usar el mismo código de sombreador, solo que con diferentes texturas.

  3. Para dibujar, simplemente recorra los sombreadores, configure cada sombreador en el ID3D11DeviceContext, configure cualquier parámetro (búferes constantes, texturas, etc.), luego dibuje los objetos. En pseudocódigo, incluida la distinción de sombreadores / materiales que mencioné:

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

Se puede decir mucho más sobre la administración de objetos, mallas, sombreadores, diseños de entrada, buffers constantes, etc., pero esto debería ser suficiente para comenzar. :)

Nathan Reed
fuente
Propone ordenar por sombreador y luego por material. ¿Tiene algún dato sobre el costo de cambiar de sombreador a cambiar de material? Ah, y para DX9, una combinación VS / PS se llama "programa". No estoy tan seguro si todavía usan esa terminología en DX11.
Panda Pyjama
1
@PandaPajama Esa es una buena pregunta. No, no tengo ni conozco ninguna medición reciente del costo real de cambiar materiales o sombreadores. Este enfoque ha sido la "sabiduría común" durante años, pero vale la pena hacer algunas mediciones reales para ver cómo han cambiado las cosas ... tal vez lo haga si puedo encontrar el tiempo. :)
Nathan Reed