# Wave ripple effect?

I've been working on a tower-defense game for some time now, and so far I am really satisfied with the results. However, there's one thing I'd like to add.

I've seen a video of GeoDefense for Windows Phone 7 here: http://www.youtube.com/watch?v=YhPr4A4LRPQ

Notice how (when a unit gets killed or a projectile hits a unit), the background ripples in some kind of wave effect.

How can I make an equivalent? I'm thinking that I somehow need to do it in the vertex shader, with a quad made of many vertices.

Edit It is important to note that my XNA game is not made for Windows phone, but for Windows PCs.

-

The problem is that XNA on Windows Phone doesn't have custom shader support - so you can't write a vertex shader or pixel shader. However, you can use a trick described by Catalin Zima that deforms a vertex grid to achieve the same effect.

If you are not targetting Windows Phone 7, you can use a trick that I described on my blog. Copying the relevant bits in:

These distortions require 2 images. Firstly you need the entire scene as a render target (i.e. Texture2D) as well as the distortion render target. Typically you would use a particle system to fill the distortion render target; using special distortion sprites (example below).

Each color component in the distortion target (and distortion sprites) represents the following:

• R: dx: X offset – f(x)=2x-1 mapping ([0.0f, 1.0f] to [-1.0f, 1.0f]).
• G: dy: Y offset – f(x)=2x-1 mapping.
• B: m: Z strength – f(x)=x mapping.

A good example of a sprite that would be used for a ripple would be:

Determining the outcome of a ripple is as simple as adding the waves together (keeping in mind the mapping you need to perform first to [-1.0f, 1.0f]); because waves in reality are also additive this just works - you will get very good approximations of real waves.

Once you have the two render targets you can use the following shader:

Texture InputTexture; // The distortion map.
Texture LastTexture; // The actual rendered scene.

sampler inputTexture = sampler_state
{
texture = <InputTexture>;
magFilter = POINT;
minFilter = POINT;
mipFilter = POINT;
};

sampler lastTexture = sampler_state
{
texture = <LastTexture>;
magFilter = LINEAR;
minFilter = LINEAR;
mipFilter = LINEAR;
};

struct VS_OUTPUT
{
float4 Position : POSITION;
float2 TexCoords : TEXCOORD0;
};

float4 Distort (VS_OUTPUT Input)
{
float4 color1;
float4 color2;
float2 coords;
float mul;

coords = Input.TexCoords;
color1 = tex2D(inputTexture, coords);

// 0.1 seems to work nicely.
mul = (color1.b * 0.1);

coords.x += (color1.r * mul) - mul / 2;
coords.y += (color1.g * mul) - mul / 2;

color2 = tex2D(lastTexture, coords);

return color2;
}

float4 RunEffects (VS_OUTPUT Input) : COLOR0
{
float4 color;

color = Distort(Input);

return color;
}

technique Main
{
pass P0
{