//====== Copyright © 1996-2006, Valve Corporation, All rights reserved. =======

// STATIC: "CONVERT_TO_SRGB"			"0..1"	[ps20b][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC]
// STATIC: "CONVERT_TO_SRGB"			"0..1"	[ps30][= g_pHardwareConfig->NeedsShaderSRGBConversion()] [PC]
// STATIC: "CONVERT_TO_SRGB"			"0..0"	[= 0] [XBOX]

// DYNAMIC: "PIXELFOGTYPE"				"0..1"
// DYNAMIC: "NUM_LIGHTS"				"0..2"	[ps20]
// DYNAMIC: "NUM_LIGHTS"				"0..4"	[ps20b]
// DYNAMIC: "NUM_LIGHTS"				"0..4"	[ps30]
// DYNAMIC: "AMBIENT_LIGHT"				"0..1"
// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA"	"0..1"	[ps20b] [PC]
// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA"	"0..0"	[ps20b] [XBOX]
// DYNAMIC: "WRITE_DEPTH_TO_DESTALPHA"	"0..1"	[ps30]

#if defined( SHADER_MODEL_PS_2_0 )
#	define WRITE_DEPTH_TO_DESTALPHA 0
#endif

#include "shader_constant_register_map.h"

const float3 cAmbientCube[6]				: register( PSREG_AMBIENT_CUBE );
const float4 g_FogParams					: register( PSREG_FOG_PARAMS );
const float4 g_EyePos_SpecExponent			: register( PSREG_EYEPOS_SPEC_EXPONENT );
PixelShaderLightInfo cLightInfo[3]			: register( PSREG_LIGHT_INFO_ARRAY );			// 2 registers each - 6 registers total

sampler BaseTextureSampler					: register( s0 );
sampler BumpTextureSampler					: register( s1 );
sampler NormalizeSampler					: register( s2 );

struct PS_INPUT
{
	float2 baseTexCoord						: TEXCOORD0;
	float4 worldVertToEyeVector_Darkening	: TEXCOORD1;
	float3x3 tangentSpaceTranspose			: TEXCOORD2;
	//	     second row						: TEXCOORD3;
	//	     third row						: TEXCOORD4;
	float4 worldPos_projPosZ				: TEXCOORD5;
	float2 lightAtten01						: TEXCOORD6;
	float2 lightAtten23						: TEXCOORD7;
};



#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)))

#define worldVertToEyeVector i.worldVertToEyeVector_Darkening.xyz
#define fDarkening i.worldVertToEyeVector_Darkening.w

#endif



float4 main( PS_INPUT i ) : COLOR
{
	bool bAmbientLight = AMBIENT_LIGHT ? true : false;
	int nNumLights = NUM_LIGHTS;

	float4 vLightAtten = float4( i.lightAtten01, i.lightAtten23 );
	float4 baseSample = tex2D( BaseTextureSampler, i.baseTexCoord );

	float3 worldSpaceNormal, tangentSpaceNormal = float3(0, 0, 1);
	float fSpecExp = g_EyePos_SpecExponent.w;

	float4 normalTexel = tex2D( BumpTextureSampler, i.baseTexCoord );
	tangentSpaceNormal = 2.0f * normalTexel.xyz - 1.0f;
	worldSpaceNormal = normalize( mul( i.tangentSpaceTranspose, tangentSpaceNormal ) );

	// If the exponent passed in as a constant is zero, use the value from the map as the exponent
	if ( fSpecExp == 0 )
		fSpecExp = 1.0f * ( 1.0f - normalTexel.w ) + 150.0f * normalTexel.w;

	// Summation of diffuse illumination from all local lights
	float3 diffuseLighting = PixelShaderDoLighting(	i.worldPos_projPosZ.xyz, worldSpaceNormal,
													float3( 0.0f, 0.0f, 0.0f ), false,
													bAmbientLight, vLightAtten,
													cAmbientCube, NormalizeSampler, nNumLights, cLightInfo, true,
													false, 0, false, NormalizeSampler );

#if ((defined(SHADER_MODEL_PS_2_B) || defined(SHADER_MODEL_PS_3_0)))

	float3 vDummy, specularLighting;

	// Summation of specular from all local lights
	PixelShaderDoSpecularLighting( i.worldPos_projPosZ.xyz, worldSpaceNormal, fSpecExp, normalize(worldVertToEyeVector),
								   vLightAtten, nNumLights, cLightInfo,
								   false, 1.0f, false, NormalizeSampler, 1.0f, false, 1.0f,

								   // Outputs
								   specularLighting, vDummy );

	// Specular plus diffuse, all darkened as a function of mouth openness
	float3 result = (specularLighting * baseSample.a + baseSample.rgb * diffuseLighting) * fDarkening;

#else
	float3 result = baseSample.rgb * diffuseLighting * i.worldVertToEyeVector_Darkening.w;
#endif

	float fogFactor = CalcPixelFogFactor( PIXELFOGTYPE, g_FogParams, g_EyePos_SpecExponent.z, i.worldPos_projPosZ.z, i.worldPos_projPosZ.w );
	return FinalOutput( float4(result, 1.0f), fogFactor, PIXELFOGTYPE, TONEMAP_SCALE_LINEAR, (WRITE_DEPTH_TO_DESTALPHA != 0), i.worldPos_projPosZ.w );
}