/*=============================================================================
	ShadowDepthVertexShader.usf: Vertex shader for writing shadow depth.
	Copyright 1998-2010 Epic Games, Inc. All Rights Reserved.
=============================================================================*/

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

#ifndef OUTPUT_DEPTH_TO_COLOR
#define OUTPUT_DEPTH_TO_COLOR 0
#endif

#ifndef PERSPECTIVE_CORRECT_DEPTH
#define PERSPECTIVE_CORRECT_DEPTH 0
#endif

// PS3 use depth textures for projected shadows
#if PS3
	#undef SUPPORTS_DEPTH_TEXTURES
	#define SUPPORTS_DEPTH_TEXTURES 1
#endif

float4x4 ProjectionMatrix;

/** Used to normalize the outputted depth */
float InvMaxSubjectDepth;

/** Tweakable depth bias */
float DepthBias;

//@todo - make this a bool, bool shader parameters currently do not work in vertex shaders on Xbox 360 (TTP 125134)
float bClampToNearPlane;

void Main(
	FVertexFactoryInput Input,
#if !MATERIALBLENDING_SOLID
	out FVertexFactoryInterpolants OutFactoryInterpolants,
#endif
#if PERSPECTIVE_CORRECT_DEPTH || !SUPPORTS_DEPTH_TEXTURES
	out float ShadowDepth : TEXCOORD4, 
#endif
	out float4 OutPosition : POSITION
	)
{
	FVertexFactoryIntermediates VFIntermediates = GetVertexFactoryIntermediates(Input);
	float4 WorldPos = VertexFactoryGetWorldPosition(Input, VFIntermediates);
	float3x3 TangentBasis = VertexFactoryGetTangentBasis(Input, VFIntermediates);

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

	OutPosition = MulMatrix(ProjectionMatrix,WorldPos);

	// Clamp the vertex to the near plane if it is in front of the near plane
	// This has problems if some vertices of a triangle get clamped and others do not, also causes artifacts with non-ortho projections
	if (bClampToNearPlane && OutPosition.z < 0)
	{
		OutPosition.z = 0.000001f;
		OutPosition.w = 1.0f;
	}

#if PERSPECTIVE_CORRECT_DEPTH
	ShadowDepth = OutPosition.z;
#else
		// Output linear, normalized depth
	#if SUPPORTS_DEPTH_TEXTURES
		OutPosition.z = (OutPosition.z * InvMaxSubjectDepth + DepthBias) * OutPosition.w;
	#else
		#if !OUTPUT_DEPTH_TO_COLOR
			OutPosition.z = (OutPosition.z * InvMaxSubjectDepth + DepthBias) * OutPosition.w;
		#endif
		ShadowDepth = (OutPosition.z * InvMaxSubjectDepth + DepthBias);
	#endif
#endif

#if !MATERIALBLENDING_SOLID
	// Masked materials need texture coords to clip
	OutFactoryInterpolants = VertexFactoryGetInterpolants(Input, VFIntermediates);
#endif
}
