Take the 2-minute tour ×

I am learning Direct3D 11, and in all basic tutorials I found on shader writing, Vertex and Pixel shaders are written so they transform whole scene same way. Tutorials like render cube with texture...

But I wonder, how do you differentiate objects? What if you want, for example, to simulate mirror surface on some object and use different shaders to render rest of the scene? I think that most games must use many vertex and pixel shaders to achieve various look and transformations.

Thank you.

share|improve this question

1 Answer 1

up vote 12 down vote accepted

Yes, a game engine will in general have a variety of different shaders. The typical pattern is:

  1. While initializing the engine and loading the game world, prepare all the shaders you will use for rendering. By "prepare" I mean load them into memory, compile them if necessary, and do all the ID3D11Device::CreatePixelShader and similar calls to get the D3D shader objects allocated and ready to go. Keep the objects in an array or some other data structure.

    Usually you will have a one-to-one relationship between vertex shaders and pixel shaders that are designed to work together. I think of them as a single object, which I just call a "shader", even though it really contains a vertex shader and a pixel shader (and maybe geometry/hull/domain shaders as well).

  2. Each frame, once you have found the list of objects (meshes) to render, sort them by shader. The idea is to minimize the number of times you switch shaders in a frame, by drawing all the objects with a given shader together. This is because switching shaders is a somewhat expensive operation (although you can certainly do it several hundred or a thousand times per frame, so it's not really that expensive).

    In fact, you can go one step further and sort meshes by shader first and material second. By "material", I mean a combination of a shader and a set of textures and parameters for it. Shaders usually have some textures and numeric parameters (stored in constant buffers) that feed into them, so for instance a brick material and asphalt material might use the same shader code, just with different textures.

  3. To draw, just loop over the shaders, set each shader in the ID3D11DeviceContext, set any parameters (constant buffers, textures, etc.), then draw the objects. In pseudocode, including the shaders/materials distinction I mentioned:

    for each shader:
        // Set the device context to use this shader
        for each material that uses this shader:
            // Set the device context to use any constant buffers, textures, samplers,
            // etc. needed for this material
            for each mesh that uses this material:
                // Set any constant buffers containing parameters specific to the mesh
                // (e.g. world matrix)
                // Set the context to use the vertex & index buffers for this mesh
                // Draw it

There's a lot more that could be said about managing objects, meshes, shaders, input layouts, constant buffers, etc. but this should be enough to get you started. :)

share|improve this answer
This really helped, thank you. –  Jan Tobola Feb 22 '13 at 8:42
You propose sorting by shader and then by material. Do you have any hard data on the cost of switching shaders vs switching materials? Oh, and for DX9, a VS/PS combination is called "program". I'm not so sure if they still use that terminology in DX11. –  Panda Pajama Feb 22 '13 at 10:10
@PandaPajama That's a good question. No, I don't have or know of any recent measurements of the actual cost of switching materials or shaders. This approach has been the "common wisdom" for years, but it's worth doing some actual measurements to see how things have changed...maybe I'll do that if I can find the time. :) –  Nathan Reed Feb 22 '13 at 18:21

Your Answer


