You could define a function:
void FogPixel(inout vec4 colour, vec3 position)
and when you create your shaders on the fly, if you’re not doing fogging, insert a string:
void FogPixel(inout vec4 colour, vec3 position)
{
// do nothing, passthrough
}
and when you want to do fogging, insert a different string:
void FogPixel(inout vec4 colour, vec3 position)
{
// fog implementation
}
So that the fog function is behaving sort of like a virtual function / abstract interface that you can call in your materials without worrying about the implementation.
If you look in GPU gems, there’s an article about interfaces in Cg, which just formalizes the above.
Unfortunately, I’ve tried something like this before, and its really slow… compiling a one line glsl shader takes about 40ms on my machine, compiling 6 different (short) shaders took close to 1 second. I think nvidia needs to optimize their glsl compiler more…
So if you going to go with the compile-on-the-fly route, then you’ll need some method to cache your shaders, or perhaps you build them all ahead of time at level load, rather compiling them on the fly…
Also, if you do things this way, you’ll run into inefficiency problems. What if in your FogPixel() function you sometimes want to use linear fog, and sometimes radial distance fog? What if by chance you’re already calculating the radial distance in your main shader, should you have to calculate it again in your fog shader?