| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- #include <common/texture/texture-lod>
- #define int2 vec2
- #define float2 vec2
- #define float3 vec3
- #define float4 vec4
- #define FxaaBool3 bvec3
- #define FxaaInt2 vec2
- #define FxaaFloat2 vec2
- #define FxaaFloat3 vec3
- #define FxaaFloat4 vec4
- #define FxaaBool2Float(a) mix(0.0, 1.0, (a))
- #define FxaaPow3(x, y) pow(x, y)
- #define FxaaSel3(f, t, b) mix((f), (t), (b))
- #define FxaaToFloat3(a) FxaaFloat3((a), (a), (a))
- float4 FxaaTexLod0(sampler2D tex, float2 pos) {
- #if defined(CC_USE_WGPU)
- return textureLod(tex, pos.xy, 0.0);
- #else
- return texture(tex, pos.xy);
- #endif
- }
- float4 FxaaTexGrad(sampler2D tex, float2 pos, float2 grad) {
- return fragTextureGrad(tex, pos.xy, grad, grad);
- }
- float4 FxaaTexOff(sampler2D tex, float2 pos, int2 off, float2 rcpFrame) {
- return FxaaTexLod0(tex, pos.xy + vec2(off.x, off.y) * rcpFrame);
- }
- #define FXAA_SRGB_ROP 0
- #ifndef FXAA_PRESET
- #define FXAA_PRESET 3
- #endif
- #if (FXAA_PRESET == 0)
- #define FXAA_EDGE_THRESHOLD (1.0/4.0)
- #define FXAA_EDGE_THRESHOLD_MIN (1.0/12.0)
- #define FXAA_SEARCH_STEPS 2
- #define FXAA_SEARCH_ACCELERATION 4
- #define FXAA_SEARCH_THRESHOLD (1.0/4.0)
- #define FXAA_SUBPIX 1
- #define FXAA_SUBPIX_FASTER 1
- #define FXAA_SUBPIX_CAP (2.0/3.0)
- #define FXAA_SUBPIX_TRIM (1.0/4.0)
- #endif
- #if (FXAA_PRESET == 1)
- #define FXAA_EDGE_THRESHOLD (1.0/8.0)
- #define FXAA_EDGE_THRESHOLD_MIN (1.0/16.0)
- #define FXAA_SEARCH_STEPS 4
- #define FXAA_SEARCH_ACCELERATION 3
- #define FXAA_SEARCH_THRESHOLD (1.0/4.0)
- #define FXAA_SUBPIX 1
- #define FXAA_SUBPIX_FASTER 0
- #define FXAA_SUBPIX_CAP (3.0/4.0)
- #define FXAA_SUBPIX_TRIM (1.0/4.0)
- #endif
- #if (FXAA_PRESET == 2)
- #define FXAA_EDGE_THRESHOLD (1.0/8.0)
- #define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
- #define FXAA_SEARCH_STEPS 8
- #define FXAA_SEARCH_ACCELERATION 2
- #define FXAA_SEARCH_THRESHOLD (1.0/4.0)
- #define FXAA_SUBPIX 1
- #define FXAA_SUBPIX_FASTER 0
- #define FXAA_SUBPIX_CAP (3.0/4.0)
- #define FXAA_SUBPIX_TRIM (1.0/4.0)
- #endif
- #if (FXAA_PRESET == 3)
- #define FXAA_EDGE_THRESHOLD (1.0/8.0)
- #define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
- #define FXAA_SEARCH_STEPS 16
- #define FXAA_SEARCH_ACCELERATION 1
- #define FXAA_SEARCH_THRESHOLD (1.0/4.0)
- #define FXAA_SUBPIX 1
- #define FXAA_SUBPIX_FASTER 0
- #define FXAA_SUBPIX_CAP (3.0/4.0)
- #define FXAA_SUBPIX_TRIM (1.0/4.0)
- #endif
- #if (FXAA_PRESET == 4)
- #define FXAA_EDGE_THRESHOLD (1.0/8.0)
- #define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
- #define FXAA_SEARCH_STEPS 24
- #define FXAA_SEARCH_ACCELERATION 1
- #define FXAA_SEARCH_THRESHOLD (1.0/4.0)
- #define FXAA_SUBPIX 1
- #define FXAA_SUBPIX_FASTER 0
- #define FXAA_SUBPIX_CAP (3.0/4.0)
- #define FXAA_SUBPIX_TRIM (1.0/4.0)
- #endif
- #if (FXAA_PRESET == 5)
- #define FXAA_EDGE_THRESHOLD (1.0/8.0)
- #define FXAA_EDGE_THRESHOLD_MIN (1.0/24.0)
- #define FXAA_SEARCH_STEPS 32
- #define FXAA_SEARCH_ACCELERATION 1
- #define FXAA_SEARCH_THRESHOLD (1.0/4.0)
- #define FXAA_SUBPIX 1
- #define FXAA_SUBPIX_FASTER 0
- #define FXAA_SUBPIX_CAP (3.0/4.0)
- #define FXAA_SUBPIX_TRIM (1.0/4.0)
- #endif
- #define FXAA_SUBPIX_TRIM_SCALE (1.0/(1.0 - FXAA_SUBPIX_TRIM))
- float FxaaLuma(float3 rgb) {
- return rgb.y * (0.587/0.299) + rgb.x; }
- float3 FxaaLerp3(float3 a, float3 b, float amountOfA) {
- return (FxaaToFloat3(-amountOfA) * b) +
- ((a * FxaaToFloat3(amountOfA)) + b); }
- float3 FxaaFilterReturn(float3 rgb) {
- #if FXAA_SRGB_ROP
- return FxaaSel3(
- rgb * FxaaToFloat3(1.0/12.92),
- FxaaPow3(
- rgb * FxaaToFloat3(1.0/1.055) + FxaaToFloat3(0.055/1.055),
- FxaaToFloat3(2.4)),
- rgb > FxaaToFloat3(0.04045));
- #else
- return rgb;
- #endif
- }
- float3 FxaaPixelShader(float2 pos, sampler2D tex, float2 rcpFrame) {
- float3 rgbN = FxaaTexOff(tex, pos.xy, FxaaInt2( 0,-1), rcpFrame).xyz;
- float3 rgbW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1, 0), rcpFrame).xyz;
- float3 rgbM = FxaaTexOff(tex, pos.xy, FxaaInt2( 0, 0), rcpFrame).xyz;
- float3 rgbE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1, 0), rcpFrame).xyz;
- float3 rgbS = FxaaTexOff(tex, pos.xy, FxaaInt2( 0, 1), rcpFrame).xyz;
- float lumaN = FxaaLuma(rgbN);
- float lumaW = FxaaLuma(rgbW);
- float lumaM = FxaaLuma(rgbM);
- float lumaE = FxaaLuma(rgbE);
- float lumaS = FxaaLuma(rgbS);
- float rangeMin = min(lumaM, min(min(lumaN, lumaW), min(lumaS, lumaE)));
- float rangeMax = max(lumaM, max(max(lumaN, lumaW), max(lumaS, lumaE)));
- float range = rangeMax - rangeMin;
- #if FXAA_DEBUG
- float lumaO = lumaM / (1.0 + (0.587/0.299));
- #endif
- if(range < max(FXAA_EDGE_THRESHOLD_MIN, rangeMax * FXAA_EDGE_THRESHOLD)) {
- #if FXAA_DEBUG
- return FxaaFilterReturn(FxaaToFloat3(lumaO));
- #endif
- return FxaaFilterReturn(rgbM); }
- #if FXAA_SUBPIX > 0
- #if FXAA_SUBPIX_FASTER
- float3 rgbL = (rgbN + rgbW + rgbE + rgbS + rgbM) *
- FxaaToFloat3(1.0/5.0);
- #else
- float3 rgbL = rgbN + rgbW + rgbM + rgbE + rgbS;
- #endif
- #endif
- #if FXAA_SUBPIX != 0
- float lumaL = (lumaN + lumaW + lumaE + lumaS) * 0.25;
- float rangeL = abs(lumaL - lumaM);
- #endif
- #if FXAA_SUBPIX == 1
- float blendL = max(0.0,
- (rangeL / range) - FXAA_SUBPIX_TRIM) * FXAA_SUBPIX_TRIM_SCALE;
- blendL = min(FXAA_SUBPIX_CAP, blendL);
- #endif
- #if FXAA_SUBPIX == 2
- float blendL = rangeL / range;
- #endif
- float3 rgbNW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1,-1), rcpFrame).xyz;
- float3 rgbNE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1,-1), rcpFrame).xyz;
- float3 rgbSW = FxaaTexOff(tex, pos.xy, FxaaInt2(-1, 1), rcpFrame).xyz;
- float3 rgbSE = FxaaTexOff(tex, pos.xy, FxaaInt2( 1, 1), rcpFrame).xyz;
- #if (FXAA_SUBPIX_FASTER == 0) && (FXAA_SUBPIX > 0)
- rgbL += (rgbNW + rgbNE + rgbSW + rgbSE);
- rgbL *= FxaaToFloat3(1.0/9.0);
- #endif
- float lumaNW = FxaaLuma(rgbNW);
- float lumaNE = FxaaLuma(rgbNE);
- float lumaSW = FxaaLuma(rgbSW);
- float lumaSE = FxaaLuma(rgbSE);
- float edgeVert =
- abs((0.25 * lumaNW) + (-0.5 * lumaN) + (0.25 * lumaNE)) +
- abs((0.50 * lumaW ) + (-1.0 * lumaM) + (0.50 * lumaE )) +
- abs((0.25 * lumaSW) + (-0.5 * lumaS) + (0.25 * lumaSE));
- float edgeHorz =
- abs((0.25 * lumaNW) + (-0.5 * lumaW) + (0.25 * lumaSW)) +
- abs((0.50 * lumaN ) + (-1.0 * lumaM) + (0.50 * lumaS )) +
- abs((0.25 * lumaNE) + (-0.5 * lumaE) + (0.25 * lumaSE));
- bool horzSpan = edgeHorz >= edgeVert;
- float lengthSign = horzSpan ? -rcpFrame.y : -rcpFrame.x;
- if(!horzSpan) lumaN = lumaW;
- if(!horzSpan) lumaS = lumaE;
- float gradientN = abs(lumaN - lumaM);
- float gradientS = abs(lumaS - lumaM);
- lumaN = (lumaN + lumaM) * 0.5;
- lumaS = (lumaS + lumaM) * 0.5;
- bool pairN = gradientN >= gradientS;
- if(!pairN) lumaN = lumaS;
- if(!pairN) gradientN = gradientS;
- if(!pairN) lengthSign *= -1.0;
- float2 posN;
- posN.x = pos.x + (horzSpan ? 0.0 : lengthSign * 0.5);
- posN.y = pos.y + (horzSpan ? lengthSign * 0.5 : 0.0);
- gradientN *= FXAA_SEARCH_THRESHOLD;
- float2 posP = posN;
- float2 offNP = horzSpan ?
- FxaaFloat2(rcpFrame.x, 0.0) :
- FxaaFloat2(0.0, rcpFrame.y);
- float lumaEndN = lumaN;
- float lumaEndP = lumaN;
- bool doneN = false;
- bool doneP = false;
- #if FXAA_SEARCH_ACCELERATION == 1
- posN += offNP * FxaaFloat2(-1.0, -1.0);
- posP += offNP * FxaaFloat2( 1.0, 1.0);
- #endif
- #if FXAA_SEARCH_ACCELERATION == 2
- posN += offNP * FxaaFloat2(-1.5, -1.5);
- posP += offNP * FxaaFloat2( 1.5, 1.5);
- offNP *= FxaaFloat2(2.0, 2.0);
- #endif
- #if FXAA_SEARCH_ACCELERATION == 3
- posN += offNP * FxaaFloat2(-2.0, -2.0);
- posP += offNP * FxaaFloat2( 2.0, 2.0);
- offNP *= FxaaFloat2(3.0, 3.0);
- #endif
- #if FXAA_SEARCH_ACCELERATION == 4
- posN += offNP * FxaaFloat2(-2.5, -2.5);
- posP += offNP * FxaaFloat2( 2.5, 2.5);
- offNP *= FxaaFloat2(4.0, 4.0);
- #endif
- for(int i = 0; i < FXAA_SEARCH_STEPS; i++) {
- #if FXAA_SEARCH_ACCELERATION == 1
- if(!doneN) lumaEndN =
- FxaaLuma(FxaaTexLod0(tex, posN.xy).xyz);
- if(!doneP) lumaEndP =
- FxaaLuma(FxaaTexLod0(tex, posP.xy).xyz);
- #else
- if(!doneN) lumaEndN =
- FxaaLuma(FxaaTexGrad(tex, posN.xy, offNP).xyz);
- if(!doneP) lumaEndP =
- FxaaLuma(FxaaTexGrad(tex, posP.xy, offNP).xyz);
- #endif
- doneN = doneN || (abs(lumaEndN - lumaN) >= gradientN);
- doneP = doneP || (abs(lumaEndP - lumaN) >= gradientN);
- if(doneN && doneP) break;
- if(!doneN) posN -= offNP;
- if(!doneP) posP += offNP; }
- float dstN = horzSpan ? pos.x - posN.x : pos.y - posN.y;
- float dstP = horzSpan ? posP.x - pos.x : posP.y - pos.y;
- bool directionN = dstN < dstP;
- lumaEndN = directionN ? lumaEndN : lumaEndP;
- if(((lumaM - lumaN) < 0.0) == ((lumaEndN - lumaN) < 0.0))
- lengthSign = 0.0;
- float spanLength = (dstP + dstN);
- dstN = directionN ? dstN : dstP;
- float subPixelOffset = (0.5 + (dstN * (-1.0/spanLength))) * lengthSign;
- float3 rgbF = FxaaTexLod0(tex, FxaaFloat2(
- pos.x + (horzSpan ? 0.0 : subPixelOffset),
- pos.y + (horzSpan ? subPixelOffset : 0.0))).xyz;
- #if FXAA_SUBPIX == 0
- return FxaaFilterReturn(rgbF);
- #else
- return FxaaFilterReturn(FxaaLerp3(rgbL, rgbF, blendL));
- #endif
- }
|