Monday, April 25, 2011

Multiple techniques in one effect

In our effect files we can have more than just one technique. Different techniques can have different number of passes and can call different pixel and vertex shaders, it's all very simple but still, it's worth mentioning.

For different techniques to have any reason to exist they must have something different. For example they could compile different shaders:

technique Single
{
    pass Pass1
    {
        VertexShader = compile vs_3_0 VS();
        PixelShader = compile ps_3_0 PSSingle();
    }
}
 
technique Additive
{
    pass Pass1
    {
        VertexShader = compile vs_3_0 VS();
        PixelShader = compile ps_3_0 PSAdditive();
    }
}

Here I have 2 techniques (from the same file) that use the same vertex shader but a different pixel shader. Here is an example of why I would like to have 2 techniques in the same file, to reuse the code (of course you can always use includes for that).

Within a pass you don't have to just set the shaders you want to use, you can also set render states (I will only talk about 2). For example adding this line within an effect pass will make it draw all geometry in Wireframe:

        FillMode = Wireframe;

Fill mode specifies how objects should be drawn, the accepted values are Wireframe and Solid. Solid is the type of rendering we have used so far, coloring the whole polygon. Wireframe tells the GPU to only render the edges of an object.
When we draw in wireframe we see that only the polygons that we would normally see are drawn, this is caused by culling. Polygon culling means that only polygons facing us will be rendered (the front of the polygon is determined by the order of it's vertices). The render state name is CullMode and the values you can set are None, CW and CCW. Setting the CullMode to None will force all polygons to be drawn to the screen so you'll be able to see all polygon edges in wireframe mode. The other too settings tell the graphics card to cull faces with vertices in a certain order. The default is CCW, this will cull counter clockwise polygons. If you set CW you will cull clockwise polygons, this will allow you to see the interior of the object (this is relative to how 3D models are created, I'm talking for the default case in XNA).

Ok, now that we have more than just one technique we have to be able to select the technique from the application. To do this we change the CurrentTechnique of our effect. Note that the CurrentTechnique has to be an item from the Techniques arrays of our effect. We can index the techniques by number of name, once again I recommend using names as you could always add a new techniques between the others and change the order in the array. The line of code to select the technique is:

effect.CurrentTechnique = effect.Techniques["Additive"];

Above I have set the CurrentTechnique of the effect object to the Additive technique.

As I mentioned earlier, different techniques can have different number of passes. If we don't care how many passes it has and just want to render all techniques in the same way we can use the following code line:

    foreach (EffectPass pass in effect.CurrentTechnique.Passes)
    {
        pass.Apply();
        GraphicsDevice.Draw...
    }

We only have to iterate throw each pass in the current technique, apply it and then render the geometry with that pass.

No comments:

Post a Comment