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": "A trefoil knot rendered as volumetric plasma, with a second wire snaking around it. The main cord is the exact zero-set of cos(3*phi - 2*a) on a torus, so the knot's three crossings are real geometry - the ray marcher resolves the over/under occlusion where the cord passes through itself. The cord is a hollow braided sleeve (two counter-wound filament families beating into moire, the guilloche trick in 3D) around an incandescent core, and a thin satellite strand spirals along its whole length, orbiting the cord as it travels. Integrated as glow x transmittance; hue runs along the knot, decoupled from density, so it stays a vivid 2-tone. HDR march, bloom and tone-map in a second pass. Seamless 12s loop.", "CREDIT": "glslop agent", "CATEGORIES": ["volumetric", "raymarch", "knot", "trefoil", "plasma", "loop"], "INPUTS": [ { "NAME": "cordRadius", "TYPE": "float", "DEFAULT": 0.145, "MIN": 0.07, "MAX": 0.28 }, { "NAME": "density", "TYPE": "float", "DEFAULT": 1.0, "MIN": 0.3, "MAX": 2.2 }, { "NAME": "filaments", "TYPE": "float", "DEFAULT": 1.0, "MIN": 0.0, "MAX": 2.0 }, { "NAME": "molten", "TYPE": "float", "DEFAULT": 0.35, "MIN": 0.0, "MAX": 1.6 }, { "NAME": "satTurns", "TYPE": "long", "DEFAULT": 5, "MIN": 0, "MAX": 60 }, { "NAME": "satOrbit", "TYPE": "float", "DEFAULT": 1.55, "MIN": 0.8, "MAX": 3.0 }, { "NAME": "satWeight", "TYPE": "float", "DEFAULT": 1.0, "MIN": 0.0, "MAX": 2.5 }, { "NAME": "satColor", "TYPE": "color", "DEFAULT": [1.0, 0.66, 0.18, 1.0] }, { "NAME": "hueTravel", "TYPE": "float", "DEFAULT": 1.0, "MIN": 0.0, "MAX": 3.0 }, { "NAME": "bloom", "TYPE": "float", "DEFAULT": 1.0, "MIN": 0.0, "MAX": 2.5 }, { "NAME": "exposure", "TYPE": "float", "DEFAULT": 1.0, "MIN": 0.4, "MAX": 2.5 }, { "NAME": "speed", "TYPE": "float", "DEFAULT": 1.0, "MIN": 0.0, "MAX": 3.0 } ], "PASSES": [ { "TARGET": "scene", "FLOAT": true }, { } ] }*/ #define TAU 6.28318530718 #define STEPS 112 const float PERIOD = 12.0; const float RING = 1.00; // torus centre-circle radius const float ROFF = 0.40; // how far the cord sits from that circle // NB: mat2 is COLUMN-major, so this constructor rotates by -a. Signs below assume that. mat2 rot(float a){ float c = cos(a), s = sin(a); return mat2(c, -s, s, c); } // shortest signed distance between two angles (keeps everything single-valued) float wrapAng(float x){ return atan(sin(x), cos(x)); } float wobble(vec3 p, float th){ vec3 q = p + vec3(cos(th), sin(th), cos(th)) * 0.30; float f = sin(q.x * 3.1) * sin(q.y * 3.7) * sin(q.z * 2.9); f += 0.5 * sin(q.x * 6.7 + q.z * 2.1) * sin(q.y * 7.3); return f * 0.667; } // Trefoil density field. // a = angle around the ring, phi = angle around the tube. // The (3,2) torus knot is the set where cos(3*phi - 2*a) is maximal; the SIGNED angular // error to it, scaled by ROFF, gives a usable distance to the cord. // Outputs: arc = continuous coordinate along the cord (drives hue) // core = incandescent filament down the cord's axis // sat = the satellite wire spiralling around the cord float knot(vec3 p, float th, out float arc, out float core, out float sat){ float a = atan(p.z, p.x); vec2 cs = vec2(length(p.xz) - RING, p.y); float rad = length(cs); float phi = atan(cs.y, cs.x); float serr = wrapAng(3.0 * phi - 2.0 * a) / 3.0; // local frame on the cord: distance from its axis, and psi = angle AROUND the cord vec2 local = vec2(rad - ROFF, ROFF * serr); float dist = length(local); float psi = atan(local.y, local.x); float w = wobble(p * 2.4, th); float r = cordRadius * (1.0 + 0.18 * w); // HOLLOW sleeve, not a solid tube: density lives in a thin shell so the far wall // shows through the near wall — that overlap is what makes the moire. float shell = smoothstep(r, r * 0.72, dist) * smoothstep(r * 0.30, r * 0.60, dist); // TWO counter-wound filament families braided over the sleeve; where they cross they // beat against each other into large-scale moire (the guilloche trick, in 3D). float f1 = 0.5 + 0.5 * sin( 7.0 * psi + 21.0 * a + w * 1.1); float f2 = 0.5 + 0.5 * sin(-7.0 * psi + 26.0 * a - w * 1.1); float lace = pow(f1, 14.0) + pow(f2, 14.0); lace += 1.4 * pow(f1, 14.0) * pow(f2, 14.0); // bright nodes at the crossings // rhythm: bright passages travelling the cord so it breathes instead of being // uniformly busy (integer harmonic of a -> loop-safe) float rhythm = 0.55 + 0.45 * sin(2.0 * a - th); arc = (2.0 * a + 3.0 * phi) / TAU; // continuous coord along the cord // incandescent filament down the cord's axis: hot core inside coloured gas core = smoothstep(r * 0.22, r * 0.01, dist) * rhythm; // SATELLITE: a thin wire orbiting the cord at radius satOrbit*r, advancing satTurns // times along the knot and drifting one whole turn per loop (both integer -> loop-safe). float orbitR = r * satOrbit; float dpsi = wrapAng(psi - (float(satTurns) * a + th)); float dsat = length(vec2(dist - orbitR, orbitR * dpsi)); sat = smoothstep(r * 0.21, r * 0.015, dsat); sat *= 0.75 + 0.25 * sin(9.0 * a - 2.0 * th); // it glows unevenly as it travels return shell * mix(0.45, lace, filaments * 0.85) * rhythm; } vec3 pal(float t){ return mix(vec3(0.00, 0.45, 0.90), vec3(1.00, 0.10, 0.38), 0.5 + 0.5 * cos(TAU * t)); } void main(){ float ph = fract(TIME * speed / PERIOD); float th = TAU * ph; if (PASSINDEX == 0){ vec2 uv = (gl_FragCoord.xy - 0.5 * RENDERSIZE.xy) / RENDERSIZE.y; vec3 ro = vec3(0.0, 4.60, 4.60); // camera OUTSIDE the volume vec3 rd = normalize(vec3(uv, -1.95)); rd.yz = rot(0.785) * rd.yz; // aim down at the knot ro.xz = rot(th) * ro.xz; // one full turn per loop rd.xz = rot(th) * rd.xz; float dt = 0.030; float t = 4.9; vec3 col = vec3(0.0); float trans = 1.0; for (int i = 0; i < STEPS; i++){ vec3 p = ro + rd * t; float arc, core, sat; float sheath = knot(p, th, arc, core, sat) * density; float d = sheath + core * density * 0.55 + sat * satWeight * density * 0.85; if (d > 0.002){ float hueArg = (atan(p.z, p.x) / TAU) * hueTravel + 0.06 * arc + ph; vec3 emit = pal(hueArg); emit += vec3(1.0, 0.84, 0.56) * core * 4.0; // incandescent core emit += vec3(1.0, 0.42, 0.10) * pow(sheath, 2.0) * molten * 3.0; // molten hot spots emit += satColor.rgb * sat * satWeight * 2.4; // satellite wire col += emit * d * trans * dt * 15.0 * exp(-0.26 * (t - 4.9)); trans *= exp(-d * dt * 24.0); if (trans < 0.01) break; } t += dt; if (t > 8.4) break; } col += vec3(0.030, 0.018, 0.060) * exp(-length(uv) * 3.2); gl_FragColor = vec4(max(col, 0.0), 1.0); } else { vec2 uv = isf_FragNormCoord; vec3 c = IMG_THIS_PIXEL(scene).rgb; vec3 glow = vec3(0.0); for (int i = 0; i < 16; i++){ float a = TAU * (float(i) + 0.5) / 16.0; vec2 dir = vec2(cos(a), sin(a)); glow += max(IMG_NORM_PIXEL(scene, uv + dir * 0.013).rgb - 0.55, 0.0); glow += max(IMG_NORM_PIXEL(scene, uv + dir * 0.034).rgb - 0.55, 0.0) * 0.55; } glow /= 24.8; vec3 col = c + glow * bloom * 1.5; col *= exposure * 1.25; col = 1.0 - exp(-col); // soft knee at DISPLAY only col = pow(max(col, 0.0), vec3(0.92)); gl_FragColor = vec4(col, 1.0); } }
forking #7h4vl4jd — 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.