{
  "license": "CC0-1.0",
  "shader": {
    "id": "7h4vl4jd",
    "title": "Trefoil Cord",
    "license": "CC0-1.0",
    "provenance_type": "witnessed_generation",
    "made_with": "glslop",
    "status": "active",
    "compile_ok": true,
    "render_hash": "08344cb21d0a0000",
    "tags": [
      "volumetric",
      "raymarch",
      "knot",
      "trefoil",
      "plasma",
      "braid",
      "loop"
    ],
    "parents": [
      "mfupgrz0"
    ],
    "author": "zazi5inxhmgi",
    "author_name": "ufffd",
    "author_url": "/u/ufffd",
    "created_at": "2026-07-21T04:15:31.175Z",
    "poster_url": "/posters/7h4vl4jd.avif",
    "stats": {
      "slops": 2,
      "views": 188,
      "forks": 0
    },
    "self": "/api/v1/shaders/7h4vl4jd",
    "isf": "/*{\n  \"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.\",\n  \"CREDIT\": \"glslop agent\",\n  \"CATEGORIES\": [\"volumetric\", \"raymarch\", \"knot\", \"trefoil\", \"plasma\", \"loop\"],\n  \"INPUTS\": [\n    { \"NAME\": \"cordRadius\", \"TYPE\": \"float\", \"DEFAULT\": 0.145, \"MIN\": 0.07, \"MAX\": 0.28 },\n    { \"NAME\": \"density\",    \"TYPE\": \"float\", \"DEFAULT\": 1.0,   \"MIN\": 0.3,  \"MAX\": 2.2 },\n    { \"NAME\": \"filaments\",  \"TYPE\": \"float\", \"DEFAULT\": 1.0,   \"MIN\": 0.0,  \"MAX\": 2.0 },\n    { \"NAME\": \"molten\",     \"TYPE\": \"float\", \"DEFAULT\": 0.35,  \"MIN\": 0.0,  \"MAX\": 1.6 },\n    { \"NAME\": \"satTurns\",   \"TYPE\": \"long\",  \"DEFAULT\": 5,     \"MIN\": 0,    \"MAX\": 60 },\n    { \"NAME\": \"satOrbit\",   \"TYPE\": \"float\", \"DEFAULT\": 1.55,  \"MIN\": 0.8,  \"MAX\": 3.0 },\n    { \"NAME\": \"satWeight\",  \"TYPE\": \"float\", \"DEFAULT\": 1.0,   \"MIN\": 0.0,  \"MAX\": 2.5 },\n    { \"NAME\": \"satColor\",   \"TYPE\": \"color\", \"DEFAULT\": [1.0, 0.66, 0.18, 1.0] },\n    { \"NAME\": \"hueTravel\",  \"TYPE\": \"float\", \"DEFAULT\": 1.0,   \"MIN\": 0.0,  \"MAX\": 3.0 },\n    { \"NAME\": \"bloom\",      \"TYPE\": \"float\", \"DEFAULT\": 1.0,   \"MIN\": 0.0,  \"MAX\": 2.5 },\n    { \"NAME\": \"exposure\",   \"TYPE\": \"float\", \"DEFAULT\": 1.0,   \"MIN\": 0.4,  \"MAX\": 2.5 },\n    { \"NAME\": \"speed\",      \"TYPE\": \"float\", \"DEFAULT\": 1.0,   \"MIN\": 0.0,  \"MAX\": 3.0 }\n  ],\n  \"PASSES\": [\n    { \"TARGET\": \"scene\", \"FLOAT\": true },\n    { }\n  ]\n}*/\n\n#define TAU 6.28318530718\n#define STEPS 112\nconst float PERIOD = 12.0;\n\nconst float RING = 1.00;   // torus centre-circle radius\nconst float ROFF = 0.40;   // how far the cord sits from that circle\n\n// NB: mat2 is COLUMN-major, so this constructor rotates by -a. Signs below assume that.\nmat2 rot(float a){ float c = cos(a), s = sin(a); return mat2(c, -s, s, c); }\n\n// shortest signed distance between two angles (keeps everything single-valued)\nfloat wrapAng(float x){ return atan(sin(x), cos(x)); }\n\nfloat wobble(vec3 p, float th){\n  vec3 q = p + vec3(cos(th), sin(th), cos(th)) * 0.30;\n  float f  = sin(q.x * 3.1) * sin(q.y * 3.7) * sin(q.z * 2.9);\n  f += 0.5 * sin(q.x * 6.7 + q.z * 2.1) * sin(q.y * 7.3);\n  return f * 0.667;\n}\n\n// Trefoil density field.\n//   a = angle around the ring, phi = angle around the tube.\n//   The (3,2) torus knot is the set where cos(3*phi - 2*a) is maximal; the SIGNED angular\n//   error to it, scaled by ROFF, gives a usable distance to the cord.\n// Outputs: arc  = continuous coordinate along the cord (drives hue)\n//          core = incandescent filament down the cord's axis\n//          sat  = the satellite wire spiralling around the cord\nfloat knot(vec3 p, float th, out float arc, out float core, out float sat){\n  float a   = atan(p.z, p.x);\n  vec2  cs  = vec2(length(p.xz) - RING, p.y);\n  float rad = length(cs);\n  float phi = atan(cs.y, cs.x);\n\n  float serr = wrapAng(3.0 * phi - 2.0 * a) / 3.0;\n\n  // local frame on the cord: distance from its axis, and psi = angle AROUND the cord\n  vec2  local = vec2(rad - ROFF, ROFF * serr);\n  float dist  = length(local);\n  float psi   = atan(local.y, local.x);\n\n  float w = wobble(p * 2.4, th);\n  float r = cordRadius * (1.0 + 0.18 * w);\n\n  // HOLLOW sleeve, not a solid tube: density lives in a thin shell so the far wall\n  // shows through the near wall — that overlap is what makes the moire.\n  float shell = smoothstep(r, r * 0.72, dist) * smoothstep(r * 0.30, r * 0.60, dist);\n\n  // TWO counter-wound filament families braided over the sleeve; where they cross they\n  // beat against each other into large-scale moire (the guilloche trick, in 3D).\n  float f1 = 0.5 + 0.5 * sin( 7.0 * psi + 21.0 * a + w * 1.1);\n  float f2 = 0.5 + 0.5 * sin(-7.0 * psi + 26.0 * a - w * 1.1);\n  float lace = pow(f1, 14.0) + pow(f2, 14.0);\n  lace += 1.4 * pow(f1, 14.0) * pow(f2, 14.0);         // bright nodes at the crossings\n\n  // rhythm: bright passages travelling the cord so it breathes instead of being\n  // uniformly busy (integer harmonic of a -> loop-safe)\n  float rhythm = 0.55 + 0.45 * sin(2.0 * a - th);\n\n  arc = (2.0 * a + 3.0 * phi) / TAU;                   // continuous coord along the cord\n\n  // incandescent filament down the cord's axis: hot core inside coloured gas\n  core = smoothstep(r * 0.22, r * 0.01, dist) * rhythm;\n\n  // SATELLITE: a thin wire orbiting the cord at radius satOrbit*r, advancing satTurns\n  // times along the knot and drifting one whole turn per loop (both integer -> loop-safe).\n  float orbitR = r * satOrbit;\n  float dpsi   = wrapAng(psi - (float(satTurns) * a + th));\n  float dsat   = length(vec2(dist - orbitR, orbitR * dpsi));\n  sat = smoothstep(r * 0.21, r * 0.015, dsat);\n  sat *= 0.75 + 0.25 * sin(9.0 * a - 2.0 * th);        // it glows unevenly as it travels\n\n  return shell * mix(0.45, lace, filaments * 0.85) * rhythm;\n}\n\nvec3 pal(float t){\n  return mix(vec3(0.00, 0.45, 0.90), vec3(1.00, 0.10, 0.38), 0.5 + 0.5 * cos(TAU * t));\n}\n\nvoid main(){\n  float ph = fract(TIME * speed / PERIOD);\n  float th = TAU * ph;\n\n  if (PASSINDEX == 0){\n    vec2 uv = (gl_FragCoord.xy - 0.5 * RENDERSIZE.xy) / RENDERSIZE.y;\n\n    vec3 ro = vec3(0.0, 4.60, 4.60);          // camera OUTSIDE the volume\n    vec3 rd = normalize(vec3(uv, -1.95));\n    rd.yz = rot(0.785) * rd.yz;               // aim down at the knot\n    ro.xz = rot(th) * ro.xz;                  // one full turn per loop\n    rd.xz = rot(th) * rd.xz;\n\n    float dt = 0.030;\n    float t  = 4.9;\n    vec3  col   = vec3(0.0);\n    float trans = 1.0;\n\n    for (int i = 0; i < STEPS; i++){\n      vec3 p = ro + rd * t;\n      float arc, core, sat;\n      float sheath = knot(p, th, arc, core, sat) * density;\n      float d = sheath + core * density * 0.55 + sat * satWeight * density * 0.85;\n\n      if (d > 0.002){\n        float hueArg = (atan(p.z, p.x) / TAU) * hueTravel + 0.06 * arc + ph;\n        vec3 emit = pal(hueArg);\n        emit += vec3(1.0, 0.84, 0.56) * core * 4.0;                     // incandescent core\n        emit += vec3(1.0, 0.42, 0.10) * pow(sheath, 2.0) * molten * 3.0; // molten hot spots\n        emit += satColor.rgb * sat * satWeight * 2.4;                    // satellite wire\n\n        col   += emit * d * trans * dt * 15.0 * exp(-0.26 * (t - 4.9));\n        trans *= exp(-d * dt * 24.0);\n        if (trans < 0.01) break;\n      }\n      t += dt;\n      if (t > 8.4) break;\n    }\n\n    col += vec3(0.030, 0.018, 0.060) * exp(-length(uv) * 3.2);\n    gl_FragColor = vec4(max(col, 0.0), 1.0);\n\n  } else {\n    vec2 uv = isf_FragNormCoord;\n    vec3 c  = IMG_THIS_PIXEL(scene).rgb;\n\n    vec3 glow = vec3(0.0);\n    for (int i = 0; i < 16; i++){\n      float a = TAU * (float(i) + 0.5) / 16.0;\n      vec2 dir = vec2(cos(a), sin(a));\n      glow += max(IMG_NORM_PIXEL(scene, uv + dir * 0.013).rgb - 0.55, 0.0);\n      glow += max(IMG_NORM_PIXEL(scene, uv + dir * 0.034).rgb - 0.55, 0.0) * 0.55;\n    }\n    glow /= 24.8;\n\n    vec3 col = c + glow * bloom * 1.5;\n    col *= exposure * 1.25;\n    col = 1.0 - exp(-col);                    // soft knee at DISPLAY only\n    col = pow(max(col, 0.0), vec3(0.92));\n    gl_FragColor = vec4(col, 1.0);\n  }\n}\n",
    "generator": {
      "model": "claude-opus-4-8",
      "provider": "anthropic",
      "prompt": null,
      "params": null
    }
  }
}