#version 300 es
// ╔═════════════╦════════════════╗
// ║ Marco Gomez ║ https://mgz.me ║
// ╚═════════════╩════════════════╝
precision highp float;
uniform sampler2D prgm1Texture;
uniform vec2 resolution;
uniform vec2 mouselerp;
uniform vec2 mouse;
uniform float time;
uniform float fft;
out vec4 fragColor;
const float PI = acos(-1.0);
const float TAU = PI * 2.0;
const float hk = 1.0 / sqrt(3.0);
#define cSize 12.0, 12.0
#define cPad 3.0, 3.0
#define baseColor 0.01, 0.01, 0.01, 1.0
#define mouseColor 0.1, 0.9, 0.7, 1.0
#define mouseRadius 64.0
#define fadeOut 0.0047
const vec2 neighbours[8] = vec2[8](
vec2(-1.0, -1.0),
vec2(-1.0, +0.0),
vec2(-1.0, +1.0),
vec2(+0.0, -1.0),
vec2(+0.0, +1.0),
vec2(+1.0, -1.0),
vec2(+1.0, +0.0),
vec2(+1.0, +1.0)
);
float ssin(float t) {
return (2.0 / PI) * atan(sin(TAU * t * 0.5) / 0.1) * 2.0;
}
float osc(float s, float e, float t, float ts) {
return (e - s) / 2.0 + s + sin(t * ts) * (e - s) * 0.5;
}
vec3 hueShift(vec3 col, float a) {
const vec3 k = vec3(hk);
float ca = cos(a);
return vec3(col * ca + cross(k, col) * sin(a) + k * dot(k, col) * (1.0 - ca));
}
vec4 getBounds(vec2 pixel, vec2 cellSize, vec2 cellPad) {
vec2 reach = cellSize + cellPad;
vec2 index = floor(pixel / reach);
vec2 start = reach * index;
vec2 limit = reach * (index + vec2(1.0));
return vec4(start, limit);
}
vec2 getCenter(vec2 pixel, vec2 cellSize, vec2 cellPad) {
vec4 bounds = getBounds(pixel, cellSize, cellPad);
vec2 start = bounds.xy;
vec2 limit = bounds.zw;
return (start + limit) * 0.5;
}
float isPixelInside(vec2 pixel, vec2 cellSize, vec2 cellPad) {
vec4 bounds = getBounds(pixel, cellSize, cellPad);
vec2 limit = bounds.zw;
float outside = float(
(pixel.x > (limit.x - cellPad.x)) ||
(pixel.y > (limit.y - cellPad.y))
);
float inside = 1.0 - outside;
return inside;
}
vec2 inRadius(vec2 canvas_cell, vec2 cursor_cell, float radius) {
vec2 v = canvas_cell - cursor_cell;
float d = dot(v, v);
float rad = radius * radius;
float inside = 1.0 - step(rad, d);
return vec2(inside, d);
}
vec4 getColor(vec2 pixel, vec2 cellSize, vec2 cellPad, vec4 brushColor, float rad, vec2 mousePixel) {
vec2 center = getCenter(pixel, cellSize, cellPad);
vec2 mouseCenter = getCenter(mousePixel.xy, cellSize, cellPad);
vec2 insideAndDistance = inRadius(center, mouseCenter, rad);
float insideRadius = insideAndDistance[0];
float dist = insideAndDistance[1];
vec4 drawnColor = insideRadius * (1.0 - dist / rad / rad) * brushColor;
return drawnColor;
}
vec4 getAvg(vec2 pixel, vec2 cellSize, vec2 cellPad, vec2 res) {
vec2 curCenter = getCenter(pixel, cellSize, cellPad);
vec2 fullCellSize = cellSize + cellPad;
vec4 averageColor = vec4(0.0);
for(int i = 0; i < 8; i++) {
vec2 neighCellShift = neighbours[i] * fullCellSize;
vec2 neighCellCenter = curCenter + neighCellShift;
vec2 neighUV = neighCellCenter / res;
vec4 neighColor = texture(prgm1Texture, neighUV);
averageColor += neighColor;
}
return averageColor / 8.0;
}
vec2 getPattern(float rA, float rB, float angle) {
float x = (rA - rB) * cos(angle) + rA * cos(((rA - rB) / rB) * angle);
float y = (rA - rB) * sin(angle) - rA * sin(((rA - rB) / rB) * angle);
return vec2(x, y) * 1.2;
}
void main(void) {
vec2 uv = gl_FragCoord.xy / resolution.xy;
float t = time * 1.5;
float o = osc(-0.1, 0.2, time, 0.0625);
vec2 v2o = vec2(0.75 + o, 0.85 + o);
vec2 rawMouse = (mix(mouse.xy, mouselerp.xy, 0.6) * 0.5 + 0.5) * resolution.xy;
vec2 infPattern = vec2(cos(t), sin(t) * cos(t));
vec2 pattern = getPattern(0.4, 0.1, t);
float transition = clamp(ssin(time * 0.05), 0.0, 1.0);
vec2 pat = mix(infPattern, pattern, transition);
vec2 inf = ((pat * v2o) * 0.5 + 0.5) * resolution.xy;
vec2 mousePixel = (length(mouse) < 3.0) ? rawMouse : inf;
vec4 prevFrame = texture(prgm1Texture, uv) * (1.0 - fadeOut);
prevFrame *= float(prevFrame.a > 1e-5);
vec4 cellColor = vec4(baseColor);
vec4 brushColor = vec4(mouseColor);
float brushRadius = mouseRadius;
vec2 cellSize = vec2(cSize);
vec2 cellPad = vec2(cPad);
float inside = isPixelInside(gl_FragCoord.xy, cellSize, cellPad);
vec4 curDrawnColor = (
getColor(
gl_FragCoord.xy, cellSize, cellPad,
vec4(hueShift(brushColor.xyz, TAU * fft + time * 3.0) * 3.0, brushColor.a),
brushRadius, mousePixel
)
);
vec4 diff = curDrawnColor - prevFrame;
diff *= float(diff.a > 0.0);
vec4 straightBrushedColor = inside * (prevFrame + diff);
vec4 averageColor = getAvg(gl_FragCoord.xy, cellSize, cellPad, resolution.xy);
fragColor = mix(straightBrushedColor, averageColor, (fadeOut * cellSize.x * 0.25));
fragColor = clamp(vec4(0.0), vec4(1.0), fragColor);
}
#version 300 es
// ╔═════════════╦════════════════╗
// ║ Marco Gomez ║ https://mgz.me ║
// ╚═════════════╩════════════════╝
precision highp float;
uniform sampler2D prgm1Texture;
uniform vec2 resolution;
uniform float time;
out vec4 fragColor;
const float PI = acos(-1.0);
const float TAU = PI * 2.0;
const vec2 hashv2 = vec2(12.9898, 78.233);
const float hashS = 43758.5453123;
#define cSize 12.0, 12.0
#define cPad 3.0, 3.0
#define baseColor 0.01, 0.02, 0.02, 1.0
#define try(new) old = mix (new, old, step (length (old-ref), length (new-ref)));
vec3 findClosest(vec3 ref) {
vec3 old = vec3 (100.0 * 255.0);
try(vec3( 0.0, 0.0, 0.0)); // 0 - black (YPbPr = 0.0 , 0.0 , 0.0 )
try(vec3(133.0, 59.0, 81.0)); // 1 - magenta (YPbPr = 0.25 , 0.0 , 0.5 )
try(vec3( 80.0, 71.0, 137.0)); // 2 - dark blue (YPbPr = 0.25 , 0.5 , 0.0 )
try(vec3(233.0, 93.0, 240.0)); // 3 - purple (YPbPr = 0.5 , 1.0 , 1.0 )
try(vec3( 0.0, 104.0, 82.0)); // 4 - dark green (YPbPr = 0.25 , 0.0 , -0.5 )
try(vec3(146.0, 146.0, 146.0)); // 5 - gray #1 (YPbPr = 0.5 , 0.0 , 0.0 )
try(vec3( 0.0, 168.0, 241.0)); // 6 - medium blue (YPbPr = 0.5 , 1.0 , -1.0 )
try(vec3(202.0, 195.0, 248.0)); // 7 - light blue (YPbPr = 0.75 , 0.5 , 0.0 )
try(vec3( 81.0, 92.0, 15.0)); // 8 - brown (YPbPr = 0.25 , -0.5 , 0.0 )
try(vec3(235.0, 127.0, 35.0)); // 9 - orange (YPbPr = 0.5 , -1.0 , 1.0 )
try(vec3(241.0, 166.0, 191.0)); // 11 - pink (YPbPr = 0.75 , 0.0 , 0.5 )
try(vec3( 0.0, 201.0, 41.0)); // 12 - green (YPbPr = 0.5 , -1.0 , -1.0 )
try(vec3(203.0, 211.0, 155.0)); // 13 - yellow (YPbPr = 0.75 , -0.5 , 0.0 )
try(vec3(154.0, 220.0, 203.0)); // 14 - aqua (YPbPr = 0.75 , 0.0 , -0.5 )
try(vec3(255.0, 255.0, 255.0)); // 15 - white (YPbPr = 1.0 , 0.0 , 0.0 )
try(vec3(120.0, 41.0, 34.0)); // 2 - red (YPbPr = 0.25 , -0.383 , 0.924 )
try(vec3(135.0, 214.0, 221.0)); // 3 - cyan (YPbPr = 0.75 , 0.383 , -0.924 )
try(vec3(170.0, 95.0, 182.0)); // 4 - purple (YPbPr = 0.5 , 0.707 , 0.707 )
try(vec3( 85.0, 160.0, 73.0)); // 5 - green (YPbPr = 0.5 , -0.707 , -0.707 )
try(vec3( 64.0, 49.0, 141.0)); // 6 - blue (YPbPr = 0.25 , 1.0 , 0.0 )
try(vec3(191.0, 206.0, 114.0)); // 7 - yellow (YPbPr = 0.75 , -1.0 , 0.0 )
try(vec3(170.0, 116.0, 73.0)); // 8 - orange (YPbPr = 0.5 , -0.707 , 0.707 )
try(vec3(234.0, 180.0, 137.0)); // 9 - light orange (YPbPr = 0.75 , -0.707 , 0.707 )
try(vec3(184.0, 105.0, 98.0)); // 10 - light red (YPbPr = 0.5 , -0.383 , 0.924 )
try(vec3(199.0, 255.0, 255.0)); // 11 - light cyan (YPbPr = 1.0 , 0.383 , -0.924 )
try(vec3(234.0, 159.0, 246.0)); // 12 - light purple (YPbPr = 0.75 , 0.707 , 0.707 )
try(vec3(148.0, 224.0, 137.0)); // 13 - light green (YPbPr = 0.75 , -0.707 , -0.707 )
try(vec3(128.0, 113.0, 204.0)); // 14 - light blue (YPbPr = 0.5 , 1.0 , 0.0 )
try(vec3(255.0, 255.0, 178.0)); // 15 - light yellow (YPbPr = 1.0 , -1.0 , 0.0 )
try(vec3(161.0, 77.0, 67.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, 86.0, 165.0)); // 4 - purple (YPbPr = 0.375 , 0.707 , 0.707 )
try(vec3( 92.0, 173.0, 95.0)); // 5 - green (YPbPr = 0.5 , -0.707 , -0.707 )
try(vec3( 79.0, 68.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, 58.0)); // 8 - orange (YPbPr = 0.375 , -0.707 , 0.707 )
try(vec3(110.0, 83.0, 11.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( 99.0, 99.0, 99.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 )
try(vec3( 62.0, 184.0, 73.0)); // 2 - medium green (YPbPr = 0.53 , -0.509 , -0.755 )
try(vec3(116.0, 208.0, 125.0)); // 3 - light green (YPbPr = 0.67 , -0.377 , -0.566 )
try(vec3( 89.0, 85.0, 224.0)); // 4 - dark blue (YPbPr = 0.40 , 1.0 , -0.132 )
try(vec3(128.0, 128.0, 241.0)); // 5 - light blue (YPbPr = 0.53 , 0.868 , -0.075 )
try(vec3(185.0, 94.0, 81.0)); // 6 - dark red (YPbPr = 0.47 , -0.321 , 0.679 )
try(vec3(101.0, 219.0, 239.0)); // 7 - cyan (YPbPr = 0.73 , 0.434 , -0.887 )
try(vec3(219.0, 101.0, 89.0)); // 8 - medium red (YPbPr = 0.53 , -0.377 , 0.868 )
try(vec3(255.0, 137.0, 125.0)); // 9 - light red (YPbPr = 0.67 , -0.377 , 0.868 )
try(vec3(204.0, 195.0, 94.0)); // 10 - dark yellow (YPbPr = 0.73 , -0.755 , 0.189 )
try(vec3(222.0, 208.0, 135.0)); // 11 - light yellow (YPbPr = 0.80 , -0.566 , 0.189 )
try(vec3( 58.0, 162.0, 65.0)); // 12 - dark green (YPbPr = 0.47 , -0.453 , -0.642 )
try(vec3(183.0, 102.0, 181.0)); // 13 - magenta (YPbPr = 0.53 , 0.377 , 0.491 )
try(vec3(204.0, 204.0, 204.0)); // 14 - grey (YPbPr = 0.80 , 0.0 , 0.0 )
try(vec3(226.0, 226.0, 226.0)); // L90
try(vec3(198.0, 198.0, 198.0)); // L80
try(vec3(171.0, 171.0, 171.0)); // L70
try(vec3(145.0, 145.0, 145.0)); // L60
try(vec3(119.0, 119.0, 119.0)); // L50
try(vec3( 94.0, 94.0, 94.0)); // L40
try(vec3( 71.0, 71.0, 71.0)); // L30
try(vec3( 48.0, 48.0, 48.0)); // L20
try(vec3( 27.0, 27.0, 27.0)); // L10
return old ;
}
float gaussian(float z, float u, float o) {
return (
(1.0 / (o * sqrt(TAU))) *
(exp(-(((z - u) * (z - u)) / (2.0 * (o * o)))))
);
}
vec3 gaussgrain(float t) {
vec2 ps = vec2(1.0) / resolution.xy;
vec2 uv = gl_FragCoord.xy * ps;
float seed = dot(uv, hashv2);
float noise = fract(sin(seed) * hashS + t);
noise = gaussian(noise, 0.0, 0.5);
return vec3(noise);
}
vec4 getBounds(vec2 pixel, vec2 cellSize, vec2 cellPad) {
vec2 reach = cellSize + cellPad;
vec2 index = floor(pixel / reach);
vec2 start = reach * index;
vec2 limit = reach * (index + vec2(1.0));
return vec4(start, limit);
}
float isPixelInside(vec2 pixel, vec2 cellSize, vec2 cellPad) {
vec4 bounds = getBounds(pixel, cellSize, cellPad);
vec2 limit = bounds.zw;
float outside = float(
(pixel.x > (limit.x - cellPad.x)) ||
(pixel.y > (limit.y - cellPad.y))
);
float inside_cell = 1.0 - outside;
return inside_cell;
}
void main(void) {
vec2 uv = gl_FragCoord.xy / resolution.xy;
float frameScale = 29.97;
float frameTime = floor(time * frameScale) / frameScale;
vec3 gA = gaussgrain(frameTime) * 0.42;
vec3 gB = gaussgrain(frameTime + 0.1) * 0.42;
vec4 cellColor = vec4(baseColor);
vec2 cellSize = vec2(cSize);
vec2 cellPad = vec2(cPad);
float inside = clamp(isPixelInside(gl_FragCoord.xy, cellSize, cellPad), 0.0, 1.0);
vec4 color = texture(prgm1Texture, uv);
color.xyz += (gA + gB) * 1e-2;
color.xyz = mix(findClosest(color.xyz * 255.0) / 255.0, color.xyz, 0.42);
fragColor = inside * (cellColor + color);
fragColor.a = 1.0;
}
#version 300 es
// ╔═════════════╦════════════════╗
// ║ Marco Gomez ║ https://mgz.me ║
// ╚═════════════╩════════════════╝
precision highp float;
uniform sampler2D prgm2Texture;
uniform vec2 resolution;
uniform float time;
out vec4 fragColor;
const float PI = acos(-1.0);
const float TAU = PI * 2.0;
const vec2 hashv2 = vec2(12.9898, 78.233);
const float hashS = 43758.5453123;
float hash(vec2 p) {
return fract(sin(dot(p, vec2(41.0, 289.0))) * hashS);
}
float gaussian(float z, float u, float o) {
return (
(1.0 / (o * sqrt(TAU))) *
(exp(-(((z - u) * (z - u)) / (2.0 * (o * o)))))
);
}
vec3 gaussgrain(float t) {
vec2 ps = vec2(1.0) / resolution.xy;
vec2 uv = gl_FragCoord.xy * ps;
float seed = dot(uv, hashv2);
float noise = fract(sin(seed) * hashS + t);
noise = gaussian(noise, 0.0, 0.5);
return vec3(noise);
}
void main(void) {
vec2 uv = gl_FragCoord.xy / resolution.xy;
vec4 prgm2 = texture(prgm2Texture, uv);
float frameScale = 29.97;
float frameTime = floor(time * frameScale) / frameScale;
vec4 col = prgm2;
float w = 0.1;
vec2 a = vec2(uv.x - 0.5, uv.y - 0.66);
vec2 b = a * 0.15 / float(10.0);
uv += b * (hash(uv.xy + fract(time)) * 2.0);
for (float i = 1.0; i > 0.995; i-= 0.0001) {
uv -= 0.5; uv *= i; uv += 0.5;
col += texture(prgm2Texture, uv) * w * 1.7;
w *= 0.95;
}
vec3 gA = gaussgrain(frameTime) * 0.42;
vec3 gB = gaussgrain(frameTime + 0.1) * 0.42;
col *= 0.9; col.xyz += gA * gB * 0.0625;
fragColor = mix(prgm2, col, 0.3);
}