Problem polega na tym, że XNA w Windows Phone nie ma niestandardowej obsługi modułu cieniującego - więc nie można pisać modułu cieniującego wierzchołków ani modułu cieniującego piksele. Możesz jednak użyć sztuczki opisanej przez Catalin Zima, która deformuje siatkę wierzchołków, aby osiągnąć ten sam efekt.
Jeśli nie celujesz w Windows Phone 7, możesz skorzystać ze sztuczki opisanej na moim blogu . Kopiowanie odpowiednich bitów w:
Te zniekształcenia wymagają 2 zdjęć. Po pierwsze, potrzebna jest cała scena jako cel renderowania (tj. Texture2D), a także cel renderowania zniekształceń. Zazwyczaj używasz układu cząstek do wypełnienia celu renderowania zniekształceń; za pomocą specjalnych duszków zniekształcających (przykład poniżej).
Każdy składnik koloru w docelowym zniekształceniu (i duszkach zniekształcających) reprezentuje następujące elementy:
- R : dx: X offset - f (x) = mapowanie 2x-1 ([0,0f, 1,0f] na [-1,0f, 1,0f]).
- G : dy: przesunięcie Y - f (x) = mapowanie 2x-1.
- B : m: Z wytrzymałość - f (x) = x mapowanie.
Dobrym przykładem duszka, który byłby użyty do tętnienia byłoby:
Określenie wyniku tętnienia jest tak proste, jak dodanie fal razem (pamiętając o odwzorowaniu, które należy wykonać najpierw na [-1.0f, 1.0f]); ponieważ fale w rzeczywistości również są addytywne, to po prostu działa - otrzymasz bardzo dobre przybliżenie rzeczywistych fal.
Po uzyskaniu dwóch celów renderowania możesz użyć następującego modułu cieniującego:
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();
}
}
To jest efekt końcowy:
Ta technika powinna również działać w przypadku gier 3D; chociaż być może będziesz musiał poświęcić więcej uwagi modułowi cieniującemu i modułowi zniekształceń.