问题在于Windows Phone上的XNA不支持自定义着色器-因此您不能编写顶点着色器或像素着色器。但是,您可以使用Catalin Zima描述的技巧使顶点网格变形以达到相同的效果。
如果您的目标不是Windows Phone 7,则可以使用我在博客中描述的技巧。复制相关位:
这些失真需要2张图像。首先,您需要将整个场景作为渲染目标(即Texture2D)以及变形渲染目标。通常,您将使用粒子系统来填充变形渲染目标。使用特殊的变形精灵(下面的示例)。
变形目标(和变形精灵)中的每个颜色分量表示以下内容:
- R:dx:X偏移– f(x)= 2x-1映射([0.0f,1.0f]到[-1.0f,1.0f])。
- G:dy:Y偏移– f(x)= 2x-1映射。
- B:m:Z强度– f(x)= x映射。
一个用于涟漪的精灵的好例子是:
确定波动的结果就像将波加在一起一样简单(请记住,首先需要执行到[-1.0f,1.0f]的映射);因为现实中的波浪也是加法的,所以这是可行的 -您将获得非常近似真实的波浪。
一旦有了两个渲染目标,就可以使用以下着色器:
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();
}
}
这是最终效果:
此技术也应适用于3D游戏。尽管您可能不得不更多地考虑粒子着色器和变形着色器。