Hi all, recently I've tried to implement macro support for my effect system. It is working using the d3deffect class. We have some count of *.fx files for each type of entity( atmospherics.fx, water.fx, meshes.fx etc), so if some #ifdef #endif brunching is happened for the some particular technique, we need to recompile all effect (many techniques)/
Now what I wanna do:
1) split each effect to many ones, such a single technique equals one effect, (<name_of_effect>_<name_of_tech>.fx)
2) put common functions separately to the outer *.fxh file, will be included to the each of pointed above effects
so if we need to recompile something, we are doing it at "technique" level, not all effect
Is it right, may be someone has implemented this alghoritm, are you?
Now second, the next common used idea - do not use effect files and d3deffect functionality at all.
pro - we can work at shader level
cons - not easy to implement, we need deal with many registers, and set it manually (some people assigns registers explicitly)
Now the second question - what method are the best? What approach do you using in your projects? Thanks
Well yes, I implemented something like this once, too. I used a shader library storing all shader files I’ve ever compiled with all macros, last file modification dates and modification dates of all included files. On demand I recompiled files if necessary. I used this system for a while, but now I’m kind of back using the effect framework again, since it makes the life a little easier.
If you are allowed to move to the Dx11 API, you can use dynamic shader linkage, which essentially solves all your problems. If you target older hardware or want to keep Dx9, you could go with Nvidia’s Cg, since it has this feature too.
Basically, dynamic shader linkage allows you to define interfaces, which you can implement with “classes”. Now, at bind time of your shader you can assign each interface variable a certain class instance, thereby choosing the branch in your shader code you want to follow. (About three lines of code: get the interface variable, get the class instance, assign class instance to interface variable)
This brings a few extra benefits: Firstly, the code is much cleaner, since you don’t have #ifdefs everywhere. Secondly, the register allocation for the currently selected branch is chosen optimally (well, would be true for #ifdef stuff, too). Thirdly, you don’t have to maintain dozens of compiled shader versions, since everything is contained in your single byte code file. Ultimately, dynamic shader linkage is supposed to solve the ubershader dilemma, which you are facing right now. If you’re more interested in this topic, there was a talk at Gamefest in 2008 on this. You can find the slides (and an audio track!) online somewhere at MSDN. (I can help you searching for it, if you need assistance.)
Personally, I only gathered some experience with the dynamic shader linkage of the Dx11 effect framework and I loved it. I haven’t used CG at all so far, since I just recently learned that it had dynamic shader linkage for years.
Perhaps, you want to take a look at those things, if only to make an informed choice. Take your time, deciding on this one, since it affects very, very, …, very much.