otherwise I would always need two different shaders for double and single sided stuff
That is the way it is - regarding most shader permutation issues. I have the same problems here, like object shaders with have to support some stuff if a certain flag is set or not. My solution is for now and forever:
- mask out the optional shader parts with #define's
- implement a structure that holds all shader permutations
- write a generic shader compiler function, that can get a char* for the fx file and a string as define-list parameter and put it together (define list before shader text) and compile it
- write a special function, that loads the structure with teh shaders through different calls for the shader compiler to generate all needed permutations
- write a function, that returns a MATERIAL* and gets an entity or soem arguments or whatever, which selects the appropriate shader
This way you generate all necessary shaders, whereas each shader has zero overhead, because unnecessary stuff has been "compiled out". The function then encapsulates arbitrary logic for what shader to use in which circumstance.
This way, you can e.g. redefine flag1 as doublesided material and then select the double-sided permutation of your e.g. object shader.
The downside is that you have to maintain several things and that shader loading time increases by the amount of permutations, but the benefits are extremely optimized shaders and dynamically loadable shaders (you could bake in constants, useful for unrolling arbitrary loops, which amount is defined during runtime, like blur samples in DOF shaders or so...).