fork a shader
Write or paste an ISF shader (GLSL ES with a /*{ ... }*/ header). It compiles + renders in yer browser. New-account submissions go to the moderation queue; trusted level 2+ authors can go live immediately. Everything is CC0. Got a file first? preview it locally →
A model marks this as witnessed_generation (honest AI provenance). Leave blank if you hand-authored it.
/*{ "DESCRIPTION": "Restroom-sign pictogram: white standing figure on a rounded black tile, with a Motion Mode dropdown: Wave, Walk and Run (the figure turns to a side-view profile), Dance, Jumping Jacks and Stand Still. Fully jointed figure (shoulders, elbows, rounded nub ends, knees) with body bounce, sway and head follow. Moves lock to a BPM. Also color cycle, glow, outline and pulse for live use.", "CREDIT": "Craig", "ISFVSN": "2", "CATEGORIES": ["generator"], "INPUTS": [ { "NAME": "motionMode", "LABEL": "Motion Mode", "TYPE": "long", "DEFAULT": 0, "VALUES": [0, 1, 2, 3, 4, 5], "LABELS": ["Wave", "Walk (Side View)", "Run (Side View)", "Dance", "Jumping Jacks", "Stand Still"] }, { "NAME": "bpm", "LABEL": "Tempo (BPM)", "TYPE": "float", "DEFAULT": 120.0, "MIN": 60.0, "MAX": 200.0 }, { "NAME": "moveAmount", "LABEL": "Move Amount", "TYPE": "float", "DEFAULT": 1.0, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "speed", "TYPE": "float", "DEFAULT": 1.0, "MIN": 0.0, "MAX": 4.0 }, { "NAME": "groundDashes","LABEL": "Ground Dashes (Walk/Run)", "TYPE": "bool", "DEFAULT": 0 }, { "NAME": "hue", "TYPE": "float", "DEFAULT": 0.5, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "colorCycle", "LABEL": "Color Cycle", "TYPE": "float", "DEFAULT": 0.0, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "figureColor", "LABEL": "Figure Color", "TYPE": "color", "DEFAULT": [1.0, 1.0, 1.0, 1.0] }, { "NAME": "tileColor", "LABEL": "Tile Color", "TYPE": "color", "DEFAULT": [0.0, 0.0, 0.0, 1.0] }, { "NAME": "outerColor", "LABEL": "Outer Color", "TYPE": "color", "DEFAULT": [1.0, 1.0, 1.0, 1.0] }, { "NAME": "showTile", "LABEL": "Show Tile", "TYPE": "bool", "DEFAULT": 1 }, { "NAME": "zoom", "TYPE": "float", "DEFAULT": 1.0, "MIN": 0.25, "MAX": 3.0 }, { "NAME": "waveAuto", "LABEL": "Auto Wave Loop", "TYPE": "bool", "DEFAULT": 1 }, { "NAME": "waveStyle", "LABEL": "Wave Style", "TYPE": "long", "DEFAULT": 0, "VALUES": [0, 1, 2], "LABELS": ["Elbow Wave", "Wrist Flick", "Big Wave"] }, { "NAME": "waveRaise", "LABEL": "Arm Raise", "TYPE": "float", "DEFAULT": 1.0, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "waveCycle", "LABEL": "Loop Length (s)","TYPE": "float", "DEFAULT": 6.0, "MIN": 2.0, "MAX": 20.0 }, { "NAME": "waveSpeed", "LABEL": "Wave Speed", "TYPE": "float", "DEFAULT": 1.6, "MIN": 0.0, "MAX": 5.0 }, { "NAME": "waveAmount", "LABEL": "Wave Amount", "TYPE": "float", "DEFAULT": 0.6, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "bodyFollow", "LABEL": "Head Follow", "TYPE": "float", "DEFAULT": 0.5, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "waveLeft", "LABEL": "Mirror Figure", "TYPE": "bool", "DEFAULT": 0 }, { "NAME": "pulse", "TYPE": "float", "DEFAULT": 0.0, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "glow", "TYPE": "float", "DEFAULT": 0.0, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "outlineMix", "LABEL": "Outline Only", "TYPE": "float", "DEFAULT": 0.0, "MIN": 0.0, "MAX": 1.0 }, { "NAME": "lineWidth", "LABEL": "Line Width", "TYPE": "float", "DEFAULT": 0.3, "MIN": 0.0, "MAX": 1.0 } ] }*/ // All geometry is measured off the 1000x1000 reference, in a y-up pixel frame // (Y = 1000 - imageY), so the numbers map straight back to the photo. // Every motion mode returns to the exact reference silhouette at rest. // "Mirror Figure" flips the sample point about the figure's centre line (x = 491), // which also moves the wave to the other arm, or turns the side-view walker to face left. #define PI 3.14159265 #define HALF_PI 1.5707963 // Reference rest geometry #define PELVIS vec2(491.0, 452.0) #define HIP_L vec2(445.5, 470.0) #define HIP_R vec2(537.0, 470.0) #define FOOT_L vec2(445.5, 153.5) #define FOOT_R vec2(537.0, 153.5) #define LEG_SEG 158.25 // thigh = shin, so the rest leg is exactly straight mat2 rot(float a) { float c = cos(a), s = sin(a); return mat2(c, -s, s, c); } // iq rounded box with per-corner radii: r = (topRight, bottomRight, topLeft, bottomLeft) float sdRoundBox(vec2 p, vec2 b, vec4 r) { r.xy = (p.x > 0.0) ? r.xy : r.zw; r.x = (p.y > 0.0) ? r.x : r.y; vec2 q = abs(p) - b + r.x; return min(max(q.x, q.y), 0.0) + length(max(q, 0.0)) - r.x; } // Box defined by min/max corners float boxMM(vec2 p, vec2 mn, vec2 mx, vec4 r) { vec2 c = 0.5 * (mn + mx); vec2 h = 0.5 * (mx - mn); return sdRoundBox(p - c, h, r); } float sdSeg(vec2 p, vec2 a, vec2 b) { vec2 pa = p - a, ba = b - a; float h = clamp(dot(pa, ba) / dot(ba, ba), 0.0, 1.0); return length(pa - ba * h); } float dot2(vec2 v) { return dot(v, v); } // iq exact distance to a quadratic Bezier (A -> C, control B) float sdBezier(vec2 pos, vec2 A, vec2 B, vec2 C) { vec2 a = B - A; vec2 b = A - 2.0 * B + C; vec2 c = a * 2.0; vec2 d = A - pos; float kk = 1.0 / dot(b, b); float kx = kk * dot(a, b); float ky = kk * (2.0 * dot(a, a) + dot(d, b)) / 3.0; float kz = kk * dot(d, a); float res; float pp = ky - kx * kx; float p3 = pp * pp * pp; float qq = kx * (2.0 * kx * kx - 3.0 * ky) + kz; float h = qq * qq + 4.0 * p3; if (h >= 0.0) { h = sqrt(h); vec2 x = (vec2(h, -h) - qq) / 2.0; vec2 uv = sign(x) * pow(abs(x), vec2(1.0 / 3.0)); float t = clamp(uv.x + uv.y - kx, 0.0, 1.0); res = dot2(d + (c + b * t) * t); } else { float z = sqrt(-pp); float v = acos(qq / (pp * z * 2.0)) / 3.0; float m = cos(v); float n = sin(v) * 1.732050808; vec3 t = clamp(vec3(m + m, -n - m, n - m) * z - kx, 0.0, 1.0); res = min(dot2(d + (c + b * t.x) * t.x), dot2(d + (c + b * t.y) * t.y)); } return sqrt(res); } float smin(float a, float b, float k) { k = max(k, 0.001); float h = clamp(0.5 + 0.5 * (b - a) / k, 0.0, 1.0); return mix(b, a, h) - k * h * (1.0 - h); } // Arm angle convention, per side: 0 = pointing outward from the body, // -PI/2 = hanging down, +PI/2 = straight up. sx = +1 screen right, -1 screen left. vec2 aDir(float a, float sx) { return vec2(sx * cos(a), sin(a)); } // How far an arm is lifted (drives the shoulder tuck and joint slide) float liftOf(float upper) { return clamp((upper + HALF_PI) / (HALF_PI + 0.16), 0.0, 1.0); } // Ease with a small late overshoot, so the waving arm "arrives" instead of stopping dead float liftCurve(float x) { x = clamp(x, 0.0, 1.0); return smoothstep(0.0, 0.8, x) + 0.07 * sin(PI * clamp((x - 0.6) / 0.4, 0.0, 1.0)); } // --------------------------------------------------------------------------- // Pose: everything the figure needs for one frame // --------------------------------------------------------------------------- struct Pose { vec2 body; // upper-body offset (bounce / sway) float tilt; // upper-body roll around the pelvis (+ = counter-clockwise) float headTilt; // extra head roll around the neck vec3 armL; // left arm angles: (upper, forearm, nub) vec2 lenL; // left arm lengths: (forearm, nub) vec3 armR; // right arm angles vec2 lenR; // right arm lengths vec2 footL; // foot targets (world space) vec2 footR; float splay; // how far knees bow outward when the legs bend (0..1) }; void restPose(inout Pose P) { P.body = vec2(0.0); P.tilt = 0.0; P.headTilt = 0.0; P.armL = vec3(-HALF_PI); P.armR = vec3(-HALF_PI); P.lenL = vec2(103.0, 0.0); P.lenR = vec2(103.0, 0.0); P.footL = FOOT_L; P.footR = FOOT_R; P.splay = 0.45; } // Even-width arm tube: straight upper arm, then forearm + rounded nub as one // smooth Bezier curve (so a trailing nub bends the forearm instead of kinking). // With nub length 0 it is a plain straight capsule, identical to the reference arm. float armTube(vec2 p, vec2 S, float sx, float r, vec3 ang, vec2 len) { vec2 E = S + 115.0 * aDir(ang.x, sx); vec2 W = E + len.x * aDir(ang.y, sx); vec2 T = W + len.y * aDir(ang.z, sx); float dU = sdSeg(p, S, E) - r; float dF = sdBezier(p, E, W, T) - r; return smin(dU, dF, 4.0 * clamp(len.y / 30.0, 0.0, 1.0) + 0.001); } // Two-bone leg with simple IK: hip H reaches for foot target F. // If F is out of reach the leg straightens toward it. side = -1 left, +1 right. float legTube(vec2 p, vec2 H, vec2 F, float r, float side, float splay) { vec2 d = F - H; float len = max(length(d), 0.001); vec2 dir = d / len; float reach = min(len, 2.0 * LEG_SEG); vec2 Fp = H + dir * reach; float h = sqrt(max(LEG_SEG * LEG_SEG - 0.25 * reach * reach, 0.0)); vec2 perp = vec2(-dir.y, dir.x); // pointing +x for a leg hanging down vec2 K = H + dir * (0.5 * reach) + perp * h * splay * side; return min(sdSeg(p, H, K), sdSeg(p, K, Fp)) - r; } float figure(vec2 p, Pose P) { // Upper-body space: undo the bounce/sway and roll around the pelvis vec2 pu = rot(P.tilt) * (p - PELVIS - P.body) + PELVIS; // Head, rolled around the neck vec2 N = vec2(491.0, 772.0); vec2 hp = rot(P.headTilt) * (pu - N) + N; float head = length(hp - vec2(491.0, 854.0)) - 67.0; // Shoulder yoke with rounded top corners. On a lifted side the shoulder cap // tucks in and tightens, so the raised arm becomes the shoulder line. float liftL = liftOf(P.armL.x); float liftR = liftOf(P.armR.x); float xL = mix(333.0, 407.0, liftL), rL = mix(80.0, 34.0, liftL); float xR = mix(648.0, 576.0, liftR), rR = mix(80.0, 34.0, liftR); float yoke = boxMM(pu, vec2(xL, 600.0), vec2(xR, 772.0), vec4(rR, 0.0, rL, 0.0)); // Below the armpit line outside the torso the arms own the space; // the cut rises on a lifted side to make room for a clean armpit. float cutL = boxMM(pu, vec2(-1000.0, -1000.0), vec2(407.0, 668.0 + 40.0 * liftL), vec4(0.0)); float cutR = boxMM(pu, vec2(576.0, -1000.0), vec2(2000.0, 668.0 + 40.0 * liftR), vec4(0.0)); yoke = max(yoke, -min(cutL, cutR)); // Torso block down to the crotch float torso = boxMM(pu, vec2(407.0, 452.0), vec2(576.0, 700.0), vec4(0.0)); float body = min(yoke, torso); // Arms. Shoulder joints slide up and in as each arm lifts, so a raised arm // comes out of the top of the shoulder instead of the armpit. vec2 SL = mix(vec2(363.0, 700.0), vec2(404.0, 744.0), smoothstep(0.0, 0.6, liftL)); vec2 SR = mix(vec2(619.0, 700.0), vec2(578.0, 744.0), smoothstep(0.0, 0.6, liftR)); float armL = armTube(pu, SL, -1.0, 30.0, P.armL, P.lenL); float armR = armTube(pu, SR, 1.0, 29.0, P.armR, P.lenR); // Blend lifted arms into the shoulder/armpit; razor sharp at rest float d = smin(body, armR, 0.5 + 24.0 * liftR); d = smin(d, armL, 0.5 + 24.0 * liftL); d = min(d, head); // Legs: hips ride with the upper body, feet go where the pose puts them mat2 back = rot(-P.tilt); vec2 HL = back * (HIP_L - PELVIS) + PELVIS + P.body; vec2 HR = back * (HIP_R - PELVIS) + PELVIS + P.body; float legL = legTube(p, HL, P.footL, 38.5, -1.0, P.splay); float legR = legTube(p, HR, P.footR, 39.0, 1.0, P.splay); d = min(d, min(legL, legR)); return d; } // --------------------------------------------------------------------------- // Motion modes // --------------------------------------------------------------------------- // Wave: elbow-led lift, forearm wave with trailing nub, auto loop or manual void poseWave(inout Pose P, float t) { float ph = fract(t / waveCycle); float autoRaise = smoothstep(0.06, 0.24, ph) * (1.0 - smoothstep(0.80, 0.96, ph)); float raise = waveAuto ? autoRaise * waveRaise : waveRaise; float lift = liftCurve(raise); float fold = smoothstep(0.35, 1.0, raise); float env = smoothstep(0.78, 1.0, raise); // Style presets: pose = (upper angle, elbow bend), amp = (forearm, nub flick, shoulder) float style = float(waveStyle); vec2 pose = vec2(0.16, 1.22); vec3 amp = vec3(0.75, 0.30, 0.00); if (style > 0.5 && style < 1.5) { pose = vec2(0.22, 1.12); amp = vec3(0.08, 0.60, 0.00); } else if (style > 1.5) { pose = vec2(0.08, 0.86); amp = vec3(0.10, 0.30, 0.27); } float w = t * waveSpeed * 2.0 * PI; float A = waveAmount * env; float osc = sin(w); float lag = sin(w - 1.1); float upper = mix(-HALF_PI, pose.x, lift) + A * (amp.z - 0.25 * amp.x) * osc; float foreHang = min(upper, -HALF_PI + 0.3); float foreUp = upper + pose.y + A * amp.x * osc; float fore = mix(foreHang, foreUp, fold); float nub = fore - 0.12 * fold + A * amp.y * lag; P.armR = vec3(upper, fore, nub); P.lenR = vec2(mix(103.0, 84.0, fold), 30.0 * fold); P.headTilt = bodyFollow * (0.09 * clamp(lift, 0.0, 1.0) + 0.035 * A * sin(w - 1.8)); } // --------------------------------------------------------------------------- // Side view (Walk / Run): the figure turns to profile, facing screen right. // Angles here are measured from straight down, + = forward (toward +x). // --------------------------------------------------------------------------- struct Side { float lean; // torso lean from the hip (+ = forward) float hipY; // hip joint height (feet are planted from this) float headTilt; // head nod vec3 armN; // near arm: (upper, forearm, nub) angles, relative to the torso vec3 armF; // far arm float nubLen; // trailing nub length (0 = plain round end like the reference) float farBack; // how far back the far shoulder sits vec2 legN; // near leg: (thigh angle, knee bend; + bends the shin back) vec2 legF; // far leg }; vec2 dDown(float a) { return vec2(sin(a), -cos(a)); } // iq uneven capsule: p relative to the bottom centre, axis +y, radii r1 (bottom) / r2 (top) float sdUnevenCapsule(vec2 p, float r1, float r2, float h) { p.x = abs(p.x); float b = (r1 - r2) / h; float a = sqrt(1.0 - b * b); float k = dot(p, vec2(-b, a)); if (k < 0.0) return length(p) - r1; if (k > a * h) return length(p - vec2(0.0, h)) - r2; return dot(p, vec2(a, b)) - r1; } // Vertical reach of a leg from hip to ankle float legDrop(vec2 leg) { return LEG_SEG * (cos(leg.x) + cos(leg.x - leg.y)); } // Profile leg: thigh, shin, and a rounded shoe toe so the foot reads in profile. // The toe sits flush with the sole of the round heel so the outline stays clean. float sideLeg(vec2 p, vec2 H, vec2 leg, float r) { vec2 K = H + LEG_SEG * dDown(leg.x); float shin = leg.x - leg.y; vec2 A = K + LEG_SEG * dDown(shin); vec2 fwd = vec2(cos(shin), sin(shin)); // 90deg forward of the shin vec2 t0 = A + dDown(shin) * (r - 30.0) + fwd * 6.0; // Never let the toe dig into the ground (Y 115): near the floor the foot // pivots flat on its toe as the heel lifts. float minY = (145.0 - t0.y) / 40.0; if (fwd.y < minY) { fwd.y = clamp(minY, -1.0, 1.0); fwd.x = sqrt(max(1.0 - fwd.y * fwd.y, 0.0)); } float d = min(sdSeg(p, H, K), sdSeg(p, K, A)) - r; return smin(d, sdSeg(p, t0, t0 + fwd * 40.0) - 30.0, 16.0); } // Profile arm: same even-width tube and rounded nub as the front-view arm float sideArm(vec2 p, vec2 S, vec3 ang, float nubLen) { vec2 E = S + 115.0 * dDown(ang.x); vec2 W = E + 103.0 * dDown(ang.y); vec2 T = W + nubLen * dDown(ang.z); float dU = sdSeg(p, S, E) - 29.0; float dF = sdBezier(p, E, W, T) - 29.0; return smin(dU, dF, 4.0 * clamp(nubLen / 30.0, 0.0, 1.0) + 0.001); } float figureSide(vec2 p, Side P) { vec2 H = vec2(491.0, P.hipY); vec2 u = vec2(sin(P.lean), cos(P.lean)); // torso axis vec2 n = vec2(u.y, -u.x); // Torso: profile chest/back, a little fuller at the chest than the hips vec2 B = H + u * 30.0; vec2 tp = vec2(dot(p - B, n), dot(p - B, u)); float torso = sdUnevenCapsule(tp, 60.0, 70.0, 210.0); // Head rides the torso, nodding around the neck vec2 neck = H + u * 300.0; vec2 hc = neck + 84.0 * vec2(sin(P.lean * 0.6 + P.headTilt), cos(P.lean * 0.6 + P.headTilt)); float head = length(p - hc) - 67.0; // Limbs. Arm angles are relative to the torso, so a lean carries them forward. // The far shoulder can sit a touch back, so a far arm swung behind shows as a // clear shape instead of slivers along the torso edge. vec2 S = H + u * 236.0; vec2 SF = S - n * P.farBack + u * 6.0; float armN = sideArm(p, S, P.armN + P.lean * 0.6, P.nubLen); float armF = sideArm(p, SF, P.armF + P.lean * 0.6, P.nubLen); float legN = sideLeg(p, H, P.legN, 38.5); float legF = sideLeg(p, H, P.legF, 38.5); // Pictogram layering: far limbs sit behind, separated by a thin black gap float gap = 10.0; float back = min(armF, legF); back = max(back, -(legN - gap)); // near leg in front of far leg back = max(back, -(torso - gap)); // far arm and far hip tuck behind the torso float d = min(min(torso, head), legN); d = smin(d, back, 0.5); // Near arm on top of everything with its own gap d = max(d, -(armN - gap)); d = min(d, armN); return d; } // Walk: profile gait. Thigh swing, knee folds in early swing, a little flex on // landing; the hip height is solved so the standing foot stays on the ground. void poseWalkSide(inout Side P, float beats, float E) { float ph = PI * beats; // one step per beat, stride every 2 for (int i = 0; i < 2; i++) { float f = ph + float(i) * PI; float th = 0.08 + 0.36 * sin(f); float kn = 0.08 + 0.95 * pow(max(0.0, cos(f + 0.35)), 2.0) + 0.18 * pow(max(0.0, cos(f - 2.1)), 4.0); vec2 leg = vec2(th, kn) * E; float sw = -0.38 * sin(f); // arm swings opposite its leg vec3 arm = vec3(sw, sw + 0.22 + 0.25 * max(0.0, -sin(f)), 0.0) * E; arm.z = arm.y; if (i == 0) { P.legN = leg; P.armF = arm; } else { P.legF = leg; P.armN = arm; } } P.hipY = FOOT_L.y + max(legDrop(P.legN), legDrop(P.legF)); P.lean = 0.05 * E; P.headTilt = bodyFollow * 0.05 * E * sin(2.0 * ph + 0.6); P.nubLen = 0.0; P.farBack = 0.0; // far arm hides behind the body at mid-swing } // Run: longer stride, high heel kick, bent pumping arms, forward lean and a // short flight phase as stance switches feet. void poseRunSide(inout Side P, float beats, float E) { float ph = 2.0 * PI * beats; // one stride (two steps) per beat for (int i = 0; i < 2; i++) { float f = ph + float(i) * PI; float th = 0.10 + 0.55 * sin(f) + 0.22 * sin(2.0 * f); float kn = 0.30 + 1.75 * pow(max(0.0, cos(f + 0.45)), 1.6) + 0.35 * pow(max(0.0, cos(f - 2.9)), 2.0); vec2 leg = vec2(th, kn) * E; float sw = -0.80 * sin(f); vec3 arm = vec3(sw, sw + 1.55 + 0.20 * sin(f), 0.0); arm = mix(vec3(0.0), arm, E); arm.z = arm.y + 0.25 * E * cos(f); // nub trails the pump if (i == 0) { P.legN = leg; P.armF = arm; } else { P.legF = leg; P.armN = arm; } } float dn = legDrop(P.legN), df = legDrop(P.legF); float flight = 24.0 * E * pow(clamp(1.0 - abs(dn - df) / 70.0, 0.0, 1.0), 2.0); P.hipY = FOOT_L.y + max(dn, df) + flight; P.lean = 0.20 * E; P.headTilt = bodyFollow * (-0.08 * E + 0.05 * E * sin(2.0 * ph)); P.nubLen = 18.0 * E; P.farBack = 24.0 * E; } // Dance: side-to-side groove, dip on every beat, heel pops, alternating arm raises void poseDance(inout Pose P, float beats, float E) { float ph = PI * beats; // full groove every two beats float s = sin(ph); float dip = 0.5 + 0.5 * cos(2.0 * ph); // 1 on each beat P.body = vec2(24.0 * E * s, -14.0 * E * dip); P.tilt = -0.07 * E * s; // lean into the sway P.headTilt = bodyFollow * 0.12 * E * sin(ph + 0.8); // Slightly wider stance, unweighted heel pops up P.footL = FOOT_L + vec2(-20.0 * E, 18.0 * E * pow(max( s, 0.0), 2.0)); P.footR = FOOT_R + vec2( 20.0 * E, 18.0 * E * pow(max(-s, 0.0), 2.0)); P.splay = 0.6; float upR = smoothstep(0.1, 0.9, 0.5 + 0.5 * s); float upL = smoothstep(0.1, 0.9, 0.5 - 0.5 * s); float pump = 0.15 * (dip - 0.5); float lagR = 0.25 * cos(ph), lagL = -lagR; float uR = mix(-1.25, 0.45, upR), aR = mix(-0.35, 1.35, upR) + pump; float uL = mix(-1.25, 0.45, upL), aL = mix(-0.35, 1.35, upL) + pump; P.armR = mix(vec3(-HALF_PI), vec3(uR, aR, aR - 0.1 * upR + lagR), E); P.armL = mix(vec3(-HALF_PI), vec3(uL, aL, aL - 0.1 * upL + lagL), E); P.lenR = mix(vec2(103.0, 0.0), vec2(mix(95.0, 84.0, upR), mix(16.0, 30.0, upR)), E); P.lenL = mix(vec2(103.0, 0.0), vec2(mix(95.0, 84.0, upL), mix(16.0, 30.0, upL)), E); } // Jumping jacks: hop on each switch, land open (arms up, feet wide) then closed void poseJacks(inout Pose P, float beats, float E) { float ph = PI * beats; // open on one beat, closed on the next float j = (0.5 - 0.5 * cos(ph)) * E; // 0 closed .. 1 open float hop = 24.0 * E * abs(sin(ph)); // airborne between positions P.body = vec2(0.0, hop - 9.0 * j); // sink a touch when landing wide P.footL = FOOT_L + vec2(-75.0 * j, hop); P.footR = FOOT_R + vec2( 75.0 * j, hop); P.splay = 0.3; float u = mix(-HALF_PI, 0.85, j); float a = mix(-HALF_PI, 0.95, j); float trail = 0.15 * E * sin(ph); P.armR = vec3(u, a, a - trail); P.armL = vec3(u, a, a - trail); P.lenR = vec2(mix(103.0, 84.0, j), 30.0 * j); P.lenL = P.lenR; } // Stand still: just a slow breath void poseStand(inout Pose P, float t, float E) { P.body = vec2(0.0, 2.5 * E * sin(t * 1.3)); } void main() { float t = TIME * speed; float beats = t * bpm / 60.0; float E = moveAmount; // Aspect-correct coords, mapped into the reference's 1000-unit frame vec2 p = isf_FragNormCoord - 0.5; p.x *= RENDERSIZE.x / RENDERSIZE.y; float upp = 1000.0 / (RENDERSIZE.y * zoom); // reference units per screen pixel (for AA) vec2 q = p * 1000.0 / zoom + 500.0; // Rounded black tile float dTile = sdRoundBox(q - vec2(500.0), vec2(468.0), vec4(95.0)); float tileM = showTile ? clamp(0.5 - dTile / upp, 0.0, 1.0) : 1.0; // ---------------- Pose for the selected motion ---------------- float mode = float(motionMode); bool sideView = mode > 0.5 && mode < 2.5; // Walk and Run turn to profile Pose P; restPose(P); if (mode < 0.5) poseWave(P, t); else if (mode < 3.5) poseDance(P, beats, E); else if (mode < 4.5) poseJacks(P, beats, E); else poseStand(P, t, E); Side SP; SP.lean = 0.0; SP.hipY = HIP_L.y; SP.headTilt = 0.0; SP.nubLen = 0.0; SP.farBack = 0.0; SP.armN = vec3(0.0); SP.armF = vec3(0.0); SP.legN = vec2(0.0); SP.legF = vec2(0.0); if (mode > 0.5 && mode < 1.5) poseWalkSide(SP, beats, E); else if (mode > 1.5 && mode < 2.5) poseRunSide(SP, beats, E); // ---------------- Figure ---------------- float s = 1.0 + pulse * 0.08 * sin(t * 3.0); vec2 c = vec2(491.0, 500.0); vec2 fq = (q - c) / s + c; if (waveLeft) fq.x = 982.0 - fq.x; // mirror about the figure's centre line float dFig = (sideView ? figureSide(fq, SP) : figure(fq, P)) * s; // Optional ground dashes that scroll under the feet in Walk / Run if (sideView && groundDashes) { float scroll = beats * (mode < 1.5 ? 210.0 : 470.0); float gx = mod(fq.x + scroll, 110.0) - 55.0; float dash = boxMM(vec2(gx, fq.y), vec2(-30.0, 92.0), vec2(30.0, 102.0), vec4(5.0)); dash = max(dash, abs(fq.x - 491.0) - 380.0); dFig = min(dFig, dash * s); } // Fill vs outline float lw = mix(3.0, 40.0, lineWidth); float mFill = clamp(0.5 - dFig / upp, 0.0, 1.0); float mLine = clamp(0.5 - (abs(dFig) - lw * 0.5) / upp, 0.0, 1.0); float m = mix(mFill, mLine, outlineMix); // Color: solid figure color blended toward the reference cosine palette vec3 pal = 0.5 + 0.5 * cos(t + q.y * 0.006 + q.x * 0.002 + vec3(0.0, 2.0, 4.0) + hue * 6.2831); vec3 fig = mix(figureColor.rgb, pal, colorCycle); // Soft halo around the figure float g = glow * exp(-max(dFig, 0.0) / 60.0) * 0.8; vec3 inside = tileColor.rgb + fig * g; inside = mix(inside, fig, m); vec3 col = mix(outerColor.rgb, inside, tileM); gl_FragColor = vec4(col, 1.0); }
forking #4mdpp7el — lineage will be recorded.
renders in YOUR browser. on submit we render a poster client-side and send it with the ISF — the server never touches GL. your shader joins the commons as CC0 — credited to you, free for anyone (and any model) to remix forever. that's the whole point. it's permanent: once it's public, CC0 has no take-backs. by submitting you attest you have the right to release it as CC0.