Efeito cascata de onda?

9

Estou trabalhando em um jogo de defesa de torre há algum tempo e até agora estou realmente satisfeito com os resultados. No entanto, gostaria de acrescentar uma coisa.

Vi um vídeo do GeoDefense para Windows Phone 7 aqui: http://www.youtube.com/watch?v=YhPr4A4LRPQ

Observe como (quando uma unidade é morta ou um projétil atinge uma unidade), o fundo ondula em algum tipo de efeito de onda.

Como posso fazer um equivalente? Estou pensando que, de alguma forma, preciso fazê-lo no shader de vértice, com um quad feito de muitos vértices.

Qual é a sua ligação?

Editar É importante observar que meu jogo XNA não é feito para Windows phone, mas para PCs com Windows.

Mathias Lykkegaard Lorenzen
fonte

Respostas:

8

O problema é que o XNA no Windows Phone não possui suporte para sombreador personalizado - portanto, você não pode escrever um sombreador de vértice ou sombreador de pixel. No entanto, você pode usar um truque descrito por Catalin Zima que deforma uma grade de vértices para obter o mesmo efeito.

Se você não está direcionando o Windows Phone 7, pode usar um truque que descrevi no meu blog . Copiando os bits relevantes em:

Essas distorções requerem 2 imagens. Primeiro, você precisa de toda a cena como destino de renderização (ou seja, Texture2D), bem como o destino de renderização de distorção. Normalmente, você usaria um sistema de partículas para preencher o alvo de renderização da distorção; usando sprites especiais de distorção (exemplo abaixo).

Cada componente de cor no alvo de distorção (e sprites de distorção) representa o seguinte:

  • R : deslocamento dx: X - f (x) = mapeamento 2x-1 ([0,0f, 1,0f] a [-1,0f, 1,0f]).
  • G : dy: deslocamento Y - f (x) = mapeamento 2x-1.
  • B : m: força Z - f (x) = x mapeamento.

Um bom exemplo de um sprite que seria usado para uma ondulação seria:

Ripple Sprite

Determinar o resultado de uma ondulação é tão simples quanto somar as ondas (tendo em mente o mapeamento necessário primeiro para [-1.0f, 1.0f]); porque as ondas na realidade também são aditivas, isso simplesmente funciona - você terá boas aproximações das ondas reais.

Depois de ter os dois destinos de renderização, você pode usar o seguinte 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 é o efeito final:

Efeito cascata

Essa técnica também deve funcionar para jogos em 3D; embora você precise dedicar mais atenção ao sombreador de partículas e ao sombreamento por distorção.

Jonathan Dickinson
fonte
Não estou fazendo o jogo para Windows Phone. Eu atualizei minha pergunta.
Mathias Lykkegaard Lorenzen
@MathiasLykkegaardLorenzen Tirei algum conteúdo do meu blog e o coloquei na resposta, espero que seja um bom ponto de partida.
Jonathan Dickinson
O exemplo do telefone é bom e é exatamente o que estou tentando fazer. Infelizmente, quero que o efeito se mova com o mundo e não seja baseado nas coordenadas da tela. Isso é possível?
Mathias Lykkegaard Lorenzen
@MathiasLykkegaardLorenzen É definitivamente possível, mas será incrivelmente caro - nesse caso, eu recomendo que você escolha a minha solução. Vou lhe enviar o código, se eu puder encontrá-lo; desde que você prometa não usar nenhuma das minhas obras de arte :).
Jonathan Dickinson
@ Jonathan Dickinson Você poderia nos fornecer o código XNA 4 atualizado?
Amir Rezaei