tep360:
Let say I have two separate fx files. The first and the second fx actually have the same vertex shader code. When I load these two effect files, will the framework be smart enough to know that they have the same vertex shader code and internally share the function?
No, at least not to my knowledge. I'm pretty sure that the only way that this would result in only one actual vertex shader being compiled and instantiated would be if the same vertex shader were used by two techniques or passes in the same .fx file. Otherwise you'll have duplicate instances of the same vertex shader that function exactly the same, but will still result in the overhead you get from switching shaders.
tep360:
If not, does it mean it's better to put two techniques into one file?
To put that into extreme, if I have a lot of techniques in one file (possibly because material/lighting permutation); you can imagine how long the file can be. I then load the file and clone the effect for each model. So, if I have 100 models, I will have 100 cloned instance of that effect. Would that be efficient? My worry is that each model will have those big humongous shader code. Or the framework will be smart enough to share the code?
Well...it's a very tricky situation. If you pack too much into a single Effect it gets unwieldy pretty quickly...plus if you're using the framework to auto-generate variants of your shaders based on parameters sent to the shader functions, you'll still have the problem of shader-switching overhead to worry about. Using a system that assembles shader fragments or toggles #defines on and off can clean things up and give you many variations, but the downside is that you have to inplement/maintain this system and you will end up with even more individual vertex and pixel shaders (which means overhead from switching a lot).
One tool available that doesn't always get used a lot is static branching. If you have certain things that you want toggled on or off (like diffuse/normal/specular/glow maps, reflections, rim lighting, etc.) you can branch on a shader constant (that's assigned to one of the boolean constant registers) and when you run the shader the branches will get removed (making them "free"). This can help reduce your shader permutations a bit. Techniques like deferred shadowing or deferred shading can also reduce your permutations by decoupling certain parts of the pipeline, but they do of course have their own issues.
Matt Pettineo | DirectX/XNA MVP
Ride into
The Danger Zone |
PIX With XNA Tutorial