/*=============================================================================
	MotionVelocityShader.usf: Calculates velocity vectors.
	Copyright © 2003-2006 Epic Games, Inc. All Rights Reserved.
=============================================================================*/

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


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

float4x4 ViewProjectionMatrix REGISTER(252);
float4x4 PrevViewProjectionMatrix;

struct FVertexOutput
{
    float4 Position : POSITION;		// Position current frame
    float4 Positions : TEXCOORD6;	// XY = 2D-position current frame, ZW = 2D-position previous frame

	FVertexFactoryInterpolants OutFactoryInterpolants;
};

void VertexShader( FVertexFactoryInput Input, out FVertexOutput Output )
{
	Output.Position = MulMatrix( ViewProjectionMatrix, VertexFactoryGetWorldPosition(Input, Output.OutFactoryInterpolants) );
	Output.Positions.xy = Output.Position.xy / Output.Position.w;

	FVertexFactoryInterpolants Dummy;
	float4 PrevWorldPos = MulMatrix( PrevViewProjectionMatrix, VertexFactoryGetPreviousWorldPosition( Input, Dummy ) );
	Output.Positions.zw = PrevWorldPos.xy / PrevWorldPos.w;
}


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

// This parameter brings a [-2,+2] velocity vector into [0,1] range,
// where 0 is mapped to -MaxVelocity, and 1 is mapped to +MaxVelocity.
// These values depend on screen resolution and blur distance, so they
// should be adjusted from CPU.
// Initialized here for a 16-pixel blur distance on a 640,480 resolution.
// XY = Multiplier, ZW = Offset

float4 VelocityScaleOffset = { 0.25f*640.0f/16.0f, 0.25f*480.0f/16.0f, 0.5f, 0.5f };
float4 IndividualVelocityScale = { 1.0f, 1.0f, 0.0002f, 0.9998f };

void PixelShader( FVertexFactoryInterpolants Interpolants, float4 Positions : TEXCOORD6, out float4 OutColor : COLOR0 )
{
	// Manual clipping here (alpha-test, etc)
	FMaterialParameters MaterialParameters = GetMaterialParameters( Interpolants );
	CalcMaterialParameters( MaterialParameters, 0, 0 );
	GetMaterialClipping( MaterialParameters );

	// Calculate velocity from previous position to current position (projection space)
	float2 Velocity = Positions.xy - Positions.zw;

	// Scale by opacity
	Velocity	*= GetMaterialOpacity( MaterialParameters );

	// Scale by UPrimitiveComponent::MotionBlurScale and resolution
	Velocity	*= IndividualVelocityScale.xy;

	// Clamp vector to unit length and bias components to [0,1] range.
	float L		= dot( Velocity, Velocity );
	L			= max( L, 1.0f );
	Velocity	= Velocity*0.5f*rsqrt(L) + 0.5f;

	// Clamp so that components are never 0 (special meaning to the motion blur pass).
	Velocity = clamp( Velocity, IndividualVelocityScale.z, IndividualVelocityScale.w );
	OutColor = float4(Velocity, 0, 0);
}
