Well it requires some bitwork, ie. shifting and masking. First of all, you'll need to decide yourself the layout of the bits such as
bit 0 : Ambient fog (one bit is enough for yes/no)
bit 1 : Normal map
bit 2-3 : Num Point lights (2 bits is enough for values between 0-3)
As the loop counter presents all the shader permutations, only thing left is to extract each bit field (variable "i" is the loop counter presented in the earlier post):
bool AmbientFog = i & 1; (the desired value is in the first bit so masking out other bits is enough)
bool NormalMap = (i >> 1) & 1; (the desired value is in the second bit so one shift is necessary and masking after)
int NumPointLights = (i >> 2) & 3;
4 bits are used here (you'll need few bits more) so the loop needs to be run 2^4 times.
Shifts are practically multiplies / divisions by 2^(shift value) which effectively will move the bits in the desired positions. After shifting is is necessary to use AND (&) operator to mask out unwanted bits.
The loop creating all the permutations doesn't know about the required usage - ie. it can't know whether a permutation is used or not. Nothing prevents you from creating permutations while program is running (and saving them to disk in order to accelerate the program operation). Of course this maybe produce slowdowns if a new shader permuation is required.
Do i understand this approach correctly: You compile all the shader permutations in runtime (at startup for example)?
Is it possible to compile the shader permutations in build time, but still having the luxury of having them named nicely, so they can be identified at runtime by using the bitmask you suggested above?