¿Efecto ondulación?

9

He estado trabajando en un juego de defensa de la torre durante algún tiempo, y hasta ahora estoy realmente satisfecho con los resultados. Sin embargo, hay una cosa que me gustaría agregar.

He visto un video de GeoDefense para Windows Phone 7 aquí: http://www.youtube.com/watch?v=YhPr4A4LRPQ

Observe cómo (cuando una unidad muere o un proyectil golpea una unidad), el fondo se ondula en algún tipo de efecto de onda.

¿Cómo puedo hacer un equivalente? Estoy pensando que de alguna manera necesito hacerlo en el sombreador de vértices, con un quad hecho de muchos vértices.

Cual es tu llamada

Editar Es importante tener en cuenta que mi juego XNA no está hecho para Windows phone, sino para PC con Windows.

Mathias Lykkegaard Lorenzen
fuente

Respuestas:

8

El problema es que XNA en Windows Phone no tiene soporte de sombreador personalizado, por lo que no puede escribir un sombreador de vértices o sombreadores de píxeles. Sin embargo, puede usar un truco descrito por Catalin Zima que deforma una cuadrícula de vértice para lograr el mismo efecto.

Si no está apuntando a Windows Phone 7, puede usar un truco que describí en mi blog . Copiando los bits relevantes en:

Estas distorsiones requieren 2 imágenes. En primer lugar, necesita toda la escena como un objetivo de renderizado (es decir, Texture2D), así como el objetivo de renderizado de distorsión. Por lo general, usaría un sistema de partículas para llenar el objetivo de renderizado de distorsión; utilizando sprites especiales de distorsión (ejemplo a continuación)

Cada componente de color en el objetivo de distorsión (y los sprites de distorsión) representa lo siguiente:

  • R : dx: desplazamiento X - f (x) = mapeo 2x-1 ([0.0f, 1.0f] a [-1.0f, 1.0f]).
  • G : dy: desplazamiento de Y - f (x) = mapeo 2x-1.
  • B : m: Fuerza Z - f (x) = x mapeo.

Un buen ejemplo de un sprite que se usaría para una onda sería:

Sprite ondulado

Determinar el resultado de una onda es tan simple como sumar las ondas (teniendo en cuenta el mapeo que debe realizar primero en [-1.0f, 1.0f]); porque las ondas en realidad también son aditivas, esto simplemente funciona : obtendrá muy buenas aproximaciones de ondas reales.

Una vez que tenga los dos objetivos de renderizado, puede usar el siguiente sombreador:

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();
    }
}

Este es el efecto final:

Efecto dominó

Esta técnica también debería funcionar para juegos 3D; aunque es posible que deba dedicar más atención al sombreador de partículas y al sombreador de distorsión.

Jonathan Dickinson
fuente
No estoy haciendo el juego para Windows Phone. He actualizado mi pregunta.
Mathias Lykkegaard Lorenzen
@MathiasLykkegaardLorenzen Quité parte del contenido de mi blog y lo puse en la respuesta, espero que te brinde un buen punto de partida.
Jonathan Dickinson
El ejemplo del teléfono es bueno y es exactamente lo que estoy tratando de hacer. Desafortunadamente, quiero que el efecto se mueva con el mundo y no se base en las coordenadas de la pantalla. ¿Es eso posible?
Mathias Lykkegaard Lorenzen
@MathiasLykkegaardLorenzen Definitivamente es posible, pero será increíblemente costoso, en cuyo caso te recomiendo que busques mi solución. Le enviaré el código por correo si puedo encontrarlo; siempre y cuando prometas no usar ninguna de mis ilustraciones :).
Jonathan Dickinson el
@ Jonathan Dickinson ¿Podría proporcionarnos un código XNA 4 actualizado?
Amir Rezaei