Hi folks,
I'm working on some engine-y kind of stuff (although not quite a full engine). I wrote a resource manager and a loader for .obj and .mtl files and can currently draw 3D models to the screen. Pretty neat.
The problem I am having is that not all .mtl (material) files have the same "variables". For example, some may have a reference to a normal map file, while others don't. Some may have specular constants and exponents defined, while others may not, and others still may define constants and textures for them.
Separate from the differences in materials, the number of lights affecting a mesh may differ from object to object.
Right now, my shader is just reading the diffuse texture and ignoring everything else, but obviously I want to be able to handle all of the other possibilities.
I see two options to handle all of these combinations of scenarios:
1. Have a "god"-shader that has some max # of lights (say, 5) and handles everything the .mtl file may have: ambient, diffuse, specular, specular exponent, and normal maps. If the actual material being rendered didn't have one of those terms in the .mtl file, (a) use a "default" value for it in the shader, or (b) possibly detect that it isn't in use and don't include it in the calculation. I don't like (b) so much because that would likely require a lot of branching, which is bad news.
2. Have one shader per configuration. So one shader that handles ambient, diffuse, and specular without any texture maps. One that handles it with texture maps. One that handles it only with diffuse texture map. For each of the previously mentioned, have versions that handle 1, 2, 3, 4, and 5 lights. Etc. etc. etc. Obviously this could get out of control pretty fast, but it seems to be the best as far as avoiding unnecessary computational costs. I am leaning towards doing things this way and writing some sort of custom shader "template" that at run-time can be transformed into the exact shader I need depending on the configurations of the material and # of lights.
I have searched pretty extensively and couldn't quite find an agreed-upon answer for this. I know that Unity allows you to write shader "templates" a la option 2 and uses #ifdef statements to compile the various parts in or out. However, if anyone here with more experience has any other suggestions to offer I would love to hear them.
Thanks a bunch!