Each CgFX file usually handles a certain effect such as bump mapping or environment mapping. The CgFX file contains one or more techniques, which describes a way to achieve the effect. Each technique can then target a certain GPU generation so that a more advanced GPU can use a more complex technique, and older graphics hardware can use a simpler one. Different techniques can also be used for level-of-detail or performance fallbacks.
// Used for advanced programmable h/w, e.g. GeForceFX, GeForce series 6, Radeon X800 technique complexPixelandVertexShader { ... } // Used for lower LOD or older programmable h/w, e.g. GeForce3/4, Radeon 9800 technique simplePixelandVertexShader { ... } // Fallback. Used for older non-programmable h/w, e.g. GeForce2 technique fixedFunction { ... }
The application can then query which techniques are available/valid in an effect, and choose an appropriate technique at runtime. CgFX loads and validates the techniques from top to bottom. This means that if techniques are ordered by complexity/requirements, the first valid technique will be the most complex technique available on the users graphics card.
Study the techniques available at the bottom of the file 'carscene-1.fx' available in the solution view in Visual Studio. The file is physically located at:
<Working directory>/fx/
Rendering passes can be used to add complexity to a technique on for example older graphics hardware. For example, an early version of Quake3 uses up to 10 rendering passes for a single frame.
Note how passes are used in the file 'carscene-1.fx'.
Each pass contains render states such as alpha blending (BlendEnable) and depth testing (DepthTestEnable), where each state is a mapping of an OpenGL call. Refer to the Cg reference documentation for further details.
Make sure you understand how render states are used in the file 'carscene-1.fx'.
The CgFX file also contains global and per-technique variables. The variables are usually passed as uniform parameters to functions, or as the value for a render state or texture state setting. The variables can contain a user-defined semantic, which helps applications provide the correct data to the shader without having to use/know the actual variable names.
sampler2D diffuseSampler : DIFFUSE_MAP { ... }; float4x4 viewMatrix : VIEW_MATRIX;
The application can then query the CgFX file for its variables using their names or their semantics.