// Vertex program for fresnel reflections / refractions
void main_vp(
		float4 pos			: POSITION,
		float4 normal		: NORMAL,
		float2 tex			: TEXCOORD0,
		
		out float4 oPos		: POSITION,
		out float3 noiseCoord : TEXCOORD0,
		out float4 projectionCoord : TEXCOORD1,
		out float3 oEyeDir : TEXCOORD2, 
		out float3 oNormal : TEXCOORD3, 

		uniform float4x4 worldViewProjMatrix,
		uniform float3 eyePosition, // object space
		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;

	oEyeDir = normalize(pos.xyz - eyePosition); 
	oNormal = normal.rgb; 
	
}

// Fragment program for distorting a texture using a 3D noise texture
void main_fp(
		float3 noiseCoord			: TEXCOORD0,
		float4 projectionCoord		: TEXCOORD1,
		float3 eyeDir				: TEXCOORD2,
		float3 normal				: TEXCOORD3,
		
		out float4 col		: COLOR,
		
		uniform float4 tintColour,
		uniform float noiseScale, 
		uniform float fresnelBias,
		uniform float fresnelScale,
		uniform float fresnelPower,
		uniform sampler2D waterTex : register(s0),
		uniform sampler2D noiseMap : register(s1),
		uniform sampler2D reflectMap : register(s2),
		uniform sampler2D refractMap : register(s3)
		)
{
	// Do the tex projection manually so we can distort _after_
	float2 final = projectionCoord.xy / projectionCoord.w;

	// Noise
	float3 noiseNormal = (tex2D(noiseMap, (noiseCoord.xy / 5)).rgb - 0.5).rbg * noiseScale;
	final += noiseNormal.xz;

	// Fresnel
	//normal = normalize(normal + noiseNormal.xz);
	float fresnel = fresnelBias + fresnelScale * pow(1 + dot(eyeDir, normal), fresnelPower);

	// Reflection / refraction
	float4 reflectionColour = tex2D(reflectMap, final);
	float4 refractionColour = tex2D(refractMap, final) + tintColour;

	// Final colour
	col = lerp(refractionColour, reflectionColour, fresnel) * tex2D(waterTex, noiseNormal) / 3 ;


}


// Old version to match ATI PS 1.3 implementation
void main_vp_old(
		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);
	
}
