具体算法见 http://www.cnblogs.com/worldreason/archive/2008/05/09/1189648.html
下面直接上代码:
HLSL:
sampler2D Background : register(s0); //水波背景图片 float dx; //水波网格每个格子的大小 =1/(water.Width-1) float dy; // =1/(water.Height-1) texture Height; //水波网格的高度数据 sampler HeightSampler = sampler_state { Texture = (Height); MipFilter = LINEAR; MinFilter = LINEAR; MagFilter = LINEAR; }; float4 PS(float2 uv : TEXCOORD0) : COLOR0 { float xoff = tex2D(HeightSampler, float2(saturate(uv.x + dx), uv.y)).x - tex2D(HeightSampler, float2(saturate(uv.x - dx), uv.y)).x; float yoff = tex2D(HeightSampler, float2(uv.x, saturate(uv.y + dy))).x - tex2D(HeightSampler, float2(uv.x, saturate(uv.y - dy))).x; uv.x = saturate(uv.x + xoff / 20); uv.y = saturate(uv.y + yoff / 20); float4 color = tex2D(Background, uv); color.rgb += (xoff + yoff) / 2; return color; } technique simple { pass Water { PixelShader = compile ps_2_0 PS(); } }
如果在WPF里使用,对应的HLSL需要做下修改:
float dx : register(C0); float dy : register(C1); sampler2D Background : register(S0); sampler2D Height : register(S1); float4 main(float2 uv : TEXCOORD) : COLOR { float xoff = tex2D(HeightSampler, float2(saturate(uv.x + dx), uv.y)).x - tex2D(HeightSampler, float2(saturate(uv.x - dx), uv.y)).x; float yoff = tex2D(HeightSampler, float2(uv.x, saturate(uv.y + dy))).x - tex2D(HeightSampler, float2(uv.x, saturate(uv.y - dy))).x; uv.x = saturate(uv.x + xoff / 20); uv.y = saturate(uv.y + yoff / 20); float4 color = tex2D(BackgroundSampler, uv); color.rgb += (xoff + yoff) / 2; return color; }
源代码下载 包含C++ & Win32、WinForm & SlimDX、WPF三个版本