Wellenwelligkeitseffekt?

9

Ich arbeite schon seit einiger Zeit an einem Tower-Defense-Spiel und bin bisher sehr zufrieden mit den Ergebnissen. Eines möchte ich jedoch hinzufügen.

Ich habe hier ein Video von GeoDefense für Windows Phone 7 gesehen: http://www.youtube.com/watch?v=YhPr4A4LRPQ

Beachten Sie, wie (wenn eine Einheit getötet wird oder ein Projektil eine Einheit trifft) sich der Hintergrund in einer Art Welleneffekt kräuselt.

Wie kann ich ein Äquivalent erstellen? Ich denke, dass ich es irgendwie im Vertex-Shader tun muss, mit einem Quad aus vielen Vertices.

Wie ist Ihr Anruf?

Bearbeiten Es ist wichtig zu beachten, dass mein XNA-Spiel nicht für Windows Phone, sondern für Windows-PCs entwickelt wurde.

Mathias Lykkegaard Lorenzen
quelle

Antworten:

8

Das Problem ist, dass XNA unter Windows Phone keine Unterstützung für benutzerdefinierte Shader bietet. Sie können also keinen Vertex-Shader oder Pixel-Shader schreiben. Sie können jedoch einen von Catalin Zima beschriebenen Trick verwenden , der ein Scheitelpunktgitter verformt, um den gleichen Effekt zu erzielen.

Wenn Sie nicht auf Windows Phone 7 abzielen, können Sie einen Trick verwenden, den ich in meinem Blog beschrieben habe . Kopieren der relevanten Bits in:

Diese Verzerrungen erfordern 2 Bilder. Zunächst benötigen Sie die gesamte Szene als Render-Ziel (dh Texture2D) sowie das Verzerrungs-Render-Ziel. Normalerweise verwenden Sie ein Partikelsystem, um das Verzerrungs-Rendering-Ziel zu füllen. mit speziellen Verzerrungs-Sprites (Beispiel unten).

Jede Farbkomponente im Verzerrungsziel (und in den Verzerrungssprites) repräsentiert Folgendes:

  • R : dx: X-Offset - f (x) = 2x-1-Zuordnung ([0.0f, 1.0f] zu [-1.0f, 1.0f]).
  • G : dy: Y-Offset - f (x) = 2x-1-Abbildung.
  • B : m: Z Stärke - f (x) = x Abbildung.

Ein gutes Beispiel für ein Sprite, das für eine Welligkeit verwendet werden würde, wäre:

Ripple Sprite

Das Ermitteln des Ergebnisses einer Welligkeit ist so einfach wie das Addieren der Wellen (unter Berücksichtigung der Zuordnung, die Sie zuerst auf [-1.0f, 1.0f] durchführen müssen); Da Wellen in der Realität auch additiv sind, funktioniert dies einfach - Sie erhalten sehr gute Annäherungen an reale Wellen.

Sobald Sie die beiden Renderziele haben, können Sie den folgenden Shader verwenden:

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

Dies ist der endgültige Effekt:

Welligkeitseffekt

Diese Technik sollte auch für 3D-Spiele funktionieren. obwohl Sie möglicherweise mehr über den Partikel-Shader und den Verzerrungs-Shader nachdenken müssen.

Jonathan Dickinson
quelle
Ich mache das Spiel nicht für Windows Phone. Ich habe meine Frage aktualisiert.
Mathias Lykkegaard Lorenzen
@MathiasLykkegaardLorenzen Ich habe einige Inhalte aus meinem Blog entfernt und in die Antwort eingefügt, hoffentlich gibt es Ihnen einen guten Ausgangspunkt.
Jonathan Dickinson
Das Telefonbeispiel ist nett und genau das, was ich versuche zu tun. Leider möchte ich, dass sich der Effekt mit der Welt bewegt und nicht auf Bildschirmkoordinaten basiert. Ist das möglich?
Mathias Lykkegaard Lorenzen
@MathiasLykkegaardLorenzen Es ist definitiv möglich, aber es wird unglaublich teuer - in diesem Fall empfehle ich Ihnen, sich für meine Lösung zu entscheiden. Ich werde Ihnen den Code zusenden, wenn ich ihn finden kann. solange du versprichst, keines meiner Kunstwerke zu verwenden :).
Jonathan Dickinson
@ Jonathan Dickinson Könnten Sie uns bitte einen aktualisierten XNA 4-Code zur Verfügung stellen?
Amir Rezaei