First explorations of an animated grid subdivision.
Log in to post a comment.
precision highp float;
// Forked from "Metaballs" by reinder
// https://oneshader.net/shader/ab59fb7967
uniform float iTime;
uniform vec2 iResolution;
uniform float iColorVariation; // value=0.3, min=0, max=3.14, step=0.01
uniform float iColorOffset; // value=4.5, min=0, max=7, step=0.01
uniform float iColorDepthVariation; // value=0.4, min=0, max=1, step=0.01
uniform float iSpeed; // value=2, min=0.5, max=2.5, step=0.01
uniform float iPow; // value=0.4, min=0.25, max=.8, step=0.01
uniform float iMin; // value=2, min=1, max=6, step=1
uniform float iMax; // value=6, min=5, max=7, step=1
const vec2 grad = vec2(.1, 0.);
#define MAX_DEPTH 8
#define AA 3
//
// Hash functions by Dave Hoskins:
//
// https://www.shadertoy.com/view/4djSRW
//
float hash12(vec2 p) {
vec3 p3 = fract(vec3(p.xyx) * .1031);
p3 += dot(p3, p3.yzx + 33.33);
return fract((p3.x + p3.y) * p3.z);
}
float hash13(vec3 p3) {
p3 = fract(p3 * .1031);
p3 += dot(p3, p3.zyx + 31.32);
return fract((p3.x + p3.y) * p3.z);
}
vec2 hash22(vec2 p) {
vec3 p3 = fract(vec3(p.xyx) * vec3(.1031, .1030, .0973));
p3 += dot(p3, p3.yzx+33.33);
return fract((p3.xx+p3.yz)*p3.zy);
}
float noise(vec3 x) {
vec3 p = floor(x);
vec3 f = smoothstep(0., 1., fract(x));
return mix( mix( mix( hash13(p + vec3(0,0,0)), hash13(p + vec3(1,0,0)), f.x),
mix( hash13(p + vec3(0,1,0)), hash13(p + vec3(1,1,0)), f.x), f.y),
mix( mix( hash13(p + vec3(0,0,1)), hash13(p + vec3(1,0,1)), f.x),
mix( hash13(p + vec3(0,1,1)), hash13(p + vec3(1,1,1)), f.x), f.y), f.z);
}
//
// rotation matrices
//
mat2 rot2D(float a) {
return mat2(cos(a), sin(a), -sin(a), cos(a));
}
vec4 cell(vec2 uv, float d) {
float size = exp2(d) * .5;
vec2 cell = ceil(uv * size);
vec2 h = hash22(cell);
float n = noise(vec3(cell, iSpeed * .05 * iTime * (h.x + .1) + h.y));
vec2 p = uv * size - cell + .5;
if (h.y > .5)
p = p.yx;
p *= sign(hash22(-cell) - .5);
// circle
float dist = length(p);
// square
vec2 q = abs(p);
if (h.x > .33)
dist = max(q.x,q.y);
// // diamond
// if (h.x > .5)
// dist = q.x + q.y;
// // hourglass
// if (h.x > .5)
// dist = q.x - q.y + .5;
// triangle
// if (h.x > .67)
// dist = max(p.x - p.y + 0.5, max(-p.x, p.y));
return vec4(h.x, n, dist, size);
}
vec3 color(float d, float gradient) {
return .5 + .5 * sin(d/float(MAX_DEPTH) * 6.28318530718 * iColorDepthVariation + vec3(0,1,2) + iColorOffset + gradient);
}
void main() {
float pix = 1.1 / min(iResolution.x, iResolution.y);
vec2 p = (gl_FragCoord.xy * 2. - iResolution.xy);
vec3 tot = color(-1., dot(p * pix, grad)) * .25;
for (int m=0; m<AA; m++) {
for (int n=0; n<AA; n++) {
vec2 q = p + 2. * vec2(m,n)/float(AA) - 1.;
q *= pix;
vec3 col = vec3(0.1);
float tn = .75, tnprev = 0.;
for (int d=1; d<MAX_DEPTH; d++) {
vec4 data = cell(q, float(d));
tn += pow(data.y, iPow);
if ( (tn <= float(d) && float(d) >= iMin) || float(d) >= iMax) {
float m = smoothstep(float(d) - 0.975, float(d) - 1., tnprev);
vec4 mdata = mix(data, cell(q, float(d) - 1.), m * m);
vec3 shape = color(float(d) - m + mdata.x * iColorVariation, dot(q, grad));
// shape *= .9 + .1 * smoothstep(.5, .4, abs(fract(mdata.z / mdata.x * 50.) - .5) );
col = mix(col, shape, step(mdata.z, 0.5 - 0.0025 * mdata.w));
break;
}
tnprev = tn;
}
tot += col;
}
}
tot *= (1./(float(AA*AA)));
tot += hash12(gl_FragCoord.xy) * 0.025;
gl_FragColor = vec4(tot, 1.);
}