Masalahnya adalah bahwa XNA di Windows Phone tidak memiliki dukungan kustom shader - jadi Anda tidak dapat menulis shader vertex atau pixel shader. Namun, Anda dapat menggunakan trik yang dijelaskan oleh Catalin Zima yang merusak bentuk vertex grid untuk mencapai efek yang sama.
Jika Anda tidak menargetkan Windows Phone 7, Anda dapat menggunakan trik yang saya jelaskan di blog saya . Menyalin bit yang relevan di:
Distorsi ini membutuhkan 2 gambar. Pertama, Anda perlu seluruh adegan sebagai target render (yaitu Texture2D) serta target render distorsi. Biasanya Anda akan menggunakan sistem partikel untuk mengisi target render distorsi; menggunakan sprite distorsi khusus (contoh di bawah).
Setiap komponen warna dalam target distorsi (dan sprite distorsi) mewakili yang berikut:
- R : dx: X offset - f (x) = pemetaan 2x-1 ([0,0f, 1.0f] hingga [-1.0f, 1.0f]).
- G : dy: Y offset - f (x) = pemetaan 2x-1.
- B : m: Z kekuatan - f (x) = x pemetaan.
Contoh yang baik dari sprite yang akan digunakan untuk riak adalah:
Menentukan hasil riak semudah menambahkan gelombang bersama-sama (perhatikan pemetaan yang harus Anda lakukan terlebih dahulu untuk [-1.0f, 1.0f]); karena gelombang pada kenyataannya juga aditif ini hanya berfungsi - Anda akan mendapatkan perkiraan yang sangat baik dari gelombang nyata.
Setelah Anda memiliki dua target render, Anda dapat menggunakan shader berikut:
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();
}
}
Ini adalah efek terakhir:
Teknik ini juga bisa digunakan untuk gim 3D; meskipun Anda mungkin harus mendedikasikan lebih banyak pemikiran untuk shader partikel dan shader distorsi.