Monday, February 20, 2012

Game Elements 5: Vignette and Shader Parameters

In my previous tutorial I gave a quick introduction to shaders. Now you should have a basic understanding of how to write a simple shader, but now I am going to show how you can control the shader through code using parameters.

To demonstrate this we are going to write a new shader that will produce a vignette effect. A Vignette typically refers to a darkened border around an image that draws the viewers attention to the center. Adding a subtle vignette effect to any game is a good way to make it look more eye catching and less amateurish. A more pronounced vignette can also be used when you want to obscure the players view of the edge of the screen, such as when walking through a dark cave.

Subtle Vignette (Left), No Vignette (Center), Strong Vignette (Right)
The algorithm for producing this vignette is not much different than the grayscale effect shown in the last tutorial so I wont bother explaining it.

sampler TextureSampler : register(s0);
float Intensity= 1;

float4 VignettePS(float2 texCoord : TEXCOORD0) : COLOR0
{
    float4 tex = tex2D(TextureSampler, texCoord);
    float2 dist = texCoord - 0.5f;
    dist.x = 1 - dot(dist, dist);
    tex.rgb *= saturate(pow(dist.x, intensity));
    return tex;
}

technique Colored
{
    pass Pass1
    {
        PixelShader = compile ps_2_0 VignettePS();
    }
}

Notice the variable "intensity" is defined outside of the pixel shader function. This intensity value sets how strong the vignette effect appears. Variables defined outside of the function can be modified from your game as follows:

MyEffect.Parameters["Intensity"].SetValue(5.5f);

Now you can use this to pass input parameters to your shaders. For practice, set a couple of buttons to increment and decrement the intensity values. And as always, let me know in the comments if you used this to produce any interesting results.

No comments:

Post a Comment