คลื่นระลอกคลื่น


9

ฉันทำงานเกมป้องกันหอคอยมาระยะหนึ่งแล้วและตอนนี้ฉันก็พอใจกับผลลัพธ์มาก อย่างไรก็ตามมีสิ่งหนึ่งที่ฉันต้องการเพิ่ม

ฉันเคยเห็นวิดีโอของ GeoDefense สำหรับ Windows Phone 7 แล้วที่นี่: http://www.youtube.com/watch?v=YhPr4A4LRPQ

โปรดสังเกตว่า (เมื่อยูนิตถูกฆ่าหรือกระสุนปืนชนกับยูนิต) พื้นหลังจะเป็นระลอกคลื่นในเอฟเฟกต์ของคลื่นบางประเภท

ฉันจะทำให้เทียบเท่าได้อย่างไร ฉันคิดว่าฉันต้องทำมันในจุดสุดยอดด้วยรูปสี่เหลี่ยมที่ทำจากจุดยอดต่างๆ

คุณโทรอะไร

แก้ไขเป็นสิ่งสำคัญที่จะต้องทราบว่าเกม XNA ของฉันไม่ได้สร้างขึ้นสำหรับ Windows phone แต่สำหรับพีซี Windows

คำตอบ:


8

ปัญหาคือ XNA บน Windows Phone ไม่มีการรองรับ Shader ที่กำหนดเองดังนั้นคุณจึงไม่สามารถเขียน Shader ที่จุดสุดยอดหรือ Pixel Shader ได้ อย่างไรก็ตามคุณสามารถใช้เคล็ดลับที่อธิบายโดยCatalin Zimaที่เปลี่ยนรูปตารางจุดสุดยอดเพื่อให้ได้ผลเช่นเดียวกัน

ถ้าคุณไม่ได้กำหนดเป้าหมาย Windows Phone 7 คุณสามารถใช้เคล็ดลับที่ผมอธิบายไว้ในบล็อกของฉัน การคัดลอกบิตที่เกี่ยวข้องใน:

การบิดเบือนเหล่านี้ต้องใช้ 2 ภาพ ก่อนอื่นคุณต้องใช้ฉากทั้งหมดเป็นเป้าหมายของการเรนเดอร์ (เช่น Texture2D) เช่นเดียวกับการบิดเบือนเรนเดอร์เป้าหมาย โดยทั่วไปคุณจะใช้ระบบอนุภาคเพื่อเติมเต็มเป้าหมายการแสดงผลที่ผิดเพี้ยน ใช้สไปรต์บิดเบือนพิเศษ (ตัวอย่างด้านล่าง)

องค์ประกอบสีแต่ละสีในเป้าหมายการบิดเบือน (และสไปรต์การบิดเบือน) แสดงถึงสิ่งต่อไปนี้:

  • R : dx: X offset - f (x) = การแมป 2x-1 ([0.0f, 1.0f] ถึง [-1.0f, 1.0f])
  • G : dy: Y offset - f (x) = การทำแผนที่ 2x-1
  • B : m: Z strength - f (x) = x การแมป

ตัวอย่างที่ดีของสไปรต์ที่จะใช้สำหรับระลอกคลื่นคือ:

ระลอกคลื่นเทพดา

การกำหนดผลลัพธ์ของระลอกนั้นง่ายพอ ๆ กับการเพิ่มคลื่นเข้าด้วยกัน (โปรดจำไว้ว่าการทำแผนที่ที่คุณต้องทำก่อนถึง [-1.0f, 1.0f]); เพราะคลื่นในความเป็นจริงก็เป็นเช่นนี้เช่นกัน - คุณจะได้รับการประมาณค่าที่ดีของคลื่นจริง

เมื่อคุณมีเป้าหมายการแสดงผลสองแบบคุณสามารถใช้ 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();
    }
}

นี่คือผลสุดท้าย:

ระลอกผล

เทคนิคนี้ควรใช้กับเกม 3 มิติเช่นกัน แม้ว่าคุณอาจจะต้องอุทิศความคิดให้กับ shader อนุภาคและ shader ที่บิดเบือนมากขึ้น


ฉันไม่ได้สร้างเกมสำหรับ Windows Phone ฉันได้อัปเดตคำถามของฉันแล้ว
Mathias Lykkegaard Lorenzen

@MathiasLykkegaardLorenzen ฉันยกเนื้อหาออกจากบล็อกของฉันและใส่ไว้ในคำตอบหวังว่ามันจะช่วยให้คุณเป็นจุดเริ่มต้นที่ดี
Jonathan Dickinson

ตัวอย่างโทรศัพท์เป็นสิ่งที่ดีและเป็นสิ่งที่ฉันพยายามทำ น่าเสียดายที่ฉันต้องการให้เอฟเฟกต์เคลื่อนไหวไปพร้อมกับโลกและไม่ขึ้นอยู่กับพิกัดของหน้าจอ เป็นไปได้ไหม
Mathias Lykkegaard Lorenzen

@MathiasLykkegaardLorenzen เป็นไปได้แน่นอน แต่มันจะมีราคาแพงอย่างไม่น่าเชื่อ - ในกรณีนี้ฉันขอแนะนำให้คุณไปหาทางออกของฉัน ฉันจะส่งรหัสให้คุณทางไปรษณีย์หากฉันสามารถหาได้ ตราบใดที่คุณสัญญาว่าจะไม่ใช้งานศิลปะใด ๆ ของฉัน :)
Jonathan Dickinson

@ Jonathan Dickinson คุณช่วยส่งรหัส XNA 4 ที่อัปเดตใหม่ให้เราได้ไหม
Amir Rezaei
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.