Pixel-Composer/shaders/sh_FXAA/sh_FXAA.fsh

78 lines
2.7 KiB
Plaintext
Raw Permalink Normal View History

2023-05-03 21:42:17 +02:00
//
// Simple passthrough fragment shader
//
varying vec2 v_vTexcoord;
varying vec4 v_vColour;
//Texel size (1/resolution)
uniform vec2 dimension;
2024-05-07 12:40:18 +02:00
uniform float cornerDis;
uniform float mixAmo;
2023-05-03 21:42:17 +02:00
#define SPAN_MAX (8.0) //Maximum texel span
//These are more technnical and probably don't need changing:
#define REDUCE_MIN (1.0 / 128.0) //Minimum "dir" reciprocal
#define REDUCE_MUL (1.0 / 32.0) //Luma multiplier for "dir" reciprocal
vec4 textureFXAA(sampler2D tex, vec2 uv) {
vec2 u_texel = 1. / dimension;
//Sample center and 4 corners
vec3 rgbCC = texture2D(tex, uv).rgb;
2024-05-07 12:40:18 +02:00
vec3 rgb00 = texture2D(tex, uv + vec2( -cornerDis, -cornerDis) * u_texel).rgb;
vec3 rgb10 = texture2D(tex, uv + vec2( +cornerDis, -cornerDis) * u_texel).rgb;
vec3 rgb01 = texture2D(tex, uv + vec2( -cornerDis, +cornerDis) * u_texel).rgb;
vec3 rgb11 = texture2D(tex, uv + vec2( +cornerDis, +cornerDis) * u_texel).rgb;
2023-05-03 21:42:17 +02:00
//Luma coefficients
const vec3 luma = vec3(0.299, 0.587, 0.114);
//Get luma from the 5 samples
float lumaCC = dot(rgbCC, luma);
float luma00 = dot(rgb00, luma);
float luma10 = dot(rgb10, luma);
float luma01 = dot(rgb01, luma);
float luma11 = dot(rgb11, luma);
//Compute gradient from luma values
vec2 dir = vec2((luma01 + luma11) - (luma00 + luma10), (luma00 + luma01) - (luma10 + luma11));
2024-05-07 12:40:18 +02:00
2023-05-03 21:42:17 +02:00
//Diminish dir length based on total luma
float dirReduce = max((luma00 + luma10 + luma01 + luma11) * REDUCE_MUL, REDUCE_MIN);
2024-05-07 12:40:18 +02:00
2023-05-03 21:42:17 +02:00
//Divide dir by the distance to nearest edge plus dirReduce
float rcpDir = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
2024-05-07 12:40:18 +02:00
2023-05-03 21:42:17 +02:00
//Multiply by reciprocal and limit to pixel span
dir = clamp(dir * rcpDir, -SPAN_MAX, SPAN_MAX) * u_texel.xy;
2024-05-07 12:40:18 +02:00
vec4 O = texture2D(tex, uv);
2023-05-03 21:42:17 +02:00
//Average middle texels along dir line
vec4 A = 0.5 * (
texture2D(tex, uv - dir * (1.0 / 6.0)) +
texture2D(tex, uv + dir * (1.0 / 6.0)));
//Average with outer texels along dir line
vec4 B = A * 0.5 + 0.25 * (
texture2D(tex, uv - dir * (0.5)) +
texture2D(tex, uv + dir * (0.5)));
//Get lowest and highest luma values
float lumaMin = min(lumaCC, min(min(luma00, luma10), min(luma01, luma11)));
float lumaMax = max(lumaCC, max(max(luma00, luma10), max(luma01, luma11)));
//Get average luma
float lumaB = dot(B.rgb, luma);
2024-05-07 12:40:18 +02:00
2023-05-03 21:42:17 +02:00
//If the average is outside the luma range, using the middle average
2024-05-07 12:40:18 +02:00
return mix(O, ((lumaB < lumaMin) || (lumaB > lumaMax)) ? A : B, mixAmo);
2023-05-03 21:42:17 +02:00
}
void main() {
2024-08-29 04:45:38 +02:00
vec4 base = texture2D( gm_BaseTexture, v_vTexcoord );
vec4 fxaa = textureFXAA( gm_BaseTexture, v_vTexcoord );
gl_FragData[0] = fxaa;
gl_FragData[1] = vec4(abs(base.rgb - fxaa.rgb), 1.);
2023-05-03 21:42:17 +02:00
}