float maxDepth = 400; //maximum water depth
float3 waterColorDeep = {0.2, 0.5 , 0.6};
float3 waterColorShallow = {1.0, 1.0 , 1.0};
float foamTiling = 20;
float2 spec = {25, 0.75}; //specular exponent and strength


float4x4 matWorld;
float4x4 matWorldViewProj;
float4x4 sc_depth_matWorldViewProjInv_flt;

float4 vecSunDir;
float4 vecViewPos;
float4 vecTime;
float4 vecSkill1;
float4 vecSkill9;

texture entSkin1; //normalmap + alpha
texture entSkin2; //foammap + alpha
texture TargetMap; //scene
texture sc_depth_map_bmap; //scene depth

sampler2D sceneSampler = sampler_state
{
	Texture = <TargetMap>;

	MinFilter = Linear;
	MagFilter = Linear;
	MipFilter = Linear;
	AddressU = MIRROR;
	AddressV = MIRROR;
};

sampler depthSampler = sampler_state 
{ 
   Texture = <sc_depth_map_bmap>; 
   MinFilter = POINT;
	MagFilter = POINT;
	MipFilter = POINT;
};

sampler2D normalSampler = sampler_state
{
	Texture = <entSkin1>;

	MinFilter = Linear;
	MagFilter = Linear;
	MipFilter = Linear;
	AddressU = WRAP;
	AddressV = WRAP;
};

sampler2D foamSampler = sampler_state
{
	Texture = <entSkin2>;

	MinFilter = Linear;
	MagFilter = Linear;
	MipFilter = Linear;
	AddressU = WRAP;
	AddressV = WRAP;
};

struct vsOut
{
	float4 Pos : POSITION;
	float4 Tex : TEXCOORD0;
	float4 projCoord : TEXCOORD1;
	float3 Normal : TEXCOORD2;
};

struct vsIn
{
	float4 Pos : POSITION;
	float2 Tex : TEXCOORD0;
	float3 Normal : NORMAL;
};

vsOut mainVS(vsIn In)
{
	vsOut Out = (vsOut)0;
	
	Out.Pos = mul(In.Pos,matWorldViewProj);
   Out.projCoord = Out.Pos;
   
   Out.Tex.xy = float2(In.Tex.x + vecTime.w * vecSkill1.y * 0.001, In.Tex.y + vecTime.w * vecSkill1.z * 0.001);
   Out.Tex.zw = In.Tex.xy;
   Out.Normal = mul(In.Normal,matWorld);
	
	return Out;
}

float4 mainPS(vsOut In):COLOR0
{
	float4 color = 1;
	
	//projective texcoords
	float2 projTex;
	projTex.x = In.projCoord.x/In.projCoord.w/2.0f +0.5f;
   projTex.y = -In.projCoord.y/In.projCoord.w/2.0f +0.5f;
   
   //clip non visible parts
   float texDepth = tex2D(depthSampler,projTex.xy).r;
	float realDepth = In.projCoord.z/In.projCoord.w;
	if(texDepth < realDepth && texDepth != 0) clip(-1);
   
   //compute world position
	float4 vp = float4(projTex.xy * float2(2, -2) - float2(1, -1), texDepth, 1);
   float4 v = mul(vp, sc_depth_matWorldViewProjInv_flt);
   float3 wp = v.xyz/v.w;
   
   //refract texcoords
   float3 normal = (tex2D(normalSampler,In.Tex.xy*10).rgb-0.5f)*2;
	projTex = projTex.xy - (  normal.xy  * vecSkill1.x * 0.5 * (1-realDepth));
	normal = (tex2D(normalSampler,In.Tex.xy).rgb-0.5f)*2;
   projTex -= (  normal.xy  * vecSkill1.x * 0.01);
   //project to object
   color.rgb = tex2D(sceneSampler,projTex.xy).rgb;
	
	//sunlight
	In.Normal = normalize(In.Normal);
	float3 Vn = normalize(vecViewPos.xyz - wp);
	float3 Ln = normalize(-vecSunDir);
	float3 Hn = normalize(Vn + Ln);
	float4 lighting = lit(dot(Ln, In.Normal), dot(Hn, In.Normal), spec.x);
	
	float waterDepth = clamp((1.0f-(wp.y-vecSkill9.x))/maxDepth,0,1);	
	color.rgb =  lerp(color.rgb*waterColorShallow, color.rgb*waterColorDeep, waterDepth);
	
	color.rgb += lighting.z*spec.y;
	
   return color;
}

technique t1
{
	pass p0
	{
		VertexShader = compile vs_2_0 mainVS();
		PixelShader = compile ps_2_0 mainPS();
		alphablendenable = TRUE;
		cullmode = none;
	}
}

