Rasagar/Library/PackageCache/com.unity.postprocessing/PostProcessing/Shaders/Builtins/TemporalAntialiasing.shader
2024-09-27 20:27:46 +03:00

166 lines
6.1 KiB
Plaintext

Shader "Hidden/PostProcessing/TemporalAntialiasing"
{
HLSLINCLUDE
#pragma exclude_renderers gles psp2
#include "Packages/com.unity.postprocessing/PostProcessing/Shaders/StdLib.hlsl"
#include "Packages/com.unity.postprocessing/PostProcessing/Shaders/Colors.hlsl"
#if UNITY_VERSION >= 201710
#define _MainTexSampler sampler_LinearClamp
#else
#define _MainTexSampler sampler_MainTex
#endif
TEXTURE2D_SAMPLER2D(_MainTex, _MainTexSampler);
float4 _MainTex_TexelSize;
TEXTURE2D_SAMPLER2D(_HistoryTex, sampler_HistoryTex);
TEXTURE2D_SAMPLER2D(_CameraDepthTexture, sampler_CameraDepthTexture);
float4 _CameraDepthTexture_TexelSize;
TEXTURE2D_SAMPLER2D(_CameraMotionVectorsTexture, sampler_CameraMotionVectorsTexture);
float2 _Jitter;
float4 _FinalBlendParameters; // x: static, y: dynamic, z: motion amplification
float _Sharpness;
float2 GetClosestFragment(float2 uv)
{
const float2 k = _CameraDepthTexture_TexelSize.xy;
const float4 neighborhood = float4(
SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, UnityStereoClamp(uv - k)),
SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, UnityStereoClamp(uv + float2(k.x, -k.y))),
SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, UnityStereoClamp(uv + float2(-k.x, k.y))),
SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, UnityStereoClamp(uv + k))
);
#if defined(UNITY_REVERSED_Z)
#define COMPARE_DEPTH(a, b) step(b, a)
#else
#define COMPARE_DEPTH(a, b) step(a, b)
#endif
float3 result = float3(0.0, 0.0, SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture, uv));
result = lerp(result, float3(-1.0, -1.0, neighborhood.x), COMPARE_DEPTH(neighborhood.x, result.z));
result = lerp(result, float3( 1.0, -1.0, neighborhood.y), COMPARE_DEPTH(neighborhood.y, result.z));
result = lerp(result, float3(-1.0, 1.0, neighborhood.z), COMPARE_DEPTH(neighborhood.z, result.z));
result = lerp(result, float3( 1.0, 1.0, neighborhood.w), COMPARE_DEPTH(neighborhood.w, result.z));
return (uv + result.xy * k);
}
float4 ClipToAABB(float4 color, float3 minimum, float3 maximum)
{
// Note: only clips towards aabb center (but fast!)
float3 center = 0.5 * (maximum + minimum);
float3 extents = 0.5 * (maximum - minimum);
// This is actually `distance`, however the keyword is reserved
float3 offset = color.rgb - center;
float3 ts = abs(extents / (offset + 0.0001));
float t = saturate(Min3(ts.x, ts.y, ts.z));
color.rgb = center + offset * t;
return color;
}
struct OutputSolver
{
float4 destination : SV_Target0;
float4 history : SV_Target1;
};
OutputSolver Solve(float2 motion, float2 texcoord)
{
const float2 k = _MainTex_TexelSize.xy;
float2 uv = UnityStereoClamp(texcoord - _Jitter);
float4 color = SAMPLE_TEXTURE2D(_MainTex, _MainTexSampler, uv);
float4 topLeft = SAMPLE_TEXTURE2D(_MainTex, _MainTexSampler, UnityStereoClamp(uv - k * 0.5));
float4 bottomRight = SAMPLE_TEXTURE2D(_MainTex, _MainTexSampler, UnityStereoClamp(uv + k * 0.5));
float4 corners = 4.0 * (topLeft + bottomRight) - 2.0 * color;
// Sharpen output
color += (color - (corners * 0.166667)) * 2.718282 * _Sharpness;
color = clamp(color, 0.0, HALF_MAX_MINUS1);
// Tonemap color and history samples
float4 average = (corners + color) * 0.142857;
float4 history = SAMPLE_TEXTURE2D(_HistoryTex, sampler_HistoryTex, UnityStereoClamp(texcoord - motion));
float motionLength = length(motion);
float2 luma = float2(Luminance(average), Luminance(color));
//float nudge = 4.0 * abs(luma.x - luma.y);
float nudge = lerp(4.0, 0.25, saturate(motionLength * 100.0)) * abs(luma.x - luma.y);
float4 minimum = min(bottomRight, topLeft) - nudge;
float4 maximum = max(topLeft, bottomRight) + nudge;
// Clip history samples
history = ClipToAABB(history, minimum.xyz, maximum.xyz);
// Blend method
float weight = clamp(
lerp(_FinalBlendParameters.x, _FinalBlendParameters.y, motionLength * _FinalBlendParameters.z),
_FinalBlendParameters.y, _FinalBlendParameters.x
);
color = lerp(color, history, weight);
color = clamp(color, 0.0, HALF_MAX_MINUS1);
OutputSolver output;
output.destination = color;
output.history = color;
return output;
}
OutputSolver FragSolverDilate(VaryingsDefault i)
{
float2 closest = GetClosestFragment(i.texcoordStereo);
float2 motion = SAMPLE_TEXTURE2D(_CameraMotionVectorsTexture, sampler_CameraMotionVectorsTexture, closest).xy;
return Solve(motion, i.texcoordStereo);
}
OutputSolver FragSolverNoDilate(VaryingsDefault i)
{
// Don't dilate in ortho !
float2 motion = SAMPLE_TEXTURE2D(_CameraMotionVectorsTexture, sampler_CameraMotionVectorsTexture, i.texcoordStereo).xy;
return Solve(motion, i.texcoordStereo);
}
ENDHLSL
SubShader
{
Cull Off ZWrite Off ZTest Always
// 0: Perspective
Pass
{
HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment FragSolverDilate
ENDHLSL
}
// 1: Ortho
Pass
{
HLSLPROGRAM
#pragma vertex VertDefault
#pragma fragment FragSolverNoDilate
ENDHLSL
}
}
}