////////////////////////////////////////////////////////////////////////////////////////////////////
// Includes
////////////////////////////////////////////////////////////////////////////////////////////////////

#include "../../../types.txt"
#include "../common.ps.txt"

////////////////////////////////////////////////////////////////////////////////////////////////////
// Constant
////////////////////////////////////////////////////////////////////////////////////////////////////

static const float3 SDP_Y_AXIS = float3( 0.0, 1.0, 0.0 );

////////////////////////////////////////////////////////////////////////////////////////////////////
// Structures
////////////////////////////////////////////////////////////////////////////////////////////////////

struct PS_INPUT
{
#if MIX_SM_HIGH
	float4 pos      : SV_POSITION;
#endif //MIX_SM_HIGH
	float2 tex      : TEXCOORD0;
#if ( ENABLE_FOG && ENABLE_ATMOSPHERE )
	float3 worldPos : TEXCOORD1;
#endif //( ENABLE_FOG && ENABLE_ATMOSPHERE )
};

////////////////////////////////////////////////////////////////////////////////////////////////////
// Grobal values
////////////////////////////////////////////////////////////////////////////////////////////////////

#if MIX_SM_HIGH

	cbuffer cbInput : register( b0 )
	{
		float4 g_BaseColor;
		float4 g_Param;
	};

	Texture2D    g_BaseTexture : register( t0 );
	SamplerState g_BaseSampler : register( s0 );
	
#else //MIX_SM_HIGH

	float4 g_BaseColor    : register( c0 );
	float4 g_Param        : register( c1 );

	sampler g_BaseSampler : register( s0 );

#endif //MIX_SM_HIGH

////////////////////////////////////////////////////////////////////////////////////////////////////
// Macros
////////////////////////////////////////////////////////////////////////////////////////////////////

#if MIX_SM_HIGH
	#define TEX_BASE( uv ) g_BaseTexture.Sample( g_BaseSampler, uv )
#else //MIX_SM_HIGH
	#define TEX_BASE( uv ) tex2D( g_BaseSampler, uv )
#endif //MIX_SM_HIGH

#define SDP_TEX_REPEAT g_Param.x // Texture repeat factor
#define SDP_DISTANCE   g_Param.y // world distance
#define SDP_FOG_RATIO  g_Param.z // saturate( 1.0 - DISTANCE * INV_FAR_Z )

////////////////////////////////////////////////////////////////////////////////////////////////////
// Main function
////////////////////////////////////////////////////////////////////////////////////////////////////

float4 main( PS_INPUT input ) : MSV_TARGET0
{
	float LdotN;
	float4 ambientColor;
	float4 baseColor;
	float4 output;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// Lighting
	////////////////////////////////////////////////////////////////////////////////////////////////////
	
	LdotN = ( SUN_ENABLED )? max( 0.0, dot( -SUN_DIR, SDP_Y_AXIS ) ) : 0.0;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// Ambient color
	////////////////////////////////////////////////////////////////////////////////////////////////////
	
	ambientColor.rgb = GLOBAL_AMBIENT_COLOR * ( 1.0 - LdotN );
	ambientColor.a = 0.0;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// Base color
	////////////////////////////////////////////////////////////////////////////////////////////////////

	baseColor = g_BaseColor * TEX_BASE( float2( input.tex.x * SDP_TEX_REPEAT, input.tex.y ) );
	baseColor.rgb *= SUN_COLOR * SUN_SCALE * LdotN;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// Finish color
	////////////////////////////////////////////////////////////////////////////////////////////////////
	
	output = ambientColor + baseColor;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// Fog
	////////////////////////////////////////////////////////////////////////////////////////////////////

#if ENABLE_FOG
	#if ENABLE_ATMOSPHERE
		float3 dir = normalize( input.worldPos - EYE_POS );
		output.rgb = ApplyFog( output.rgb, dir, SDP_DISTANCE, SDP_FOG_RATIO );
	#else //ENABLE_ATMOSPHERE
		output.rgb = ApplyFog( output.rgb, SDP_FOG_RATIO );
	#endif //ENABLE_ATMOSPHERE
#endif //ENABLE_FOG
	
	return output;
}
