// --------------------------------------------------------------------------------------------- // // WaterSurface Effect // --------------------------------------------------------------------------------------------- // // // Draws a water surface with reflections coming from a render target texture // /// Matrix that transforms the water surface into world coordinates float4x4 World; /// Matrix that transforms world coordinates into view space float4x4 View; /// Matrix that transforms view space coordinates into screen coordinates float4x4 Projection; /// Inverse view matrix for untransforming projective texture coordinates float4x4 ReflectionView; /// Projective texture containing the water reflection image texture ReflectionTexture; /// Detail texture for the water surface texture WaterTexture; // --------------------------------------------------------------------------------------------- // // Texture Samplers // --------------------------------------------------------------------------------------------- // /// Sampler for the projective reflection texture sampler2D ReflectionSampler = sampler_state { Texture = (ReflectionTexture); AddressU = Mirror; AddressV = Mirror; MinFilter = Linear; MagFilter = Linear; }; /// Sampler for the water detail texture sampler2D WaterSampler = sampler_state { Texture = (WaterTexture); AddressU = Wrap; AddressV = Wrap; MinFilter = Linear; MagFilter = Linear; }; // --------------------------------------------------------------------------------------------- // // Supporting Structures // --------------------------------------------------------------------------------------------- // /// Contains the inputs to the vertex shader struct VertexShaderInput { /// Position of the vertex in world coordinates float4 Position : POSITION0; /// Texture coordinates at the vertex float2 TextureCoordinates : TEXCOORD0; }; /// Outputs generated by the vertex shader struct VertexShaderOutput { /// Position in screen coordinates float4 Position : POSITION0; /// Texture coordinates at the vertex for the water texture float2 WaterTextureCoordinates : TEXCOORD0; /// Texture coordinates at the vertex for the reflection texture float4 ReflectionTextureCoordinates : TEXCOORD1; }; // --------------------------------------------------------------------------------------------- // // Vertex Shader // --------------------------------------------------------------------------------------------- // /// Transforms a vertex into view space /// Vertex fields the vertex shader can access /// The transformed vertex VertexShaderOutput VertexShaderFunction(VertexShaderInput input) { VertexShaderOutput output; // Transform the vertex position from world into view space float4 worldPosition = mul(input.Position, World); float4 viewPosition = mul(worldPosition, View); output.Position = mul(viewPosition, Projection); // The texture coordinates don't need any special processing output.WaterTextureCoordinates = input.TextureCoordinates; // Unproject the vertex position so it will generate texture coordinates // in screen space for the pixel shader worldPosition = mul(input.Position, World); viewPosition = mul(worldPosition, ReflectionView); output.ReflectionTextureCoordinates = mul(viewPosition, Projection); return output; } // --------------------------------------------------------------------------------------------- // // Pixel Shader // --------------------------------------------------------------------------------------------- // /// Calculates the color of a pixel /// Interpolated output of the vertex shader /// The calculated color of the pixel float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0 { float2 projectedTextureCoordinates; projectedTextureCoordinates.x = (input.ReflectionTextureCoordinates.x / input.ReflectionTextureCoordinates.w) * 0.5f + 0.5f; projectedTextureCoordinates.y = (input.ReflectionTextureCoordinates.y / input.ReflectionTextureCoordinates.w) * -0.5f + 0.5f; return tex2D(ReflectionSampler, projectedTextureCoordinates) * 0.5 + tex2D(WaterSampler, input.WaterTextureCoordinates) * 0.5; } // --------------------------------------------------------------------------------------------- // // Technique // --------------------------------------------------------------------------------------------- // technique WaterTechnique { pass NormalPass { ZEnable = true; ZWriteEnable = false; StencilEnable = false; CullMode = CCW; AlphaBlendEnable = true; SrcBlend = SrcAlpha; DestBlend = InvSrcAlpha; VertexShader = compile vs_2_0 VertexShaderFunction(); PixelShader = compile ps_2_0 PixelShaderFunction(); } }