uniform sampler texDiffuse		: register( s0 );
uniform sampler greyArea		: register( s1 );
uniform sampler falloff			: register( s2 );
uniform sampler horizon			: register( s3 );

static const float LOS_THRESHOLD 	= 0.75f;
static const float fDistMax			= 1000;
static const float SHADOW_FACTOR	= 0.8f;

extern uniform float	worldSize;
extern uniform float	sunElevation;
extern uniform float4 	wsPosCamera;
extern uniform float4	losTint;

float4 main_ps( float2 diffuseUV		: TEXCOORD0,
				float2 greyAreaUV		: TEXCOORD1,
				float3 wsPos			: TEXCOORD2 ) : COLOR0
{
	float4 outColor = tex2D(texDiffuse, diffuseUV);
	
	float offset = 1.0f/worldSize;
	
	// number should be odd, since the current pixel is the center of the bock
	// for the value 5, we get an error Shader Model 2 can't handle it
	float blockSide = 3.0f;
	
	// Ashwin please review : rakehsj
	float fOneTileOffset = 4*offset;
	
	float4 tempGrey = float4( 0.0f, 0.0f, 0.0f, 0.0f );
	float2 tempGreyAreaUV = float2( greyAreaUV.x-fOneTileOffset-blockSide*offset, greyAreaUV.y-blockSide*offset );
	
	for( int i = 0;i < blockSide;i ++ )
		for(int j = 0;j < blockSide;j ++ )
			tempGrey += tex2D( greyArea, float2(tempGreyAreaUV.x + j*offset, tempGreyAreaUV.y + i*offset) );
	
	tempGrey /= blockSide*blockSide;

#ifndef FUZZY_LOS 
	if( tempGrey.r < LOS_THRESHOLD )
	{
		outColor *= losTint;	
	}
#else
	// tempGrey:0.5->1.0
	outColor *= lerp( 2*losTint-1, 1, tempGrey.r);
#endif
	
	float fVisibility = 1.0f;

	// to reduce shadow doubling, we take closer samples
	offset /= 3.f;

	float fHCenter = tex2D( horizon, greyAreaUV.xy ).r;
	
	float4 fHSamples = float4(
						tex2D( horizon, greyAreaUV.xy + float2(-offset,0) ).r,
						tex2D( horizon, greyAreaUV.xy + float2(offset, 0) ).r,
						tex2D( horizon, greyAreaUV.xy + float2(0,-offset) ).r,
						tex2D( horizon, greyAreaUV.xy + float2(0, offset) ).r	);

	fVisibility = ( fHCenter > sunElevation ) ? SHADOW_FACTOR : 1.0f;

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

	float fDist = distance( wsPosCamera, wsPos );
	
	float fBrightness = tex1D( falloff, fDist/fDistMax );
	outColor.rgb *= fBrightness * 0.8f; // snow
	
	fVisibility /= 5.0f;
	
	return outColor * fVisibility;
}
