Files
UnrealEngineUWP/Engine/Shaders/PostProcessTemporalAA.usf
Timothy Lottes c78a1994f0 As Brian requested: YCoCg on for the high quality temporal AA.
[CL 2451992 by Timothy Lottes in Main branch]
2015-02-19 14:16:11 -05:00

279 lines
7.2 KiB
Plaintext

// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
/*=============================================================================
PostProcessTemporalAA.usf: Temporal AA
=============================================================================*/
#include "Common.usf"
#include "PostProcessCommon.usf"
#include "DeferredShadingCommon.usf" // FGBufferData
#ifndef ENABLE_TEMPORAL_AA
#define ENABLE_TEMPORAL_AA 1
#endif
float4 CameraMotion[5];
float SampleWeights[9];
float LowpassWeights[9];
float PlusWeights[5];
float2 RandomOffset;
// TODO: This can be removed.
float ClampFeebackMix;
// Faster but less accurate luma computation.
// Luma includes a scaling by 4.
float Luma4(float3 Color)
{
return (Color.g * 2.0) + (Color.r + Color.b);
}
// Optimized HDR weighting function.
float HdrWeight4(float3 Color, float Exposure)
{
return rcp(Luma4(Color) * Exposure + 4.0);
}
float HdrWeightY(float Color, float Exposure)
{
return rcp(Color * Exposure + 1.0);
}
float HdrWeightG(float3 Color, float Exposure)
{
return rcp(Color.g * Exposure + 1.0);
}
float HdrWeightG_(float Color, float Exposure)
{
return rcp(Color * Exposure + 1.0);
}
// Optimized HDR weighting function.
float HdrWeight4_(float Color, float Exposure)
{
return rcp(Color * Exposure + 4.0);
}
// Optimized HDR weighting inverse.
float HdrWeightInv4(float3 Color, float Exposure)
{
return 4.0 * rcp(Luma4(Color) * (-Exposure) + 1.0);
}
float HdrWeightInvG(float3 Color, float Exposure)
{
return rcp(Color.g * (-Exposure) + 1.0);
}
float HdrWeightInvY(float Color, float Exposure)
{
return rcp(Color * (-Exposure) + 1.0);
}
float HdrWeightInv4_(float Color, float Exposure)
{
return 4.0 * rcp(Color * (-Exposure) + 1.0);
}
float HdrWeightInvG_(float Color, float Exposure)
{
return rcp(Color * (-Exposure) + 1.0);
}
// This returns exposure normalized linear luma from a PerceptualLuma4().
float LinearLuma4(float Channel, float Exposure)
{
return Channel * HdrWeightInv4_(Channel, Exposure);
}
// This returns exposure normalized linear luma from a PerceptualLuma4().
float LinearLumaG(float Channel, float Exposure)
{
return Channel * HdrWeightInvG_(Channel, Exposure);
}
float PerceptualLuma4(float3 Color, float Exposure)
{
float L = Luma4(Color);
return L * HdrWeight4_(L, Exposure);
}
float PerceptualLumaG(float3 Color, float Exposure)
{
return Color.g * HdrWeightG_(Color.g, Exposure);
}
float Luma(float3 Color)
{
#if 1
// This seems to work better (less same luma ghost trails).
// CCIR 601 function for luma.
return dot(Color, float3(0.299, 0.587, 0.114));
#else
// Rec 709 function for luma.
return dot(Color, float3(0.2126, 0.7152, 0.0722));
#endif
}
float HighlightCompression(float Channel)
{
return Channel * rcp(1.0 + Channel);
}
float HighlightDecompression(float Channel)
{
return Channel * rcp(1.0 - Channel);
}
float PerceptualLuma(float3 Color, float Exposure)
{
return sqrt(HighlightCompression(Luma(Color) * Exposure));
}
float LinearLuma(float Channel)
{
// This returns exposure normalized linear luma from a PerceptualLuma().
return HighlightDecompression(Channel * Channel);
}
// Intersect ray with AABB, knowing there is an intersection.
// Dir = Ray direction.
// Org = Start of the ray.
// Box = Box is at {0,0,0} with this size.
// Returns distance on line segment.
float IntersectAABB(float3 Dir, float3 Org, float3 Box)
{
#if PS4_PROFILE
// This causes flicker, it should only be used on PS4 until proper fix is in.
if(min(min(abs(Dir.x), abs(Dir.y)), abs(Dir.z)) < (1.0/65536.0)) return 1.0;
#endif
float3 RcpDir = rcp(Dir);
float3 TNeg = ( Box - Org) * RcpDir;
float3 TPos = ((-Box) - Org) * RcpDir;
return max(max(min(TNeg.x, TPos.x), min(TNeg.y, TPos.y)), min(TNeg.z, TPos.z));
}
float HistoryClamp(float3 History, float3 Filtered, float3 NeighborMin, float3 NeighborMax)
{
float3 Min = min(Filtered, min(NeighborMin, NeighborMax));
float3 Max = max(Filtered, max(NeighborMin, NeighborMax));
float3 Avg2 = Max + Min;
float3 Dir = Filtered - History;
float3 Org = History - Avg2 * 0.5;
float3 Scale = Max - Avg2 * 0.5;
return saturate(IntersectAABB(Dir, Org, Scale));
}
float HdrWeight(float3 Color, float Exposure)
{
return rcp(max(Luma(Color) * Exposure, 1.0));
}
float4 HdrLerp(float4 ColorA, float4 ColorB, float Blend, float Exposure)
{
float BlendA = (1.0 - Blend) * HdrWeight(ColorA.rgb, Exposure);
float BlendB = Blend * HdrWeight(ColorB.rgb, Exposure);
float RcpBlend = rcp(BlendA + BlendB);
BlendA *= RcpBlend;
BlendB *= RcpBlend;
return ColorA * BlendA + ColorB * BlendB;
}
void SSRTemporalAAPS( float4 UVAndScreenPos : TEXCOORD0, float3 InExposureScaleVignette : TEXCOORD1, out float4 OutColor : SV_Target0 )
{
#if ENABLE_TEMPORAL_AA
float InExposureScale = InExposureScaleVignette.x;
#define AA_ALPHA 0
#define AA_CROSS 0
#define AA_DYNAMIC 0
#define AA_LERP 8
#define AA_NAN 1
#include "PostProcessTemporalCommon.usf"
#else
// On broken platforms then at least draw something without AA.
OutColor = PostprocessInput0.SampleLevel(PostprocessInput0Sampler, UVAndScreenPos.xy, 0);
#endif
}
void DOFTemporalAAPS( float4 UVAndScreenPos : TEXCOORD0, float3 InExposureScaleVignette : TEXCOORD1, out float4 OutColor : SV_Target0 )
{
#if ENABLE_TEMPORAL_AA
float InExposureScale = InExposureScaleVignette.x;
#define AA_FILTERED 0
#define AA_VELOCITY_WEIGHTING 0
#define AA_ALPHA 0
#define AA_CROSS 4
#define AA_DYNAMIC 1
#define AA_NAN 1
#define AA_BORDER 1
#define AA_FORCE_ALPHA_CLAMP 1
#define AA_GREEN_AS_LUMA 1
#define AA_YCOCG 1
#define AA_DOF 1
#include "PostProcessTemporalCommon.usf"
#else
OutColor = PostprocessInput0.SampleLevel(PostprocessInput0Sampler, UVAndScreenPos.xy, 0);
#endif
}
void LightShaftTemporalAAPS( float4 UVAndScreenPos : TEXCOORD0, float3 InExposureScaleVignette : TEXCOORD1, out float4 OutColor : SV_Target0 )
{
#if ENABLE_TEMPORAL_AA
float InExposureScale = InExposureScaleVignette.x;
#define AA_ALPHA 0
#define AA_CROSS 0
#define AA_DYNAMIC 0
#define AA_LERP 64
#define AA_NAN 1
#include "PostProcessTemporalCommon.usf"
#else
OutColor = PostprocessInput0.SampleLevel(PostprocessInput0Sampler, UVAndScreenPos.xy, 0);
#endif
}
void MainTemporalAAPS( float4 UVAndScreenPos : TEXCOORD0, float3 InExposureScaleVignette : TEXCOORD1, out float4 OutColor : SV_Target0 )
{
#if ENABLE_TEMPORAL_AA
float InExposureScale = InExposureScaleVignette.x;
#define AA_FILTERED 1
#define AA_BORDER 1
#define AA_CROSS 2
#define AA_GREEN_AS_LUMA 1
#define AA_AABB 1
#define AA_LOWPASS 0
#define AA_DEBUG 0
#define AA_VELOCITY_WEIGHTING 1
#define AA_YCOCG 1
#include "PostProcessTemporalCommon.usf"
#else
OutColor = PostprocessInput0.SampleLevel(PostprocessInput0Sampler, UVAndScreenPos.xy, 0);
#endif
}
void MainFastTemporalAAPS( float4 UVAndScreenPos : TEXCOORD0, float3 InExposureScaleVignette : TEXCOORD1, out float4 OutColor : SV_Target0 )
{
#if ENABLE_TEMPORAL_AA
float InExposureScale = InExposureScaleVignette.x;
#define AA_FILTERED 1
#define AA_BORDER 1
#define AA_CROSS 2
#define AA_GREEN_AS_LUMA 1
#define AA_AABB 1
#define AA_LOWPASS 0
#define AA_DEBUG 0
#define AA_VELOCITY_WEIGHTING 0
#define AA_YCOCG 1
#include "PostProcessTemporalCommon.usf"
#else
OutColor = PostprocessInput0.SampleLevel(PostprocessInput0Sampler, UVAndScreenPos.xy, 0);
#endif
}