ปัญหาคือ 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 ที่บิดเบือนมากขึ้น