BasicEffect: a misnomer?

Originally posted to Shawn Hargreaves Blog on MSDN, Friday, August 22, 2008

XNAThomas asks:

"I tried with all the models from the Spacewar starter kit and they seem to all have the same problem. The cockpit and engine exhausts never get the correct material/texture/lighting, although the fuselage looks fine."

Short answer: the bodies of the Spacewar ships have texture maps, but the cockpits do not. To render these correctly, your shader should disable texturing and just use the material color instead.

Longer answer: this provides a great example of why BasicEffect is actually not so basic after all! Shader permutations are the bane of graphics engine developers, and BasicEffect supports many permutations:

Two texture modes (on, off) plus two vertex color modes (on, off) and three lighting modes (off, per-vertex, per-pixel) ends up requiring 2*2*3 = 12 different versions of the BasicEffect shader.

Not all of these shaders can be used with every model. If the shader does not match its input data, things will render incorrectly. You will get unpredictable results if:

What exactly do I mean by unpredictable? On some graphics cards the rendering will come out white, while on others it may be black. If you use the debug DirectX runtime, you will get an error. This is not a good place to be!

People using BasicEffect through the Content Pipeline are often unaware of these shader variations, because the build process takes care of them for you:

Thanks to this processor magic, most models "just work" without you having to think too hard about it. But if you do stop to think, you will realize that what looks like a single BasicEffect is in fact 12 different shaders masquerading as one. This only works because the Content Pipeline has some smarts to examine your model data and automatically choose the right version of BasicEffect for each object.

If you use a custom shader instead of BasicEffect, the default content processors will no longer understand how to set it up for you. This leaves you with two choices:

  1. You could make your shader as complicated as BasicEffect, creating several versions to match different source data, and then write some code (either in a custom processor or while your game is loading) to choose the right shader for each object.

  2. Or you can simplify things by imposing restrictions on your source artwork. For instance many games decide something like "all our objects are going to be lit, and will be textured, and will not use vertex colors". This can make it dramatically easier to write and manage your shaders.
Blog index   -   Back to my homepage