// ╔═════════════╦════════════════╗
// ║ Marco Gomez ║ https://mgz.me ║
// ╚═════════════╩════════════════╝
precision highp float;
uniform sampler2D prgm1Texture;
uniform vec2 resolution;
const float zoom = 1.0;
const float amount = 1.0;
const bool bypass = false;
const float chx = 12.0;
const float chy = 18.0;
const float reinhardAmount = 0.99;
const float contrast = 0.8;
const float brightness = 30.0;
const float saturation = 1.0;
const vec2 vignetteSize = vec2(0.25, 0.25);
const float vignetteRoundness = 0.12;
const float vignetteMix = 1.0;
const float vignetteSmoothness = 0.42;
const float W = 1.2;
const float T = 7.5;
float filmicReinhardCurve(float x) {
float q = (T * T + 1.0) * x * x;
return q / (q + x + T * T);
}
vec3 filmicReinhard(vec3 c) {
float w = filmicReinhardCurve(W);
return vec3(
filmicReinhardCurve(c.r),
filmicReinhardCurve(c.g),
filmicReinhardCurve(c.b)
) / w;
}
vec3 ContrastSaturationBrightness(vec3 color, float brt, float sat, float con) {
const float AvgLumR = 0.5;
const float AvgLumG = 0.5;
const float AvgLumB = 0.5;
const vec3 LumCoeff = vec3(0.2125, 0.7154, 0.0721);
vec3 AvgLumin = vec3(AvgLumR, AvgLumG, AvgLumB);
vec3 brtColor = color * brt;
vec3 intensity = vec3(dot(brtColor, LumCoeff));
vec3 satColor = mix(intensity, brtColor, sat);
vec3 conColor = mix(AvgLumin, satColor, con);
return conColor;
}
float sdSquare(vec2 point, float width) {
vec2 d = abs(point) - width;
return min(max(d.x, d.y), 0.0) + length(max(d, 0.0));
}
float vignette(vec2 uv, vec2 size, float roundness, float smoothness) {
uv -= 0.5;
float minWidth = min(size.x, size.y);
uv.x = sign(uv.x) * clamp(abs(uv.x) - abs(minWidth - size.x), 0.0, 1.0);
uv.y = sign(uv.y) * clamp(abs(uv.y) - abs(minWidth - size.y), 0.0, 1.0);
float boxSize = minWidth * (1.0 - roundness);
float dist = sdSquare(uv, boxSize) - (minWidth * roundness);
return 1.0 - smoothstep(0.0, smoothness, dist);
}
float gray(vec3 c) {
return c.x * 0.299 + c.y * 0.587 + c.z * 0.114;
}
void P(
in int id,
in int a, in int b, in int c, in int d,
in int e, in int f, in int g, in int h,
inout ivec2 p, inout float cha
) {
if (id == int(p.y)) {
int pa = (a + 2 * (b + 2 * (c + 2 * (d + 2 * (e + 2 * (f + 2 * (g + 2 * h)))))));
cha = floor(mod(float(pa) / pow(abs(2.0), float(p.x) -1.0), 2.0));
}
}
void main(void) {
float z = zoom;
vec2 uv = vec2(
floor(gl_FragCoord.x / chx / z) * chx * z,
floor(gl_FragCoord.y / chy / z) * chy * z
) / resolution.xy;
ivec2 p = ivec2(mod(gl_FragCoord.x / z, chx), mod(gl_FragCoord.y / z, chy));
vec4 prgm1 = texture2D(prgm1Texture, uv);
vec4 prgm1Orig = prgm1;
vec3 reinhard = filmicReinhard(prgm1.xyz);
vec3 color = prgm1.rgb;
color = mix(prgm1.xyz + vec3(0.1), reinhard, reinhardAmount);
color = ContrastSaturationBrightness(color, brightness, saturation, contrast);
float v = vignette(uv, vignetteSize, vignetteRoundness, vignetteSmoothness);
vec3 vig = color * v;
color = mix(color, vig, vignetteMix);
color = mix(prgm1.xyz, color, amount);
prgm1.xyz = color * color;
float cha = 0.0;
float g = gray(prgm1.xyz);
if ( g < 0.125 ) {
P(11,0,0,0,0,0,0,0,0, p, cha);
P(10,0,0,0,0,0,0,0,0, p, cha);
P( 9,0,0,0,0,0,0,0,0, p, cha);
P( 8,0,0,0,0,0,0,0,0, p, cha);
P( 7,0,0,0,0,0,0,0,0, p, cha);
P( 6,0,0,0,0,0,0,0,0, p, cha);
P( 5,0,0,0,0,0,0,0,0, p, cha);
P( 4,0,0,0,0,0,0,0,0, p, cha);
P( 3,0,0,0,0,0,0,0,0, p, cha);
P( 2,0,0,0,0,0,0,0,0, p, cha);
P( 1,0,0,0,0,0,0,0,0, p, cha);
P( 0,0,0,0,0,0,0,0,0, p, cha);
} else if (g < 0.25) {
P(11,0,0,0,0,0,0,0,0, p, cha);
P(10,0,0,0,0,0,0,0,0, p, cha);
P( 9,0,0,0,0,0,0,0,0, p, cha);
P( 8,0,0,0,0,0,0,0,0, p, cha);
P( 7,0,0,0,0,0,0,0,0, p, cha);
P( 6,0,0,0,0,0,0,0,0, p, cha);
P( 5,0,0,0,0,0,0,0,0, p, cha);
P( 4,0,0,0,1,1,0,0,0, p, cha);
P( 3,0,0,0,1,1,0,0,0, p, cha);
P( 2,0,0,0,0,0,0,0,0, p, cha);
P( 1,0,0,0,0,0,0,0,0, p, cha);
P( 0,0,0,0,0,0,0,0,0, p, cha);
} else if (g < 0.375) {
P(11,0,0,0,0,0,0,0,0, p, cha);
P(10,0,0,0,0,0,0,0,0, p, cha);
P( 9,0,0,0,0,0,0,0,0, p, cha);
P( 8,0,0,0,0,0,0,0,0, p, cha);
P( 7,0,0,0,0,0,0,0,0, p, cha);
P( 6,0,0,0,0,0,0,0,0, p, cha);
P( 5,0,0,0,0,0,0,0,0, p, cha);
P( 4,0,0,0,1,1,0,0,0, p, cha);
P( 3,0,0,0,1,1,0,0,0, p, cha);
P( 2,0,0,0,0,1,0,0,0, p, cha);
P( 1,0,0,0,1,0,0,0,0, p, cha);
P( 0,0,0,0,0,0,0,0,0, p, cha);
} else if (g < 0.5) {
P(11,0,0,0,0,0,0,0,0, p, cha);
P(10,0,0,0,0,0,0,0,0, p, cha);
P( 9,0,0,0,0,0,0,0,0, p, cha);
P( 8,0,0,0,0,0,0,0,0, p, cha);
P( 7,0,0,0,0,0,0,0,0, p, cha);
P( 6,1,1,1,1,1,1,1,0, p, cha);
P( 5,0,0,0,0,0,0,0,0, p, cha);
P( 4,0,0,0,0,0,0,0,0, p, cha);
P( 3,0,0,0,0,0,0,0,0, p, cha);
P( 2,0,0,0,0,0,0,0,0, p, cha);
P( 1,0,0,0,0,0,0,0,0, p, cha);
P( 0,0,0,0,0,0,0,0,0, p, cha);
} else if (g < 0.625) {
P(11,0,0,0,0,0,0,0,0, p, cha);
P(10,0,0,0,0,0,0,0,0, p, cha);
P( 9,0,0,0,1,0,0,0,0, p, cha);
P( 8,0,0,0,1,0,0,0,0, p, cha);
P( 7,0,0,0,1,0,0,0,0, p, cha);
P( 6,1,1,1,1,1,1,1,0, p, cha);
P( 5,0,0,0,1,0,0,0,0, p, cha);
P( 4,0,0,0,1,0,0,0,0, p, cha);
P( 3,0,0,0,1,0,0,0,0, p, cha);
P( 2,0,0,0,0,0,0,0,0, p, cha);
P( 1,0,0,0,0,0,0,0,0, p, cha);
P( 0,0,0,0,0,0,0,0,0, p, cha);
} else if (g < 0.75) {
P(11,0,0,0,0,0,0,0,0, p, cha);
P(10,0,0,0,1,0,0,0,0, p, cha);
P( 9,1,0,0,1,0,0,1,0, p, cha);
P( 8,0,1,0,1,0,1,0,0, p, cha);
P( 7,0,0,1,1,1,0,0,0, p, cha);
P( 6,0,0,0,1,0,0,0,0, p, cha);
P( 5,0,0,1,1,1,0,0,0, p, cha);
P( 4,0,1,0,1,0,1,0,0, p, cha);
P( 3,1,0,0,1,0,0,1,0, p, cha);
P( 2,0,0,0,1,0,0,0,0, p, cha);
P( 1,0,0,0,0,0,0,0,0, p, cha);
P( 0,0,0,0,0,0,0,0,0, p, cha);
} else if (g < 0.875) {
P(11,0,0,0,0,0,0,0,0, p, cha);
P(10,0,0,1,0,0,1,0,0, p, cha);
P( 9,0,0,1,0,0,1,0,0, p, cha);
P( 8,1,1,1,1,1,1,1,0, p, cha);
P( 7,0,0,1,0,0,1,0,0, p, cha);
P( 6,0,0,1,0,0,1,0,0, p, cha);
P( 5,0,1,0,0,1,0,0,0, p, cha);
P( 4,0,1,0,0,1,0,0,0, p, cha);
P( 3,1,1,1,1,1,1,1,0, p, cha);
P( 2,0,1,0,0,1,0,0,0, p, cha);
P( 1,0,1,0,0,1,0,0,0, p, cha);
P( 0,0,0,0,0,0,0,0,0, p, cha);
} else {
P(11,0,0,0,0,0,0,0,0, p, cha);
P(10,0,0,1,1,1,1,0,0, p, cha);
P( 9,0,1,0,0,0,0,1,0, p, cha);
P( 8,1,0,0,0,1,1,1,0, p, cha);
P( 7,1,0,0,1,0,0,1,0, p, cha);
P( 6,1,0,0,1,0,0,1,0, p, cha);
P( 5,1,0,0,1,0,0,1,0, p, cha);
P( 4,1,0,0,1,0,0,1,0, p, cha);
P( 3,1,0,0,1,1,1,1,0, p, cha);
P( 2,0,1,0,0,0,0,0,0, p, cha);
P( 1,0,0,1,1,1,1,1,0, p, cha);
P( 0,0,0,0,0,0,0,0,0, p, cha);
}
vec3 col = prgm1.xyz / max(prgm1.x, max(prgm1.y, prgm1.z));
vec4 charColor = mix(vec4(cha * col, 1.0), vec4(cha), 0.5);
gl_FragColor = vec4(mix(prgm1, charColor, amount).xyz, 1.0);
}