/*=============================================================================
	LightMapDensityShader.hlsl: Shader for rendering lightmap density as a color
	Copyright 1998-2010 Epic Games, Inc. All Rights Reserved.
=============================================================================*/

#define NEEDS_LIGHTMAP_COORDINATE					(TEXTURE_LIGHTMAP || SIMPLE_TEXTURE_LIGHTMAP)

#include "Common.usf"
#include "Material.usf"
#include "VertexFactory.usf"

/*=============================================================================
	Vertex Shader
=============================================================================*/

void MainVertexShader(
	FVertexFactoryInput Input,
	out FVertexFactoryInterpolants FactoryInterpolants,
	out float4 WorldPosition	: TEXCOORD6,
	out float4 Position			: POSITION
	)
{
	FVertexFactoryIntermediates VFIntermediates = GetVertexFactoryIntermediates(Input);
	WorldPosition = VertexFactoryGetWorldPosition(Input, VFIntermediates);
	float3x3 TangentBasis = VertexFactoryGetTangentBasis(Input, VFIntermediates);

	FMaterialVertexParameters VertexParameters = GetMaterialVertexParameters(Input, VFIntermediates, WorldPosition.xyz, TangentBasis);
	WorldPosition.xyz += GetMaterialWorldPositionOffset(VertexParameters);

	Position = MulMatrix(ViewProjectionMatrix, WorldPosition);
	FactoryInterpolants = VertexFactoryGetInterpolants(Input, VFIntermediates);
}

/*=============================================================================
	Pixel Shader
=============================================================================*/

float4		LightMapDensityParameters;
float2		LightMapResolutionScale;

/**
 *	Tagging built vs. unbuilt lighting on objects.
 *	x = 1.0, y = 0.0 for built lighting
 *	x = 0.0, y = 1.0 for unbuilt lighting
 *	z = 1.0 if the object is selected
 */
float3		BuiltLightingAndSelectedFlags;

/** 
 *	X = scalar to multiply density against...
 *  Y = scalar to multiply calculatated color against...
 *      So, to enable greyscale density mode - set X != 0, Y = 0
 *		Standard color mode - set X = 0, Y = 1
 *	Z = texture lightmap scalar
 *		Set to 1.0 if texture mapped to leave texture mapped colors alone.
 *		Set to 0.0 if vertex mapped
 *	W = vertex lightmap scalar
 *		Set to 0.0 if texture mapped
 *		Set to 1.0 if vertex mapped
 */
float4		LightMapDensityDisplayOptions;

/**
 *	The color to apply to vertex mapped objects
 */
float4		VertexMappedColor;

/**
 *	The color to apply to selected objects
 */
float4		DensitySelectedColor;

/** The 'Grid' texture to show resolution */
sampler2D 	GridTexture;
/** The 'Grid' texture normal map texture */
sampler2D 	GridNormalTexture;

/**
 *	The 'main' for the PixelShader
 */
void MainPixelShader(
	FVertexFactoryInterpolants FactoryInterpolants,
	float4 WorldPosition	: TEXCOORD6,
	OPTIONAL_FacingSign
	OPTIONAL_PixelShaderScreenPosition
	out float4 OutColor		: COLOR0
	)
{
	FMaterialPixelParameters MaterialParameters = GetMaterialPixelParameters( FactoryInterpolants );
	CalcMaterialParameters(MaterialParameters, FacingSign, float4(0,0,1,0), float4(0,0,.00001f,1));
	GetMaterialClipping(MaterialParameters, PixelShaderScreenPosition.xy);

	float2 LightMapUV;
#if TEXTURE_LIGHTMAP || SIMPLE_TEXTURE_LIGHTMAP
	LightMapUV = GetLightMapCoordinate(FactoryInterpolants);
#else	//#if TEXTURE_LIGHTMAP || SIMPLE_TEXTURE_LIGHTMAP
	LightMapUV = float2(0.1,0.1);
#endif	//#if TEXTURE_LIGHTMAP || SIMPLE_TEXTURE_LIGHTMAP

	// Area of parallelogram, in world space units.
	float WorldSpaceArea = length( cross( ddx(WorldPosition.xyz), ddy(WorldPosition.xyz) ) );
	WorldSpaceArea = max( WorldSpaceArea, 0.00000001f );

	float MinDensity = LightMapDensityParameters.y;
	float IdealDensity = LightMapDensityParameters.z;
	float MaxDensity = LightMapDensityParameters.w;

	float Density = MinDensity;

	float2 TexCoord = LightMapUV * (LightMapResolutionScale.xy * 2.0);	// In texels
	float2 A = ddx(TexCoord);
	float2 B = ddy(TexCoord);
	float2 C = A.xy * B.yx;

	// Area of parallelogram, in texels.
	float TexelArea = abs( C.x - C.y );
	Density = TexelArea / WorldSpaceArea;
	// Clamp the density to the max
	Density = min( Density, MaxDensity );

	float4 TintColor;
	float4 TintGrayScale;
	if ( Density > IdealDensity )
	{
		float Range = MaxDensity - IdealDensity;
		Density -= IdealDensity;
 		TintColor = RETURN_COLOR( float4( Density/Range, (Range-Density)/Range, 0.0f, 1.0f ) );
	}
	else
	{
		float Range = IdealDensity - MinDensity;
		Density -= MinDensity;
 		TintColor = RETURN_COLOR( float4( 0.0f, Density/Range, (Range-Density)/Range, 1.0f ) )	;
	}

	float GrayScaleRange = MaxDensity - MinDensity;
	TintGrayScale = RETURN_COLOR(float4(Density/GrayScaleRange,Density/GrayScaleRange,Density/GrayScaleRange,1.0f));

	// Disable the color tinting if the option is set
	TintColor *= LightMapDensityDisplayOptions.y;
	// Enable 'grayscale' mode if desired
 	TintColor += (TintGrayScale * LightMapDensityDisplayOptions.x);
 	TintColor *= BuiltLightingAndSelectedFlags.x;
 	TintColor += BuiltLightingAndSelectedFlags.yyyy;
	// Override the coloring if vertex mapped
 	TintColor *= LightMapDensityDisplayOptions.z;
 	TintColor += (VertexMappedColor * LightMapDensityDisplayOptions.w);
 	// Override the coloring if selected...
 	TintColor *= (1.0f - BuiltLightingAndSelectedFlags.z);
 	TintColor += (DensitySelectedColor * BuiltLightingAndSelectedFlags.z);

	LightMapUV *= LightMapResolutionScale.xy;
	OutColor = tex2D(GridTexture,LightMapUV) * TintColor;
}
