My goals for hardware shader support was simple: from the game's/designer's point of view, any Cg or HLSL effect should look like a native object/material (i.e. totally indistinguishable from a built in C++ class). I didn't want the designer to have to create a CgShader object and then assign the shader to it. I wanted the game to automagically create dynamic classes on the fly that represented each of the Cg/HLSL effects it finds, and those classes should expose properties for each of the Cg/HSLS uniform parameters.
This does two things: it hides "how" a material is implemented (fixed function vs shader, Cg vs HLSL, C++ vs effect, etc) so that I can change how a material is implemented without breaking files that use it, and secondly, it allows you to connect or animate shader parameters just like any other object in the game.
Here's a shot of the current integration:
All the Shaders you see are just sucked right out of the Shader directory at startup (hence names like "shadow_PCSS" and "OldDepthOfField"). If you look at the Plastic object, you can see it has Specular and Diffuse powers, controls for the Fresnel reflection, etc all driven straight off Plastic.cgfx. It's actually pretty robust, you can drop most of the Cg effects off the web in and play with them.
Under the hood, this is built on top of a new "MetaObject" object that lets you dynamically build and then instantiate new types for the Object system on the fly. In this case, the CgShader class (indirectly) derives from MetaObject and uses it to dynamically register a new class for each .cgfx file it finds, creating properties for each Cg parameter in each effect. It then overrides all the Property methods to pipe them down into the Cg runtime (so that setting a game property will actually change the Cg program state if that instance is actually bound to the Cg program).
I also knocked up a quick DDS file reader so I could support some of the sample textures ... but there are still lots of limitation in texture support in general (no 1D, 3D or cubemaps, no hardware support for texture compression, etc).
Next time, we'll take a look at lighting. Keen eyed readers may already have found a clue in the screenshot (while the Metal shader has the typical hard coded light parameters, the Plastic one is strangely devoid of any light inputs).
Cheers!
How'd you do the plastic shader? I like the effect.