uniform sampler diffuseMap	: register(s0);
uniform sampler bumpMap		: register(s1);
uniform sampler horizon		: register(s2);

static const int NUM_LIGHTS = 2;
static const float SHADOW_FACTOR = 0.80f;

uniform float3 lightAmbient[NUM_LIGHTS];
uniform float3 lightDiffuse[NUM_LIGHTS];

extern uniform float4	colorModulate;
extern uniform float 	worldSize;
extern uniform float	sunElevation;

struct VS_INPUT 
{
	float2 uv0							: TEXCOORD0;
	float2 terrainUV					: TEXCOORD1;
	float3 tsLightDir					: TEXCOORD2;	//tangent space light direction
};

float4 main_ps( VS_INPUT input ) : COLOR0
{
	float4 diffuseMapSample = tex2D( diffuseMap, input.uv0 );
	float4 outColor = float4( 0, 0, 0, 1 );
	
	float3 normal =  normalize( tex2D( bumpMap, input.uv0 ).xyz*2.0f - 1.0f );
	
	float3 lightDir = normalize( input.tsLightDir );
	float nDotL = dot(normal, lightDir);

	float3 l = lightAmbient[0] + lightDiffuse[0] * max( 0, nDotL );

	outColor.rgb = saturate( l + l );
	outColor.a = diffuseMapSample.a ;

	outColor.rgb *= diffuseMapSample.rgb;

	// this factor does something similar to Ambient Occlusion
	float fTheta = tex2D( horizon, input.terrainUV ).r;	// horizon elevation
	float fDeltaElevation = fTheta - sunElevation;
	outColor *= lerp( 1.0, 0.4, 2*saturate(fDeltaElevation) );

	// to reduce shadow doubling, we take samples that are closely spaced
	float offset = 0.333333333333333f/worldSize;

	float fHCenter = fTheta;

	float4 fHSamples = float4(
						tex2D( horizon, input.terrainUV.xy + float2(-offset,0) ).r,
						tex2D( horizon, input.terrainUV.xy + float2(offset, 0) ).r,
						tex2D( horizon, input.terrainUV.xy + float2(0,-offset) ).r,
						tex2D( horizon, input.terrainUV.xy + float2(0, offset) ).r	);

	float fVisibility = ( fHCenter > sunElevation ) ? SHADOW_FACTOR : 1.f;

	fVisibility += ( fHSamples.r > sunElevation ) ? SHADOW_FACTOR : 1.f;
	fVisibility += ( fHSamples.g > sunElevation ) ? SHADOW_FACTOR : 1.f;
	fVisibility += ( fHSamples.b > sunElevation ) ? SHADOW_FACTOR : 1.f;
	fVisibility += ( fHSamples.a > sunElevation ) ? SHADOW_FACTOR : 1.f;
	
	fVisibility /= 5.0f;

	outColor.rgb *= colorModulate;
	outColor.rgb *= fVisibility;

	return outColor;
}
