//
// Generated by Microsoft (R) D3DX9 Shader Compiler 9.08.299.0000
//
//   psa shaderdump19/WATER006.pso /Fcshaderdump19/WATER006.pso.dis
//
//
// Parameters:
//
float4 Scroll : register(c0);
float4 EyePos : register(c1);
float4 SunDir : register(c2);
float4 SunColor : register(c3);
float4 NotUsed4 : register(c4);
float4 ShallowColor : register(c5);
float4 DeepColor : register(c6);
float4 ReflectionColor : register(c7);
float4 VarAmounts : register(c8);
float4 FogParam : register(c9);
float4 FogColor : register(c10);
float4 FresnelRI : register(c11);
float4 BlendRadius : register(c12);
float4 TESR_SunColor : register(c13);
float4 TESR_WaterCoefficients : register(c14);
float4 TESR_WaveParams : register(c15);
float4 TESR_WaterVolume : register(c16);
float4 TESR_WaterSettings : register(c17);
float4 TESR_ReciprocalResolution : register(c18);
float4 TESR_Tick : register(c19);
float4x4 TESR_ViewTransform : register(c20);
float4x4 TESR_ProjectionTransform : register(c24);

sampler2D ReflectionMap : register(s0);
sampler2D NormalMap : register(s1);
sampler2D DetailMap : register(s2);
sampler2D DepthMap : register(s3);
sampler2D DisplacementMap : register(s4);
sampler2D TESR_RenderedBuffer : register(s5) = sampler_state { };
sampler2D TESR_DepthBuffer : register(s6) = sampler_state { };

//
//
// Registers:
//
//   Name            Reg   Size
//   --------------- ----- ----
//   Scroll          const_0       1
//   EyePos          const_1       1
//   SunDir          const_2       1
//   SunColor        const_3       1
//   ShallowColor    const_5       1
//   DeepColor       const_6       1
//   ReflectionColor const_7       1
//   VarAmounts      const_8       1
//   FogParam        const_9       1
//   FogColor        const_10      1
//   FresnelRI       const_11      1
//   NormalMap       texture_1       1
//   DetailMap       texture_2       1
//


// Structures:

struct VS_OUTPUT {
    float3 texcoord_1 : TEXCOORD1_centroid;
    float4 texcoord_2 : TEXCOORD2_centroid;
    float2 texcoord_6 : TEXCOORD6;
};

struct PS_OUTPUT {
    float4 color_0 : COLOR0;
};

float3 toWorld(float2 tex)
{
    float3 v = float3(TESR_ViewTransform[2][0], TESR_ViewTransform[2][1], TESR_ViewTransform[2][2]);
    v += (1/TESR_ProjectionTransform[0][0] * (2*tex.x-1)).xxx * float3(TESR_ViewTransform[0][0], TESR_ViewTransform[0][1], TESR_ViewTransform[0][2]);
    v += (-1/TESR_ProjectionTransform[1][1] * (2*tex.y-1)).xxx * float3(TESR_ViewTransform[1][0], TESR_ViewTransform[1][1], TESR_ViewTransform[1][2]);
    return v;
}

float3 getWaterNorm( float2 tex, float dist, float camera_vector_z )
{
	float choppiness = TESR_WaveParams.x;

	float4 sampledResult = tex2D( NormalMap, tex  );

	float2 temp_norm = sampledResult.rg * 2 - 1;
	float3 norm = normalize(float3(temp_norm * choppiness, 1));
	return norm;
}

float getFresnelBelowWater( float3 ray, float3 norm )
{
	float temp_cos = dot( ray, norm );
	temp_cos = max(temp_cos, 0.659325);
	float2 vec = float2(temp_cos, sqrt(1-temp_cos*temp_cos));

	float fresnel = 1.33 * vec.x - sqrt(1 - 1.769*vec.y*vec.y);
	fresnel /= 1.33 * vec.x + sqrt(1 - 1.769*vec.y*vec.y);
	fresnel = saturate(fresnel * fresnel);

	return fresnel;
}

float getFresnelAboveWater( float3 ray, float3 norm )
{
	float temp_cos = dot( ray, norm );
	float2 vec = float2(temp_cos, sqrt(1-temp_cos*temp_cos));

	float fresnel = vec.x - 1.33 * sqrt(1 - 0.565*vec.y*vec.y);
	fresnel /= vec.x + 1.33 * sqrt(1 - 0.565*vec.y*vec.y);
	fresnel = saturate(fresnel * fresnel);

	return fresnel;
}

// Code:

PS_OUTPUT main(VS_OUTPUT IN, float2 PixelPos : VPOS) {
    PS_OUTPUT OUT;

	float2 UVCoord = (PixelPos+0.5)*TESR_ReciprocalResolution.xy;
	float4 sunColor = TESR_SunColor;
	float3 extCoeff = TESR_WaterCoefficients.xyz;
	float scattCoeff = TESR_WaterCoefficients.w;
	float waveWidth = TESR_WaveParams.y;
	bool lava = (VarAmounts.w > 0.4);

    float3 camera_vector = toWorld(UVCoord);
	float3 norm_camera_vector = normalize( camera_vector );
	float3 eyepos = IN.texcoord_2.xyz;
	eyepos.z = -IN.texcoord_1.z;

	float uw_pos = abs( eyepos.z / camera_vector.z );
	float2 surfPos = eyepos.xy + camera_vector.xy * uw_pos;
	float3 normal = getWaterNorm( surfPos / (1024 * waveWidth), uw_pos, camera_vector.z );

	//Specular effects
	float specular = saturate(dot( float3(1,1,-1)*norm_camera_vector, reflect( SunDir.xyz, normal) ));
	specular = pow(specular, 750);

	//Fresnel effects
	float4 reflection = float4( scattCoeff * FogColor.xyz / extCoeff, 1);
	reflection *= lerp( 1, 1.5, getFresnelAboveWater( norm_camera_vector, normal ) );
	float fresnel = getFresnelBelowWater( norm_camera_vector, normal );
	
	specular *= 1-fresnel;
	OUT.color_0.rgb = lerp( reflection.rgb, 10 * sunColor.xyz, specular ).rgb;

	float visibility = saturate(0.001 + fresnel + specular*length(sunColor.xyz)) * 0.9;
	if (lava)
	{
			OUT.color_0.rgb = tex2D(DetailMap, IN.texcoord_6.xy + Scroll.xy).rgb;
			OUT.color_0.r += 0.6;
			visibility = 1;
	}

	OUT.color_0.a = visibility;

    return OUT;
};

// approximately 59 instruction slots used (2 texture, 57 arithmetic)
