I have been working on a material system and for the most part everything works just fine, however, I hard code the shader that will be used. Obviously this causes a problem when I want to have the materials be saved through the material editor.

What I ended up doing was having the material save "attributes". These attributes would know if the material is using a texture or diffuse color (that's it for now). I then have a VS/PS to render objects with a texture or a diffuse color. Then for each of those, I have shaders for either no lighting, or my lighting system. Right there that will leave eight different shaders, so you can see where the complexity comes in with which ones to pick. Also, that is only if all the objects all have the same vertex type (position, tex coord, normal). However, that is not always the case, as some times the geometry may be built differently.

My question is, how can a propery shader lookup system be written for a material system? There comes into two things I can think of

  1. Shaders based upon different lighting models
  2. Shaders based upon different vertex formats

2 Answers 2


One practice I've used is to write one big file of unified shader code with features wrapped in #defines that are turned on/off at compile time. The various parameters that feed into this shader source are used to create a hash value which is used to key the resulting shader binary for fast lookup.

There is an intermediary, a container for the binary shader output that acts like a little database using the hash value as the key to the shader itself.

You have two options for compiling these shader binaries. First option would be to precompile everything and ship out the binaries, this is sub-optimal on different hardware but very nice for the end user's first runtime experience. Second option would let the end user's computer compile the shaders when encountered or (better) when first run as a setup step. That option would be slightly faster but the end user gets an extended setup during their first runtime.

  • \$\begingroup\$ For the way you practiced, are you looking up the shader at runtime or in a initialization? \$\endgroup\$
    – judeclarke
    Sep 10, 2011 at 20:26
  • \$\begingroup\$ At runtime each material has all the information to generate the hash to lookup the final shader. Generate the hash when the material is loaded and initialized, the lookup in the hash table is fast enough to use whenever it is needed for rendering. A bonus is that if you're batching by material in your renderer you can use the hash to check equality instead of a long series of comparisons. \$\endgroup\$ Sep 11, 2011 at 5:15

One common way to reduce the huge number of extra shader combinations that a standard lighting system will give you is to use deferred shading.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .