// Vertex program for fresnel reflections / refractions void main_vp( float4 pos : POSITION, float4 normal : NORMAL, float2 tex : TEXCOORD0, out float4 oPos : POSITION, out float fresnel : COLOR, out float3 noiseCoord : TEXCOORD0, out float4 projectionCoord : TEXCOORD1, uniform float4x4 worldViewProjMatrix, uniform float3 eyePosition, // object space uniform float fresnelBias, uniform float fresnelScale, uniform float fresnelPower, uniform float timeVal, uniform float scale, // the amount to scale the noise texture by uniform float scroll, // the amount by which to scroll the noise uniform float noise // the noise perturb as a factor of the time ) { oPos = mul(worldViewProjMatrix, pos); // Projective texture coordinates, adjust for mapping float4x4 scalemat = float4x4(0.5, 0, 0, 0.5, 0,-0.5, 0, 0.5, 0, 0, 0.5, 0.5, 0, 0, 0, 1); projectionCoord = mul(scalemat, oPos); // Noise map coords noiseCoord.xy = (tex + (timeVal * scroll)) * scale; noiseCoord.z = noise * timeVal; // calc fresnel factor (reflection coefficient) float3 eyeDir = normalize(pos.xyz - eyePosition); fresnel = fresnelBias + fresnelScale * pow(1 + dot(eyeDir, normal), fresnelPower); } // Fragment program for distorting a texture using a 3D noise texture void main_fp( float fresnel : COLOR, float3 noiseCoord : TEXCOORD0, float4 projectionCoord : TEXCOORD1, out float4 col : COLOR, uniform float distortionRange, uniform float4 tintColour, uniform sampler3D noiseMap, uniform sampler2D reflectMap, uniform sampler2D refractMap ) { // Randomly chosen offset for y noise sample float3 yoffset = float3(0.31, 0.58, 0.23); float2 distort; // Sample the noise texture at 2 places distort.x = tex3D(noiseMap, noiseCoord).x; distort.y = tex3D(noiseMap, noiseCoord + yoffset).x; // Scale the distortion from [0,1] to [-range,range] distort = (distort * 2 - 1) * distortionRange; // Do the tex projection manually so we can distort _after_ float2 final = projectionCoord.xy / projectionCoord.w; final += distort; float4 reflectionColour = tex2D(reflectMap, final); float4 refractionColour = tex2D(refractMap, final) + tintColour; col = lerp(refractionColour, reflectionColour, fresnel); }