/*=============================================================================
	MotionBlurPixelShader.usf: Blurs based on velocity vector.
	Copyright © 2003-2006 Epic Games, Inc. All Rights Reserved.
=============================================================================*/

#include "Common.usf"

#ifndef NUM_SAMPLES
#define NUM_SAMPLES 5
#endif

#if XBOX

// MotionBlur rendering can not limited to just SceneColor render target.  So, SCENE_COLOR_BIAS_FACTOR has to
// be set as a shader param.

float SceneColorBiasFactor;

float4 ExplicitBiasColor( float4 Color )
{
	return float4( Color.rgb * SceneColorBiasFactor, Color.a );
}

#undef  RETURN_COLOR
#define RETURN_COLOR( Color ) ExplicitBiasColor( Color );
#endif



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

void VertexShader(
	float4 InPosition : POSITION,
	float2 InScreenUV : TEXCOORD0,
	out float4 OutPosition : POSITION,
	out float4 OutScreenPosition : TEXCOORD0
	)
{
	OutPosition = InPosition;								// Target position
	OutScreenPosition = float4(InPosition.xy,InScreenUV);	// Background UV and position
}


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

sampler		VelocityBuffer;
float4x4	ScreenToWorld;
float4x4	PrevViewProjMatrix;

float4 StaticVelocityParameters = { 0.5f, -0.5f, 16.0f/1280.0f, 16.0f/720.0f };
float4 DynamicVelocityParameters = { 2.0f*16.0f/1280.0f, -2.0f*16.0f/720.0f, -16.0f/1280.0f, 16.0f/720.0f };

void PixelShader( float4 ScreenPosition : TEXCOORD0, out float4 OutColor : COLOR0 )
{
	// NOTE: Maximum value for an fp16 depth-value is 65504.
	float2	ScreenUV			= ScreenPosition.zw;
	half	CurrDepth			= min( CalcSceneDepth( ScreenUV ), 65504);
	if ( CurrDepth < 14.0f )
		CurrDepth = 65504;
	float4	ProjectedPosition	= float4( ScreenPosition.xy * CurrDepth, CurrDepth, 1 );
	float4	WorldPosition		= float4( MulMatrix(ScreenToWorld, ProjectedPosition).xyz, 1 );
	float4	PrevScreenPosition	= MulMatrix( PrevViewProjMatrix, WorldPosition );
	float2	DynamicVelocity		= tex2D( VelocityBuffer, ScreenUV ).xy;
	PrevScreenPosition.xy		/= PrevScreenPosition.w;

    // Scale static velocity from projection space to texel space and clamp to +/- MAX_VELOCITY pixels.
    float2  StaticVelocity	= ScreenPosition.xy - PrevScreenPosition.xy;
	StaticVelocity			= clamp( StaticVelocity*StaticVelocityParameters.xy, -StaticVelocityParameters.zw, StaticVelocityParameters.zw );

	// Scale dynamic velocity from biased [0,1] to +/- MAX_VELOCITY pixels
    half	Selector		= DynamicVelocity.x + DynamicVelocity.y;
	DynamicVelocity			= (DynamicVelocity*DynamicVelocityParameters.xy + DynamicVelocityParameters.zw);

	// Select between dynamic or static velocity:
    float2	PixelVelocity	= (Selector > 0.0001f) ? DynamicVelocity : StaticVelocity;
//    half Scale				= pow( length(PixelVelocity/StaticVelocityParameters.zw), 2.0f );
	half2	NominalVelocity	= PixelVelocity/StaticVelocityParameters.zw;
	half Scale				= dot(NominalVelocity, NominalVelocity);
	PixelVelocity		   *= Scale;

	float2 Step = PixelVelocity / NUM_SAMPLES;
	ScreenUV -= 2*Step;
	float3 Color = tex2D( SceneColorTexture, ScreenUV ).rgb;
	for ( int i=1; i < NUM_SAMPLES; ++i )
	{
		ScreenUV += Step;
		Color += tex2D( SceneColorTexture, ScreenUV ).rgb;
	}

//	float2 PrevScreenUV = PrevScreenPosition.xy*ScreenPositionScaleBias.xy + ScreenPositionScaleBias.wz;
//	float3 PrevColor = tex2D( SceneColorTexture, PrevScreenUV );
	OutColor = RETURN_COLOR( float4(Color/NUM_SAMPLES, 1) );// + float4(PrevColor,0)
//	OutColor = RETURN_COLOR( float4(WorldPosition.xyz/10000, 1) );
//	OutColor = RETURN_COLOR( tex2D( SceneColorTexture, ScreenPosition.xy ) );
//	OutColor = RETURN_COLOR( float4(CurrDepth/100000.0f, CurrDepth/100000.0f, CurrDepth/100000.0f, 1) );
//	OutColor = RETURN_COLOR( float4(abs(PixelVelocity.xy)/StaticVelocityParameters.zw, 0, 1) );
//	OutColor = RETURN_COLOR( float4(abs(StaticVelocity.xy)/StaticVelocityParameters.zw, 0, 1) );
//	OutColor = RETURN_COLOR( float4( (Selector>0.0001f) ? abs(DynamicVelocity.xy)/StaticVelocityParameters.zw : 0, 0, 1) );
//	OutColor = RETURN_COLOR( float4(Color, 1) );
//	OutColor = RETURN_COLOR( (Selector>0.0001f) ? length(DynamicVelocity.xy/StaticVelocityParameters.zw) : 0 );
//	OutColor = RETURN_COLOR( (Selector>0.0001f) ? 0 : length(StaticVelocity.xy/StaticVelocityParameters.zw) );
//	OutColor = RETURN_COLOR( (Selector>0.0001f) ? 0.6f : 0 );
//	OutColor = RETURN_COLOR( length(PixelVelocity/Scale) );
//	OutColor = RETURN_COLOR( length(PixelVelocity) );
}
