Vấn đề là XNA trên Windows Phone không có hỗ trợ đổ bóng tùy chỉnh - vì vậy bạn không thể viết một shader đỉnh hoặc pixel shader. Tuy nhiên, bạn có thể sử dụng một mẹo được mô tả bởi Catalin Zima làm biến dạng lưới đỉnh để đạt được hiệu quả tương tự.
Nếu bạn không nhắm mục tiêu Windows Phone 7, bạn có thể sử dụng một mẹo mà tôi đã mô tả trên blog của mình . Sao chép các bit có liên quan trong:
Những biến dạng này đòi hỏi 2 hình ảnh. Trước tiên, bạn cần toàn bộ cảnh làm mục tiêu kết xuất (ví dụ Texture2D) cũng như mục tiêu kết xuất méo. Thông thường, bạn sẽ sử dụng một hệ thống hạt để lấp đầy mục tiêu kết xuất méo; sử dụng các sprite biến dạng đặc biệt (ví dụ dưới đây).
Mỗi thành phần màu trong mục tiêu biến dạng (và các họa tiết biến dạng) thể hiện như sau:
- R : dx: X offset - ánh xạ f (x) = 2x-1 ([0.0f, 1.0f] thành [-1.0f, 1.0f]).
- G : dy: Y offset - ánh xạ f (x) = 2x-1.
- B : m: Z cường độ - f (x) = x ánh xạ.
Một ví dụ điển hình về một sprite sẽ được sử dụng cho Ripple sẽ là:
Xác định kết quả của Ripple cũng đơn giản như cộng các sóng lại với nhau (hãy nhớ rằng ánh xạ bạn cần thực hiện trước tiên thành [-1.0f, 1.0f]); bởi vì sóng trong thực tế cũng là phụ gia này chỉ hoạt động - bạn sẽ có được xấp xỉ rất tốt của sóng thực.
Khi bạn có hai mục tiêu kết xuất, bạn có thể sử dụng trình đổ bóng sau:
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();
}
}
Đây là hiệu ứng cuối cùng:
Kỹ thuật này cũng sẽ hoạt động cho các trò chơi 3D; mặc dù bạn có thể phải dành nhiều suy nghĩ hơn cho trình tạo bóng hạt và trình tạo bóng biến dạng.