133 lines
5.3 KiB
HLSL
133 lines
5.3 KiB
HLSL
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
|
|
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/PostProcessDefines.hlsl"
|
|
|
|
#define FXAA_HDR_MAPUNMAP 0
|
|
#define FXAA_SPAN_MAX (8.0)
|
|
#define FXAA_REDUCE_MUL (1.0 / 8.0)
|
|
#define FXAA_REDUCE_MIN (1.0 / 128.0)
|
|
|
|
float3 Fetch(TEXTURE2D_X_PARAM(_InputTexture, _InputTextureSampler), float2 coords, float2 offset)
|
|
{
|
|
float2 uv = saturate(coords + offset) * _RTHandleScale.xy;
|
|
return SAMPLE_TEXTURE2D_X_LOD(_InputTexture, _InputTextureSampler, uv, 0.0).xyz;
|
|
}
|
|
|
|
CTYPE Load(TEXTURE2D_X(_InputTexture), int2 icoords, int idx, int idy)
|
|
{
|
|
return LOAD_TEXTURE2D_X(_InputTexture, min(icoords + int2(idx, idy), _ScreenSize.xy - 1.0)).CTYPE_SWIZZLE;
|
|
}
|
|
|
|
float FetchAlpha(TEXTURE2D_X_PARAM(_InputTexture, _InputTextureSampler), float2 coords, float2 offset)
|
|
{
|
|
float2 uv = saturate(coords + offset) * _RTHandleScale.xy;
|
|
return SAMPLE_TEXTURE2D_X_LOD(_InputTexture, _InputTextureSampler, uv, 0.0).w;
|
|
}
|
|
|
|
void RunFXAA(TEXTURE2D_X_PARAM(_InputTexture, _InputTextureSampler), inout CTYPE outColor, uint2 positionSS, float2 positionNDC)
|
|
{
|
|
{
|
|
// Edge detection
|
|
CTYPE rgbNW = Load(_InputTexture, positionSS, -1, -1);
|
|
CTYPE rgbNE = Load(_InputTexture, positionSS, 1, -1);
|
|
CTYPE rgbSW = Load(_InputTexture, positionSS, -1, 1);
|
|
CTYPE rgbSE = Load(_InputTexture, positionSS, 1, 1);
|
|
|
|
#if !FXAA_HDR_MAPUNMAP
|
|
rgbNW.xyz = saturate(rgbNW.xyz);
|
|
rgbNE.xyz = saturate(rgbNE.xyz);
|
|
rgbSW.xyz = saturate(rgbSW.xyz);
|
|
rgbSE.xyz = saturate(rgbSE.xyz);
|
|
outColor.xyz = saturate(outColor.xyz);
|
|
#endif
|
|
|
|
float lumaNW = Luminance(rgbNW.xyz);
|
|
float lumaNE = Luminance(rgbNE.xyz);
|
|
float lumaSW = Luminance(rgbSW.xyz);
|
|
float lumaSE = Luminance(rgbSE.xyz);
|
|
float lumaM = Luminance(outColor.xyz);
|
|
|
|
float2 dir;
|
|
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
|
|
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
|
|
|
|
float lumaSum = lumaNW + lumaNE + lumaSW + lumaSE;
|
|
float dirReduce = max(lumaSum * (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
|
|
float rcpDirMin = rcp(min(abs(dir.x), abs(dir.y)) + dirReduce);
|
|
|
|
dir = min((FXAA_SPAN_MAX).xx, max((-FXAA_SPAN_MAX).xx, dir * rcpDirMin)) * _ScreenSize.zw;
|
|
|
|
// Blur
|
|
float3 rgb03 = Fetch(TEXTURE2D_X_ARGS(_InputTexture, _InputTextureSampler), positionNDC, dir * (0.0 / 3.0 - 0.5));
|
|
float3 rgb13 = Fetch(TEXTURE2D_X_ARGS(_InputTexture, _InputTextureSampler), positionNDC, dir * (1.0 / 3.0 - 0.5));
|
|
float3 rgb23 = Fetch(TEXTURE2D_X_ARGS(_InputTexture, _InputTextureSampler), positionNDC, dir * (2.0 / 3.0 - 0.5));
|
|
float3 rgb33 = Fetch(TEXTURE2D_X_ARGS(_InputTexture, _InputTextureSampler), positionNDC, dir * (3.0 / 3.0 - 0.5));
|
|
|
|
#if FXAA_HDR_MAPUNMAP
|
|
rgb03 = FastTonemap(rgb03);
|
|
rgb13 = FastTonemap(rgb13);
|
|
rgb23 = FastTonemap(rgb23);
|
|
rgb33 = FastTonemap(rgb33);
|
|
#else
|
|
rgb03 = saturate(rgb03);
|
|
rgb13 = saturate(rgb13);
|
|
rgb23 = saturate(rgb23);
|
|
rgb33 = saturate(rgb33);
|
|
#endif
|
|
|
|
float3 rgbA = 0.5 * (rgb13 + rgb23);
|
|
float3 rgbB = rgbA * 0.5 + 0.25 * (rgb03 + rgb33);
|
|
|
|
float lumaB = Luminance(rgbB);
|
|
|
|
float lumaMin = Min3(lumaM, lumaNW, Min3(lumaNE, lumaSW, lumaSE));
|
|
float lumaMax = Max3(lumaM, lumaNW, Max3(lumaNE, lumaSW, lumaSE));
|
|
|
|
float3 rgb = ((lumaB < lumaMin) || (lumaB > lumaMax)) ? rgbA : rgbB;
|
|
|
|
#if FXAA_HDR_MAPUNMAP
|
|
outColor.xyz = FastTonemapInvert(rgb);
|
|
#else
|
|
outColor.xyz = rgb;
|
|
#endif
|
|
|
|
#ifdef ENABLE_ALPHA
|
|
// FXAA for the alpha channel: alpha can be completely decorelated from the RGB channels, so we might fetch different neighbors for the alpha!
|
|
// For this reason we have to recompute the fetch direction
|
|
lumaNW = rgbNW.w;
|
|
lumaNE = rgbNE.w;
|
|
lumaSW = rgbSW.w;
|
|
lumaSE = rgbSE.w;
|
|
lumaM = outColor.w;
|
|
|
|
dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
|
|
dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
|
|
|
|
lumaSum = lumaNW + lumaNE + lumaSW + lumaSE;
|
|
dirReduce = max(lumaSum * (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
|
|
rcpDirMin = rcp(min(abs(dir.x), abs(dir.y)) + dirReduce);
|
|
|
|
dir = min((FXAA_SPAN_MAX).xx, max((-FXAA_SPAN_MAX).xx, dir * rcpDirMin)) * _ScreenSize.zw;
|
|
|
|
// Blur
|
|
float a03 = FetchAlpha(TEXTURE2D_X_ARGS(_InputTexture, _InputTextureSampler), positionNDC, dir * (0.0 / 3.0 - 0.5));
|
|
float a13 = FetchAlpha(TEXTURE2D_X_ARGS(_InputTexture, _InputTextureSampler), positionNDC, dir * (1.0 / 3.0 - 0.5));
|
|
float a23 = FetchAlpha(TEXTURE2D_X_ARGS(_InputTexture, _InputTextureSampler), positionNDC, dir * (2.0 / 3.0 - 0.5));
|
|
float a33 = FetchAlpha(TEXTURE2D_X_ARGS(_InputTexture, _InputTextureSampler), positionNDC, dir * (3.0 / 3.0 - 0.5));
|
|
|
|
a03 = saturate(a03);
|
|
a13 = saturate(a13);
|
|
a23 = saturate(a23);
|
|
a33 = saturate(a33);
|
|
|
|
float A = 0.5 * (a13 + a23);
|
|
float B = A * 0.5 + 0.25 * (a03 + a33);
|
|
|
|
lumaMin = Min3(lumaM, lumaNW, Min3(lumaNE, lumaSW, lumaSE));
|
|
lumaMax = Max3(lumaM, lumaNW, Max3(lumaNE, lumaSW, lumaSE));
|
|
|
|
outColor.w = ((lumaB < lumaMin) || (lumaB > lumaMax)) ? A : B;
|
|
#endif
|
|
|
|
}
|
|
}
|