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.
 
 
 
 
 

141 lines
6.3 KiB

#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 defined(HDR_INPUT)
#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) * _RTHandlePostProcessScale.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), _PostProcessScreenSize.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, float paperWhite, float oneOverPaperWhite)
{
{
// 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
// The pixel values we have are already tonemapped but in the range [0, 10000] nits. To run FXAA properly, we need to convert them
// to a SDR range [0; 1]. Since the tonemapped values are not evenly distributed and mostly close to the paperWhite nits value, we can
// normalize by paperWhite to get most of the scene in [0; 1] range. For the remaining pixels, we can use the FastTonemap() to remap
// them to [0, 1] range.
float lumaNW = Luminance(FastTonemap(rgbNW.xyz * oneOverPaperWhite));
float lumaNE = Luminance(FastTonemap(rgbNE.xyz * oneOverPaperWhite));
float lumaSW = Luminance(FastTonemap(rgbSW.xyz * oneOverPaperWhite));
float lumaSE = Luminance(FastTonemap(rgbSE.xyz * oneOverPaperWhite));
float lumaM = Luminance(FastTonemap(outColor.xyz * oneOverPaperWhite));
#else
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);
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);
#endif
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 * oneOverPaperWhite);
rgb13 = FastTonemap(rgb13 * oneOverPaperWhite);
rgb23 = FastTonemap(rgb23 * oneOverPaperWhite);
rgb33 = FastTonemap(rgb33 * oneOverPaperWhite);
#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) * paperWhite;
#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
}
}