Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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.

What's your call?

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

share|improve this question
add comment

1 Answer 1

up vote 8 down vote accepted

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:

Ripple Sprite

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;
    addressU = CLAMP;
    addressV = CLAMP;
};

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
    {
        PixelShader = compile ps_2_0 RunEffects();
    }
}

This is the final effect:

Ripple Effect

This technique should also work for 3D games; although you might have to dedicate more thought to the particle shader and the distortion shader.

share|improve this answer
    
I am not making the game for Windows Phone. I've updated my question. –  Mathias Lykkegaard Lorenzen Oct 6 '11 at 8:36
    
@MathiasLykkegaardLorenzen I lifted some content off my blog and put it in the answer, hopefully it gives you a good starting point. –  Jonathan Dickinson Oct 6 '11 at 9:04
    
The phone example is nice and is exactly what I am trying to do. Unfortunately, I want the effect to move with the world, and not be based on screen coordinates. Is that possible? –  Mathias Lykkegaard Lorenzen Oct 6 '11 at 14:42
    
@MathiasLykkegaardLorenzen It's definitely possible, but it will be incredibly expensive - in which case I recommend you go for my solution. I will mail you the code if I can find it; as long as you promise to not use any of my artwork :). –  Jonathan Dickinson Oct 6 '11 at 18:34
    
@Jonathan Dickinson Could you please provide us with updated XNA 4 code? –  Amir Rezaei Jan 3 '12 at 21:10
show 6 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.