//converted and updated from GG DX9 to GG DX11 for synchromesh

#include "settings.fx"
#include "constantbuffers.fx"

float4x4 WorldVP:WorldViewProjection; 
float time:Time; 
   
float4 HudFogColor  = {0.0f, 0.0f, 0.0f, 0.0000001f};
float4 HudFogDist  = {1.0f, 0.0f, 0.0f, 0.0000001f};
float4 AmbiColorOverride = {1.0f, 1.0f, 1.0f, 1.0f};
float4 AmbiColor = {0.1f, 0.1f, 0.1f, 1.0f};
float4 SurfColor = {1.0f, 1.0f, 1.0f, 1.0f};
float SpecularOverride = 1.0f;
float4 SkyColor = {1.0, 1.0, 1.0, 1.0f};
float4 FloorColor = {1.0, 1.0, 1.00, 1.0f};

// tweaks

   float Transparency = 0.9;
   float ReflectAmount = 0.5;
   float WaterBump=0.3f;
   float2 WaterScale={2900,2900};
   float4 WaterSpeed={-0.0125f,-0.015f,0.005f,-0.005f};
   float FresBias= 50.0f;
   float FresPow=2.5f;
   float DetailScale=4.0;
   float3 RefractColor={0.5f,0.5f,0.5f};
   float3 ReflectColor={0.7f,0.7f,0.7f};


float2 ViewVec;   

// Textures
Texture2D WaterReflectTX : register( t0 ); //diffuse
Texture2D NotUsed : register( t1 ); //Occlusion
Texture2D WaterbumpTX : register( t2 ); //normal
Texture2D WaterRefractTX : register( t3 ); //Specular
Texture2D NotUsed2: register( t4 );
Texture2D NotUsed3 : register( t5 );
Texture2D IlluminationOrCubeMap : register( t6 );
Texture2D MaskMap : register( t11 );

SamplerState SampleClamp
{
    Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Clamp;
    AddressV = Clamp;
	AddressW = Clamp;
};

SamplerState SampleWrap
{
	//Filter = MIN_POINT_MAG_LINEAR_MIP_POINT;
	Filter = MIN_MAG_MIP_LINEAR;
	//Filter = ANISOTROPIC;
    //AddressU = Wrap;
    //AddressV = Wrap;
	AddressU = Mirror;
    AddressV = Mirror;
	
};

// structs 
   struct In_AboveWater
     {
		float4 Pos      : POSITION;
		float2 UV0		: TEXCOORD0;
     };
   struct Out_AboveWater
     {
		float4 OPos:POSITION; 
		float4 Tex1:TEXCOORD0; 
		float2 Tex2:TEXCOORD1; 
		float4 RefrProj:TEXCOORD2;
		float4 ReflProj:TEXCOORD3;
		float3 WaterFog:TEXCOORD4; 
		float3 FresVec:TEXCOORD5; 
		float4 WPos:TEXCOORD6;
     };
  
// vertex shader
   float3x3 TBN={float3(1,0,0),float3(0,0,1),float3(0,1,0)};
   
   Out_AboveWater VS_AboveWater(In_AboveWater IN) 
    {
 	Out_AboveWater OUT;
	OUT.OPos=mul(float4(IN.Pos.xyz,1.0),WorldVP); 
	OUT.WPos=mul(float4(IN.Pos.xyz,1), World);
	float3 WPos = OUT.WPos.xyz;
	float2 Uv=(WPos.xz/WaterScale);
	float4 WaterUv;
	WaterUv.xy=Uv+(time*WaterSpeed.xy);
	WaterUv.zw=(Uv*1.25)+(time*WaterSpeed.zw);
	float3 ViewPos=ViewInv[3].xyz-WPos;
	OUT.Tex1=WaterUv;
	OUT.Tex2=Uv;
	OUT.RefrProj=float4(OUT.OPos.x*0.5+0.5*OUT.OPos.w,0.5*OUT.OPos.w-OUT.OPos.y*0.5,OUT.OPos.w,OUT.OPos.w);
  	OUT.ReflProj=float4(OUT.OPos.x*0.5+0.5*OUT.OPos.w,0.5*OUT.OPos.w+OUT.OPos.y*0.5,OUT.OPos.w,OUT.OPos.w);
 	OUT.ReflProj.y=OUT.ReflProj.y-1.0f;
	OUT.WaterFog=0; //ViewPos/FogRange;
	ViewPos.y=(ViewPos.y+FresBias)*FresPow;
	OUT.FresVec=mul(ViewPos,TBN); 
	
	return OUT;
    }
  

    float4 PS_AboveWater(Out_AboveWater IN)  : COLOR
     {	
		float4 NM = (WaterbumpTX.SampleLevel(SampleWrap,IN.Tex1.xy*DetailScale,2) + WaterbumpTX.SampleLevel(SampleWrap,IN.Tex1.zw*DetailScale,3)); //-1.0f; 
		float3 NormalMap = NM.xyz; 
		NormalMap.xy = NormalMap.xy * 2.0 - 1.0;
		float3 Reflection = 0; 
		float3 dudv = normalize(NM.rgb * 2.0 - 1.0);
		Reflection = WaterReflectTX.Sample(SampleWrap,IN.Tex1.xy + dudv.rg).xyz;
		float3 Refraction=0;
		Refraction=(WaterRefractTX.Sample(SampleClamp,(IN.RefrProj.xy/IN.RefrProj.z)).xyz) * RefractColor;
		float Fresnel=dot(NormalMap,normalize(IN.FresVec));
		float3 Water=lerp(Reflection,Refraction,Fresnel);
		float4 result = float4(Water,1.0);
		result = result + (AmbiColor * AmbiColorOverride);
		float4 cameraPos = mul(IN.WPos, View);
		float hudfogfactor = saturate((cameraPos.z- HudFogDist.x)/(HudFogDist.y - HudFogDist.x));
		float4 hudfogresult = lerp(result,float4(HudFogColor.xyz,0),hudfogfactor*HudFogColor.w);
		return float4(hudfogresult.xyz,Transparency);
     }
	 
   
// techniques   
technique11 Main
{
    pass MainPass
    {
        SetVertexShader(CompileShader(vs_5_0, VS_AboveWater()));
		SetPixelShader(CompileShader(ps_5_0, PS_AboveWater()));
		SetGeometryShader(NULL);
    }
	
	
}





