// ╔═════════════╦════════════════╗
// ║ Marco Gomez ║ https://mgz.me ║
// ╚═════════════╩════════════════╝
precision highp float;
uniform sampler2D prgm2Texture;
uniform vec2 resolution;
uniform float time;
void main(void) {
vec2 uv = gl_FragCoord.xy / resolution.xy;
vec4 prgm2 = texture2D(prgm2Texture, uv);
gl_FragColor = prgm2;
}
// ╔═════════════╦════════════════╗
// ║ Marco Gomez ║ https://mgz.me ║
// ╚═════════════╩════════════════╝
precision highp float;
uniform sampler2D camTexture;
uniform vec2 resolution;
void main(void) {
vec2 uv = gl_FragCoord.xy / resolution.xy;
float ar = resolution.x / resolution.y;
uv = uv * 2.0 - 1.0; uv *= 0.9; uv = uv * 0.5 + 0.5;
vec2 uvar = uv * vec2(ar, 16.0 / 9.0) * 0.5;
vec4 cam = texture2D(camTexture, uvar);
gl_FragColor = cam;
}
// ╔═════════════╦════════════════╗
// ║ Marco Gomez ║ https://mgz.me ║
// ╚═════════════╩════════════════╝
precision highp float;
uniform sampler2D prgm1Texture;
uniform vec2 resolution;
const float reinhardAmount = 0.6;
const float contrast = 1.3;
const float brightness = 1.3;
const float saturation = 0.8;
const vec2 vignetteSize = vec2(0.25, 0.25);
const float vignetteRoundness = 0.3;
const float vignetteMix = 0.5;
const float vignetteSmoothness = 0.5;
const float W = 1.2;
const float T = 7.5;
vec3 findClosest(in vec3 ref) {
vec3 old = vec3 (100.0 * 255.0);
#define try(new) old = mix (new, old, step (length (old-ref), length (new-ref)));
try(vec3(000.0, 000.0, 000.0)); // 0 - black (YPbPr = 0.0 , 0.0 , 0.0 )
try(vec3(255.0, 255.0, 255.0)); // 1 - white (YPbPr = 1.0 , 0.0 , 0.0 )
try(vec3(161.0, 077.0, 067.0)); // 2 - red (YPbPr = 0.313 , -0.383 , 0.924)
try(vec3(106.0, 193.0, 200.0)); // 3 - cyan (YPbPr = 0.625 , 0.383 , -0.924)
try(vec3(162.0, 086.0, 165.0)); // 4 - purple (YPbPr = 0.375 , 0.707 , 0.707)
try(vec3(092.0, 173.0, 095.0)); // 5 - green (YPbPr = 0.5 , -0.707 , -0.707)
try(vec3(079.0, 068.0, 156.0)); // 6 - blue (YPbPr = 0.25 , 1.0 , 0.0 )
try(vec3(203.0, 214.0, 137.0)); // 7 - yellow (YPbPr = 0.75 , -1.0 , 0.0 )
try(vec3(163.0, 104.0, 058.0)); // 8 - orange (YPbPr = 0.375 , -0.707 , 0.707)
try(vec3(110.0, 083.0, 011.0)); // 9 - brown (YPbPr = 0.25 , -0.924 , 0.383)
try(vec3(204.0, 127.0, 118.0)); // 10 - light red (YPbPr = 0.5 , -0.383 , 0.924)
try(vec3(099.0, 099.0, 099.0)); // 11 - dark grey (YPbPr = 0.313 , 0.0 , 0.0 )
try(vec3(139.0, 139.0, 139.0)); // 12 - grey (YPbPr = 0.469 , 0.0 , 0.0 )
try(vec3(155.0, 227.0, 157.0)); // 13 - light green (YPbPr = 0.75 , -0.707 , -0.707)
try(vec3(138.0, 127.0, 205.0)); // 14 - light blue (YPbPr = 0.469 , 1.0 , 0.0 )
try(vec3(175.0, 175.0, 175.0)); // 15 - light grey (YPbPr = 0.625 , 0.0 , 0.0 )
return old;
}
const mat4 bayertl = mat4(
00.0 / 64.0, 32.0 / 64.0, 08.0 / 64.0, 40.0 / 64.0,
48.0 / 64.0, 16.0 / 64.0, 56.0 / 64.0, 24.0 / 64.0,
12.0 / 64.0, 44.0 / 64.0, 04.0 / 64.0, 36.0 / 64.0,
60.0 / 64.0, 28.0 / 64.0, 52.0 / 64.0, 20.0 / 64.0
);
const mat4 bayertr = mat4(
02.0 / 64.0, 34.0 / 64.0, 10.0 / 64.0, 42.0 / 64.0,
50.0 / 64.0, 18.0 / 64.0, 58.0 / 64.0, 26.0 / 64.0,
14.0 / 64.0, 46.0 / 64.0, 06.0 / 64.0, 38.0 / 64.0,
62.0 / 64.0, 30.0 / 64.0, 54.0 / 64.0, 22.0 / 64.0
);
const mat4 bayerbl = mat4(
03.0 / 64.0, 35.0 / 64.0, 11.0 / 64.0, 43.0 / 64.0,
51.0 / 64.0, 19.0 / 64.0, 59.0 / 64.0, 27.0 / 64.0,
15.0 / 64.0, 47.0 / 64.0, 07.0 / 64.0, 39.0 / 64.0,
63.0 / 64.0, 31.0 / 64.0, 55.0 / 64.0, 23.0 / 64.0
);
const mat4 bayerbr = mat4(
01.0 / 64.0, 33.0 / 64.0, 09.0 / 64.0, 41.0 / 64.0,
49.0 / 64.0, 17.0 / 64.0, 57.0 / 64.0, 25.0 / 64.0,
13.0 / 64.0, 45.0 / 64.0, 05.0 / 64.0, 37.0 / 64.0,
61.0 / 64.0, 29.0 / 64.0, 53.0 / 64.0, 21.0 / 64.0
);
float dither(mat4 m, ivec2 p) {
if (p.y == 0) {
if (p.x == 0) { return m[0][0]; }
else if (p.x == 1) { return m[1][0]; }
else if (p.x == 2) { return m[2][0]; }
else { return m[3][0]; }
} else if (p.y == 1) {
if (p.x == 0) { return m[0][1]; }
else if (p.x == 1) { return m[1][1]; }
else if (p.x == 2) { return m[2][1]; }
else { return m[3][1]; }
} else if (p.y == 2) {
if (p.x == 0) { return m[0][1]; }
else if (p.x == 1) { return m[1][2]; }
else if (p.x == 2) { return m[2][2]; }
else { return m[3][2]; }
} else {
if (p.x == 0) { return m[0][3]; }
else if (p.x == 1) { return m[1][3]; }
else if (p.x == 2) { return m[2][3]; }
else { return m[3][3]; }
}
}
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);
}
void main(void) {
ivec2 p = ivec2(mod(gl_FragCoord.xy, 8.0));
vec2 uv = gl_FragCoord.xy / resolution.xy;
vec2 res = vec2(320.0, 200.0);
uv = vec2(floor(uv.x * res.x + 0.5) / res.x, floor(uv.y * res.y + 0.5) / res.y);
vec4 prgm1 = texture2D(prgm1Texture, uv);
vec3 c = prgm1.xyz;
vec3 reinhard = filmicReinhard(c);
c = mix(c + vec3(0.1), reinhard, reinhardAmount);
c = ContrastSaturationBrightness(c, brightness, saturation, contrast);
float v = vignette(uv, vignetteSize, vignetteRoundness, vignetteSmoothness);
vec3 vig = c * v;
c = mix(c, vig, vignetteMix);
c = pow(abs(c), vec3(2.2));
c -= 1.0 / 255.0;
vec3 d = vec3(0.0);
if (p.x <= 3 && p.y <= 3) {
d.r = float(c.r > dither(bayertl, p));
d.g = float(c.g > dither(bayertl, p));
d.b = float(c.b > dither(bayertl, p));
} else if (p.x > 3 && p.y <= 3) {
d.r = float(c.r > dither(bayertr, p - ivec2(4, 0)));
d.g = float(c.g > dither(bayertr, p - ivec2(4, 0)));
d.b = float(c.b > dither(bayertr, p - ivec2(4, 0)));
} else if (p.x <= 3 && p.y > 3) {
d.r = float(c.r > dither(bayerbl, p - ivec2(0, 4)));
d.g = float(c.g > dither(bayerbl, p - ivec2(0, 4)));
d.b = float(c.b > dither(bayerbl, p - ivec2(0, 4)));
} else if (p.x > 3 && p.y > 3) {
d.r = float(c.r > dither(bayerbr, p - ivec2(4, 4)));
d.g = float(c.g > dither(bayerbr, p - ivec2(4, 4)));
d.b = float(c.b > dither(bayerbr, p - ivec2(4, 4)));
}
d = findClosest(clamp(d * 255.0, 0.0, 255.0)) / 255.0;
vec4 color = vec4(d, 1.0);
gl_FragColor = color;
}