You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
455 lines
18 KiB
455 lines
18 KiB
Shader "Hidden/HDRP/TemporalAA"
|
|
{
|
|
Properties
|
|
{
|
|
[HideInInspector] _StencilRef("_StencilRef", Int) = 2
|
|
[HideInInspector] _StencilMask("_StencilMask", Int) = 2
|
|
}
|
|
|
|
HLSLINCLUDE
|
|
|
|
#pragma target 4.5
|
|
#pragma multi_compile_local_fragment _ ENABLE_ALPHA
|
|
#pragma multi_compile_local_fragment _ FORCE_BILINEAR_HISTORY
|
|
#pragma multi_compile_local_fragment _ ENABLE_MV_REJECTION
|
|
#pragma multi_compile_local_fragment _ ANTI_RINGING
|
|
#pragma multi_compile_local_fragment _ HISTORY_CONTRAST_ANTI_FLICKER
|
|
#pragma multi_compile_local_fragment _ DIRECT_STENCIL_SAMPLE
|
|
#pragma multi_compile_local_fragment LOW_QUALITY MEDIUM_QUALITY HIGH_QUALITY TAA_UPSAMPLE POST_DOF
|
|
|
|
#pragma editor_sync_compilation
|
|
// #pragma enable_d3d11_debug_symbols
|
|
|
|
#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/Builtin/BuiltinData.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/PostProcessDefines.hlsl"
|
|
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/TemporalAntialiasingOptionDef.hlsl"
|
|
|
|
// ---------------------------------------------------
|
|
// Tier definitions
|
|
// ---------------------------------------------------
|
|
// TODO: YCoCg gives better result in terms of ghosting reduction, but it also seems to let through
|
|
// some additional aliasing that is undesirable in some occasions. Would like to investigate better.
|
|
#ifdef LOW_QUALITY
|
|
#define YCOCG 0
|
|
#define HISTORY_SAMPLING_METHOD BILINEAR
|
|
#define WIDE_NEIGHBOURHOOD 0
|
|
#define NEIGHBOUROOD_CORNER_METHOD MINMAX
|
|
#define CENTRAL_FILTERING NO_FILTERING
|
|
#define HISTORY_CLIP SIMPLE_CLAMP
|
|
#define ANTI_FLICKER 0
|
|
#define VELOCITY_REJECTION (defined(ENABLE_MV_REJECTION) && 0)
|
|
#define PERCEPTUAL_SPACE 0
|
|
#define PERCEPTUAL_SPACE_ONLY_END 1 && (PERCEPTUAL_SPACE == 0)
|
|
#define BLEND_FACTOR_MV_TUNE 0
|
|
#define MV_DILATION DEPTH_DILATION
|
|
|
|
#elif defined(MEDIUM_QUALITY)
|
|
#define YCOCG 1
|
|
#define HISTORY_SAMPLING_METHOD BICUBIC_5TAP
|
|
#define WIDE_NEIGHBOURHOOD 0
|
|
#define NEIGHBOUROOD_CORNER_METHOD VARIANCE
|
|
#define CENTRAL_FILTERING NO_FILTERING
|
|
#define HISTORY_CLIP DIRECT_CLIP
|
|
#define ANTI_FLICKER 1
|
|
#define ANTI_FLICKER_MV_DEPENDENT 0
|
|
#define VELOCITY_REJECTION (defined(ENABLE_MV_REJECTION) && 0)
|
|
#define PERCEPTUAL_SPACE 1
|
|
#define PERCEPTUAL_SPACE_ONLY_END 0 && (PERCEPTUAL_SPACE == 0)
|
|
#define BLEND_FACTOR_MV_TUNE 1
|
|
#define MV_DILATION DEPTH_DILATION
|
|
|
|
#elif defined(HIGH_QUALITY) // TODO: We can do better in term of quality here (e.g. subpixel changes etc) and can be optimized a bit more
|
|
#define YCOCG 1
|
|
#define HISTORY_SAMPLING_METHOD BICUBIC_5TAP
|
|
#define WIDE_NEIGHBOURHOOD 1
|
|
#define NEIGHBOUROOD_CORNER_METHOD VARIANCE
|
|
#define CENTRAL_FILTERING BLACKMAN_HARRIS
|
|
#define HISTORY_CLIP DIRECT_CLIP
|
|
#define ANTI_FLICKER 1
|
|
#define ANTI_FLICKER_MV_DEPENDENT 1
|
|
#define VELOCITY_REJECTION defined(ENABLE_MV_REJECTION)
|
|
#define PERCEPTUAL_SPACE 1
|
|
#define PERCEPTUAL_SPACE_ONLY_END 0 && (PERCEPTUAL_SPACE == 0)
|
|
#define BLEND_FACTOR_MV_TUNE 1
|
|
#define MV_DILATION DEPTH_DILATION
|
|
|
|
#elif defined(TAA_UPSAMPLE)
|
|
#define YCOCG 1
|
|
#define HISTORY_SAMPLING_METHOD BICUBIC_5TAP
|
|
#define WIDE_NEIGHBOURHOOD 1
|
|
#define NEIGHBOUROOD_CORNER_METHOD VARIANCE
|
|
#define CENTRAL_FILTERING UPSAMPLE
|
|
#define HISTORY_CLIP DIRECT_CLIP
|
|
#define ANTI_FLICKER 1
|
|
#define ANTI_FLICKER_MV_DEPENDENT 1
|
|
#define VELOCITY_REJECTION defined(ENABLE_MV_REJECTION)
|
|
#define PERCEPTUAL_SPACE 1
|
|
#define PERCEPTUAL_SPACE_ONLY_END 0 && (PERCEPTUAL_SPACE == 0)
|
|
#define BLEND_FACTOR_MV_TUNE 1
|
|
#define MV_DILATION DEPTH_DILATION
|
|
|
|
#elif defined(POST_DOF)
|
|
#define YCOCG 1
|
|
#define HISTORY_SAMPLING_METHOD BILINEAR
|
|
#define WIDE_NEIGHBOURHOOD 0
|
|
#define NEIGHBOUROOD_CORNER_METHOD VARIANCE
|
|
#define CENTRAL_FILTERING NO_FILTERING
|
|
#define HISTORY_CLIP DIRECT_CLIP
|
|
#define ANTI_FLICKER 1
|
|
#define ANTI_FLICKER_MV_DEPENDENT 1
|
|
#define VELOCITY_REJECTION defined(ENABLE_MV_REJECTION)
|
|
#define PERCEPTUAL_SPACE 1
|
|
#define PERCEPTUAL_SPACE_ONLY_END 0 && (PERCEPTUAL_SPACE == 0)
|
|
#define BLEND_FACTOR_MV_TUNE 1
|
|
#define MV_DILATION DEPTH_DILATION
|
|
|
|
#endif
|
|
|
|
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/TemporalAntialiasing.hlsl"
|
|
|
|
TEXTURE2D_X(_DepthTexture);
|
|
TEXTURE2D_X(_InputTexture);
|
|
TEXTURE2D_X(_InputHistoryTexture);
|
|
#ifdef SHADER_API_PSSL
|
|
RW_TEXTURE2D_X(CTYPE, _OutputHistoryTexture) : register(u0);
|
|
#else
|
|
RW_TEXTURE2D_X(CTYPE, _OutputHistoryTexture) : register(u1);
|
|
#endif
|
|
|
|
#if DIRECT_STENCIL_SAMPLE
|
|
TEXTURE2D_X_UINT2(_StencilTexture);
|
|
#endif
|
|
|
|
float4 _TaaPostParameters;
|
|
float4 _TaaPostParameters1;
|
|
float4 _TaaHistorySize;
|
|
|
|
float4 _TaaFilterWeights[2];
|
|
float4 _NeighbourOffsets[4];
|
|
|
|
#define _HistorySharpening _TaaPostParameters.x
|
|
#define _AntiFlickerIntensity _TaaPostParameters.y
|
|
#define _SpeedRejectionIntensity _TaaPostParameters.z
|
|
#define _ContrastForMaxAntiFlicker _TaaPostParameters.w
|
|
|
|
#define _BaseBlendFactor _TaaPostParameters1.x
|
|
#define _CentralWeight _TaaPostParameters1.y
|
|
#define _ExcludeTAABit (uint)_TaaPostParameters1.z
|
|
#define _HistoryContrastBlendLerp _TaaPostParameters1.w
|
|
|
|
// TAAU specific
|
|
float4 _TaauParameters;
|
|
#define _TAAUFilterRcpSigma2 _TaauParameters.x
|
|
#define _TAAUScale _TaauParameters.y
|
|
#define _TAAUBoxConfidenceThresh _TaauParameters.z
|
|
#define _TAAURenderScale _TaauParameters.w
|
|
#define _InputSize _ScreenSize
|
|
|
|
|
|
float4 _TaaScales;
|
|
// NOTE: We need to define custom scales instead of using the default ones for several reasons.
|
|
// 1- This shader is shared by TAA and Temporal Upscaling, having a single scale defined in C# instead helps readability.
|
|
// 2- Especially with history, when doing temporal upscaling we have an unusal situation in which the history size doesn't match the input size.
|
|
// This in turns lead to some rounding issue (final viewport is not rounded, while the render target size is) that cause artifacts.
|
|
// To fix said artifacts we recompute manually the scales as we need them.
|
|
#define _RTHandleScaleForTAAHistory _TaaScales.xy
|
|
#define _RTHandleScaleForTAA _TaaScales.zw
|
|
|
|
#if VELOCITY_REJECTION
|
|
TEXTURE2D_X(_InputVelocityMagnitudeHistory);
|
|
#ifdef SHADER_API_PSSL
|
|
RW_TEXTURE2D_X(float, _OutputVelocityMagnitudeHistory) : register(u1);
|
|
#else
|
|
RW_TEXTURE2D_X(float, _OutputVelocityMagnitudeHistory) : register(u2);
|
|
#endif
|
|
#endif
|
|
|
|
struct Attributes
|
|
{
|
|
uint vertexID : SV_VertexID;
|
|
UNITY_VERTEX_INPUT_INSTANCE_ID
|
|
};
|
|
|
|
struct Varyings
|
|
{
|
|
float4 positionCS : SV_POSITION;
|
|
float2 texcoord : TEXCOORD0;
|
|
UNITY_VERTEX_OUTPUT_STEREO
|
|
};
|
|
|
|
Varyings Vert(Attributes input)
|
|
{
|
|
Varyings output;
|
|
UNITY_SETUP_INSTANCE_ID(input);
|
|
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
|
|
output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID);
|
|
output.texcoord = GetFullScreenTriangleTexCoord(input.vertexID);
|
|
return output;
|
|
}
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
void FragTAA(Varyings input, out CTYPE outColor : SV_Target0)
|
|
{
|
|
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
|
SetNeighbourOffsets(_NeighbourOffsets);
|
|
|
|
float sharpenStrength = _TaaFrameInfo.x;
|
|
float2 jitter = _TaaJitterStrength.zw;
|
|
|
|
float2 uv = input.texcoord;
|
|
|
|
#ifdef TAA_UPSAMPLE
|
|
float2 outputPixInInput = input.texcoord * _InputSize.xy - _TaaJitterStrength.xy;
|
|
|
|
uv = _InputSize.zw * (0.5f + floor(outputPixInInput));
|
|
#endif
|
|
|
|
// --------------- Get closest motion vector ---------------
|
|
|
|
int2 samplePos = input.positionCS.xy;
|
|
|
|
#ifdef TAA_UPSAMPLE
|
|
samplePos = outputPixInInput;
|
|
#endif
|
|
|
|
bool excludeTAABit = false;
|
|
#if DIRECT_STENCIL_SAMPLE
|
|
uint stencil = GetStencilValue(LOAD_TEXTURE2D_X(_StencilTexture, samplePos));
|
|
excludeTAABit = (stencil == _ExcludeTAABit);
|
|
#endif
|
|
|
|
float lengthMV = 0;
|
|
|
|
float2 motionVector = GetMotionVector(_CameraMotionVectorsTexture, _DepthTexture, uv, samplePos, _InputSize);
|
|
// --------------------------------------------------------
|
|
|
|
// --------------- Get resampled history ---------------
|
|
float2 prevUV = input.texcoord - motionVector;
|
|
|
|
CTYPE history = GetFilteredHistory(_InputHistoryTexture, prevUV, _HistorySharpening, _TaaHistorySize, _RTHandleScaleForTAAHistory);
|
|
bool offScreen = any(abs(prevUV * 2 - 1) >= (1.0f - (1.0 * _TaaHistorySize.zw)));
|
|
history.xyz *= PerceptualWeight(history);
|
|
// -----------------------------------------------------
|
|
|
|
// --------------- Gather neigbourhood data ---------------
|
|
CTYPE color = Fetch4(_InputTexture, uv, 0.0, _RTHandleScaleForTAA).CTYPE_SWIZZLE;
|
|
|
|
#if defined(ENABLE_ALPHA)
|
|
// Removes history rejection when the current alpha value is 0. Instead it does blend with the history color when alpha value is 0 on the current plane.
|
|
// The reasoning for blending again with the history when alpha is 0 is because we want the color to blend a bit with opacity, which is the main reason for the alpha values. sort of like a precomputed color
|
|
// As a safety, we set the color to black if alpha is 0. This results in better image quality when alpha is enabled.
|
|
color = color.w > 0.0 ? color : (CTYPE)0;
|
|
#endif
|
|
|
|
if (!excludeTAABit)
|
|
{
|
|
color = clamp(color, 0, CLAMP_MAX);
|
|
color = ConvertToWorkingSpace(color);
|
|
|
|
NeighbourhoodSamples samples;
|
|
GatherNeighbourhood(_InputTexture, uv, floor(input.positionCS.xy), color, _RTHandleScaleForTAA, samples);
|
|
// --------------------------------------------------------
|
|
|
|
// --------------- Filter central sample ---------------
|
|
float4 filterParams = 0;
|
|
#ifdef TAA_UPSAMPLE
|
|
filterParams.x = _TAAUFilterRcpSigma2;
|
|
filterParams.y = _TAAUScale;
|
|
filterParams.zw = outputPixInInput - (floor(outputPixInInput) + 0.5f);
|
|
#endif
|
|
|
|
#if CENTRAL_FILTERING == BLACKMAN_HARRIS
|
|
CTYPE filteredColor = FilterCentralColor(samples, _CentralWeight, _TaaFilterWeights);
|
|
#else
|
|
CTYPE filteredColor = FilterCentralColor(samples, filterParams);
|
|
#endif
|
|
// ------------------------------------------------------
|
|
|
|
if (offScreen)
|
|
history = filteredColor;
|
|
|
|
// --------------- Get neighbourhood information and clamp history ---------------
|
|
float colorLuma = GetLuma(filteredColor);
|
|
float historyLuma = GetLuma(history);
|
|
|
|
float motionVectorLength = 0.0f;
|
|
float motionVectorLenInPixels = 0.0f;
|
|
|
|
#if ANTI_FLICKER_MV_DEPENDENT || VELOCITY_REJECTION || BLEND_FACTOR_MV_TUNE
|
|
motionVectorLength = length(motionVector);
|
|
motionVectorLenInPixels = motionVectorLength * length(_InputSize.xy);
|
|
#endif
|
|
|
|
float aggressivelyClampedHistoryLuma = 0;
|
|
GetNeighbourhoodCorners(samples, historyLuma, colorLuma, float2(_AntiFlickerIntensity, _ContrastForMaxAntiFlicker), motionVectorLenInPixels, _TAAURenderScale, aggressivelyClampedHistoryLuma);
|
|
|
|
history = GetClippedHistory(filteredColor, history, samples.minNeighbour, samples.maxNeighbour);
|
|
if (sharpenStrength > 0)
|
|
filteredColor = SharpenColor(samples, filteredColor, sharpenStrength);
|
|
// ------------------------------------------------------------------------------
|
|
|
|
// --------------- Compute blend factor for history ---------------
|
|
float blendFactor = GetBlendFactor(colorLuma, aggressivelyClampedHistoryLuma, GetLuma(samples.minNeighbour), GetLuma(samples.maxNeighbour), _BaseBlendFactor, _HistoryContrastBlendLerp);
|
|
#if BLEND_FACTOR_MV_TUNE
|
|
blendFactor = lerp(blendFactor, saturate(2.0f * blendFactor), saturate(motionVectorLenInPixels / 50.0f));
|
|
#endif
|
|
// --------------------------------------------------------
|
|
|
|
// ------------------- Alpha handling ---------------------------
|
|
#if defined(ENABLE_ALPHA)
|
|
// Compute the antialiased alpha value
|
|
filteredColor.w = lerp(history.w, filteredColor.w, blendFactor);
|
|
// TAA should not overwrite pixels with zero alpha. This allows camera stacking with mixed TAA settings (bottom camera with TAA OFF and top camera with TAA ON).
|
|
CTYPE unjitteredColor = Fetch4(_InputTexture, input.texcoord - color.w * jitter, 0.0, _RTHandleScale.xy).CTYPE_SWIZZLE;
|
|
unjitteredColor = ConvertToWorkingSpace(unjitteredColor);
|
|
unjitteredColor.xyz *= PerceptualWeight(unjitteredColor);
|
|
filteredColor.xyz = lerp(unjitteredColor.xyz, filteredColor.xyz, filteredColor.w);
|
|
#endif
|
|
// ---------------------------------------------------------------
|
|
|
|
// --------------- Blend to final value and output ---------------
|
|
|
|
#if VELOCITY_REJECTION
|
|
// The 10 multiplier serves a double purpose, it is an empirical scale value used to perform the rejection and it also helps with storing the value itself.
|
|
lengthMV = motionVectorLength * 10;
|
|
blendFactor = ModifyBlendWithMotionVectorRejection(_InputVelocityMagnitudeHistory, lengthMV, prevUV, blendFactor, _SpeedRejectionIntensity, _RTHandleScaleForTAAHistory);
|
|
#endif
|
|
|
|
#ifdef TAA_UPSAMPLE
|
|
blendFactor *= GetUpsampleConfidence(filterParams.zw, _TAAUBoxConfidenceThresh, _TAAUFilterRcpSigma2, _TAAUScale);
|
|
#endif
|
|
blendFactor = clamp(blendFactor, 0.03f, 0.98f);
|
|
|
|
CTYPE finalColor;
|
|
#if PERCEPTUAL_SPACE_ONLY_END
|
|
finalColor.xyz = lerp(ReinhardToneMap(history).xyz, ReinhardToneMap(filteredColor).xyz, blendFactor);
|
|
finalColor.xyz = InverseReinhardToneMap(finalColor).xyz;
|
|
#else
|
|
finalColor.xyz = lerp(history.xyz, filteredColor.xyz, blendFactor);
|
|
finalColor.xyz *= PerceptualInvWeight(finalColor);
|
|
#endif
|
|
|
|
color.xyz = ConvertToOutputSpace(finalColor.xyz);
|
|
color.xyz = clamp(color.xyz, 0, CLAMP_MAX);
|
|
#if defined(ENABLE_ALPHA)
|
|
// Set output alpha to the antialiased alpha.
|
|
color.w = filteredColor.w;
|
|
#endif
|
|
}
|
|
|
|
_OutputHistoryTexture[COORD_TEXTURE2D_X(input.positionCS.xy)] = color.CTYPE_SWIZZLE;
|
|
outColor = color.CTYPE_SWIZZLE;
|
|
#if VELOCITY_REJECTION && !defined(POST_DOF)
|
|
_OutputVelocityMagnitudeHistory[COORD_TEXTURE2D_X(input.positionCS.xy)] = lengthMV;
|
|
#endif
|
|
// -------------------------------------------------------------
|
|
}
|
|
|
|
void FragExcludedTAA(Varyings input, out CTYPE outColor : SV_Target0)
|
|
{
|
|
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
|
|
|
float2 jitter = _TaaJitterStrength.zw;
|
|
float2 uv = input.texcoord - jitter;
|
|
|
|
outColor = Fetch4(_InputTexture, uv, 0.0, _RTHandleScale.xy).CTYPE_SWIZZLE;
|
|
}
|
|
|
|
void FragCopyHistory(Varyings input, out CTYPE outColor : SV_Target0)
|
|
{
|
|
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);
|
|
|
|
float2 jitter = _TaaJitterStrength.zw;
|
|
float2 uv = input.texcoord;
|
|
|
|
#ifdef TAA_UPSAMPLE
|
|
float2 outputPixInInput = input.texcoord * _InputSize.xy - _TaaJitterStrength.xy;
|
|
|
|
uv = _InputSize.zw * (0.5f + floor(outputPixInInput));
|
|
#endif
|
|
CTYPE color = Fetch4(_InputTexture, uv, 0.0, _RTHandleScaleForTAA).CTYPE_SWIZZLE;
|
|
|
|
outColor = color;
|
|
}
|
|
|
|
ENDHLSL
|
|
|
|
SubShader
|
|
{
|
|
Tags{ "RenderPipeline" = "HDRenderPipeline" }
|
|
|
|
// TAA
|
|
Pass
|
|
{
|
|
Name "TAA"
|
|
Stencil
|
|
{
|
|
ReadMask [_StencilMask] // ExcludeFromTAA
|
|
Ref [_StencilRef] // ExcludeFromTAA
|
|
Comp NotEqual
|
|
Pass Keep
|
|
}
|
|
|
|
ZWrite Off ZTest Always Blend Off Cull Off
|
|
|
|
HLSLPROGRAM
|
|
#pragma vertex Vert
|
|
#pragma fragment FragTAA
|
|
ENDHLSL
|
|
}
|
|
|
|
// Excluded from TAA
|
|
// Note: This is a straightup passthrough now, but it would be interesting instead to try to reduce history influence instead.
|
|
Pass
|
|
{
|
|
Name "Excluded From TAA"
|
|
Stencil
|
|
{
|
|
ReadMask [_StencilMask]
|
|
Ref [_StencilRef]
|
|
Comp Equal
|
|
Pass Keep
|
|
}
|
|
|
|
ZWrite Off ZTest Always Blend Off Cull Off
|
|
|
|
HLSLPROGRAM
|
|
#pragma vertex Vert
|
|
#pragma fragment FragExcludedTAA
|
|
ENDHLSL
|
|
}
|
|
|
|
Pass // TAAU
|
|
{
|
|
Name "TAAU"
|
|
// We cannot stencil with TAAU, we will need to manually sample the texture.
|
|
|
|
ZWrite Off ZTest Always Blend Off Cull Off
|
|
|
|
HLSLPROGRAM
|
|
#pragma vertex Vert
|
|
#pragma fragment FragTAA
|
|
ENDHLSL
|
|
}
|
|
|
|
Pass // Copy history
|
|
{
|
|
Name "Copy History"
|
|
ZWrite Off ZTest Always Blend Off Cull Off
|
|
|
|
HLSLPROGRAM
|
|
#pragma vertex Vert
|
|
#pragma fragment FragCopyHistory
|
|
ENDHLSL
|
|
}
|
|
|
|
}
|
|
Fallback Off
|
|
}
|