{
  "license": "CC0-1.0",
  "shader": {
    "id": "kez0lfbp",
    "title": "Gyroid Vibes",
    "license": "CC0-1.0",
    "provenance_type": "witnessed_generation",
    "made_with": "glslop",
    "status": "active",
    "compile_ok": true,
    "render_hash": "8290d7370ea06458",
    "tags": [
      "gyroid",
      "iridescent",
      "raymarching"
    ],
    "parents": [],
    "author": "hm39d0kwqymi",
    "author_name": "dewpoint",
    "author_url": "/u/dewpoint",
    "created_at": "2026-07-21T23:28:23.312Z",
    "poster_url": "/posters/kez0lfbp.avif",
    "stats": {
      "slops": 0,
      "views": 218,
      "forks": 0
    },
    "self": "/api/v1/shaders/kez0lfbp",
    "isf": "/*{\n    \"DESCRIPTION\": \"Flight through an infinite twisting gyroid lattice with iridescent edges and a multi-pass HDR bloom.\",\n    \"CREDIT\": \"Iridescence material after Psybernautics / IQ. CC0.\",\n    \"ISFVSN\": \"2\",\n    \"CATEGORIES\": [\"Generator\", \"Raymarching\", \"Geometry\"],\n    \"INPUTS\": [\n        { \"NAME\": \"uSpeed\",         \"TYPE\": \"float\", \"DEFAULT\": 0.75, \"MIN\": 0.0,   \"MAX\": 4.0,  \"LABEL\": \"Flight Speed\" },\n        { \"NAME\": \"uTwist\",         \"TYPE\": \"float\", \"DEFAULT\": 0.0255,\"MIN\": 0.0,  \"MAX\": 1.5,  \"LABEL\": \"Tunnel Twist\" },\n        { \"NAME\": \"uThickness\",     \"TYPE\": \"float\", \"DEFAULT\": 0.03, \"MIN\": 0.01,  \"MAX\": 0.20, \"LABEL\": \"Wall Thickness\" },\n        { \"NAME\": \"uRadius\",        \"TYPE\": \"float\", \"DEFAULT\": 1.9,  \"MIN\": 0.4,   \"MAX\": 3.0,  \"LABEL\": \"Tube Radius\" },\n        { \"NAME\": \"uEdge\",          \"TYPE\": \"float\", \"DEFAULT\": 4.1,  \"MIN\": 1.0,   \"MAX\": 8.0,  \"LABEL\": \"Edge Falloff\" },\n        { \"NAME\": \"uHue\",           \"TYPE\": \"float\", \"DEFAULT\": 0.0,  \"MIN\": 0.0,   \"MAX\": 1.0,  \"LABEL\": \"Hue Offset\" },\n        { \"NAME\": \"uHueSpeed\",      \"TYPE\": \"float\", \"DEFAULT\": 0.3,  \"MIN\": 0.0,   \"MAX\": 2.0,  \"LABEL\": \"Hue Drift Speed\" },\n        { \"NAME\": \"uGlow\",          \"TYPE\": \"float\", \"DEFAULT\": 0.001,\"MIN\": 0.0,   \"MAX\": 2.0,  \"LABEL\": \"Edge Glow\" },\n        { \"NAME\": \"uAudio\",         \"TYPE\": \"float\", \"DEFAULT\": 0.5,  \"MIN\": 0.0,   \"MAX\": 1.0,  \"LABEL\": \"Audio Pulse\" },\n        { \"NAME\": \"uBloomThresh\",   \"TYPE\": \"float\", \"DEFAULT\": 0.8,  \"MIN\": 0.0,  \"MAX\": 3.0,  \"LABEL\": \"Bloom Threshold\" },\n        { \"NAME\": \"uBloomIntensity\",\"TYPE\": \"float\", \"DEFAULT\": 1.2,  \"MIN\": 0.0,  \"MAX\": 4.0,  \"LABEL\": \"Bloom Intensity\" },\n        { \"NAME\": \"uBloomSize\",     \"TYPE\": \"float\", \"DEFAULT\": 1.0,  \"MIN\": 0.2,  \"MAX\": 3.0,  \"LABEL\": \"Bloom Size\" }\n    ],\n    \"PASSES\": [\n        { \"TARGET\": \"sceneBuf\", \"FLOAT\": true },\n        { \"TARGET\": \"blurX\",    \"FLOAT\": true, \"WIDTH\": \"floor($WIDTH/4.0)\", \"HEIGHT\": \"floor($HEIGHT/4.0)\" },\n        { \"TARGET\": \"blurY\",    \"FLOAT\": true, \"WIDTH\": \"floor($WIDTH/4.0)\", \"HEIGHT\": \"floor($HEIGHT/4.0)\" },\n        { }\n    ]\n}*/\n\n// ============================================================\n//  GYROID TUNNEL + BLOOM  —  ISF (glslop.com compatible)\n//\n//  4-pass pipeline, all self-contained:\n//    PASS 0 (sceneBuf) : raymarch the scene, output linear HDR\n//    PASS 1 (blurX)    : bright-pass threshold + horizontal blur (1/4 res)\n//    PASS 2 (blurY)    : vertical blur (1/4 res)\n//    PASS 3 (screen)   : composite scene + bloom, tonemap + gamma\n// ============================================================\n\nconst float PI = 3.14159265;\n\n// 2D rotation\nmat2 r2(float a){ float c = cos(a), s = sin(a); return mat2(c, -s, s, c); }\n\n// time-animated hue offset (uHue = manual offset, uHueSpeed = drift per second)\nfloat hueShift(){ return uHue + TIME * uHueSpeed; }\n\n// IQ cosine palette\nvec3 palette(float t){\n    return 0.5 + 0.5 * cos(6.28318 * (t + vec3(0.0, 0.33, 0.67) + hueShift()));\n}\n\n// gyroid pseudo-distance field\nfloat gyroid(vec3 p, float scale, float thick){\n    p *= scale;\n    return abs(dot(sin(p), cos(p.zxy))) / scale - thick;\n}\n\n// glow accumulator (reset per fragment in the scene pass)\nfloat g_glow;\n\nfloat map(vec3 p){\n    p.xy *= r2(p.z * uTwist);                 // twist the tunnel\n    float scale = 1.0 + uAudio * 0.6;         // audio-reactive pulse\n\n    float g1 = gyroid(p, 1.0 * scale, uThickness);\n    float g2 = gyroid(p, 2.0 * scale, uThickness * 0.5);\n    float d  = max(g1, -g2 * 0.7);            // subtract detail layer\n\n    // carve a hollow tube so the camera has empty space to fly through\n    float tube = uRadius - length(p.xy);\n    d = max(d, tube);\n\n    g_glow += 0.015 / (0.01 + d * d * 40.0);\n    return d;\n}\n\nvec3 getNormal(vec3 p){\n    vec2 e = vec2(0.001, 0.0);\n    return normalize(vec3(\n        map(p + e.xyy) - map(p - e.xyy),\n        map(p + e.yxy) - map(p - e.yxy),\n        map(p + e.yyx) - map(p - e.yyx)\n    ));\n}\n\n// ---- PASS 0: raymarch the scene into an HDR buffer ----\nvec3 renderScene(vec2 fragNorm){\n    g_glow = 0.0;\n\n    vec2 uv = (fragNorm * RENDERSIZE - 0.5 * RENDERSIZE) / RENDERSIZE.y;\n    float t = TIME * uSpeed;\n\n    vec3 ro = vec3(0.0, 0.0, t);\n    vec3 rd = normalize(vec3(uv, 1.2));\n    rd.xy *= r2(sin(t * 0.15) * 0.4);         // slow banking roll\n\n    float dist = 0.0;\n    bool  hit  = false;\n    vec3  p    = ro;\n\n    for(int i = 0; i < 120; i++){\n        p = ro + rd * dist;\n        float d = map(p);\n        if(d < 0.001){ hit = true; break; }\n        if(dist > 40.0) break;\n        dist += d * 0.7;\n    }\n\n    vec3 col = vec3(0.0);\n    vec3 hue = palette(TIME * 0.05 + 0.3);    // fallback tint for the background\n\n    if(hit){\n        vec3 n = getNormal(p);\n        float fres = pow(1.0 - clamp(dot(n, -rd), 0.0, 1.0), uEdge);\n\n        // iridescence material (from the reference shader)\n        float height = atan(n.y, n.x);\n        hue = cos((height + (vec3(0.0, 0.33, 0.67) + hueShift()) * PI) * 2.0) * 0.5 + 0.5;\n\n        vec3 wall = vec3(0.008, 0.008, 0.016);\n        col = wall + hue * fres * 3.5;        // HDR edges\n    }\n\n    col += hue * g_glow * uGlow;              // colored glow halo\n    col  = mix(col, vec3(0.0), smoothstep(20.0, 40.0, dist)); // depth fog\n    return col;\n}\n\n// separable Gaussian blur of the bright-pass, in `dir` (1,0) or (0,1)\nvec3 bloomBlur(vec2 fragNorm, vec2 dir){\n    vec2 px = (1.0 / RENDERSIZE) * dir * uBloomSize;\n    vec3 sum = vec3(0.0);\n    float wsum = 0.0;\n    for(int i = -6; i <= 6; i++){\n        float w = exp(-float(i * i) / 18.0);  // sigma = 3\n        vec2 uv = fragNorm + px * float(i);\n\n        vec3 s;\n        if(PASSINDEX == 1){\n            // sampling the full-res scene: apply the bright-pass threshold here\n            s = IMG_NORM_PIXEL(sceneBuf, uv).rgb;\n            s = max(s - uBloomThresh, 0.0);\n        } else {\n            // sampling the already-thresholded horizontal blur\n            s = IMG_NORM_PIXEL(blurX, uv).rgb;\n        }\n        sum  += s * w;\n        wsum += w;\n    }\n    return sum / wsum;\n}\n\nvoid main(){\n    vec2 fragNorm = isf_FragNormCoord;\n\n    if(PASSINDEX == 0){\n        // scene -> HDR buffer\n        gl_FragColor = vec4(renderScene(fragNorm), 1.0);\n\n    } else if(PASSINDEX == 1){\n        // bright-pass + horizontal blur (quarter res)\n        gl_FragColor = vec4(bloomBlur(fragNorm, vec2(1.0, 0.0)), 1.0);\n\n    } else if(PASSINDEX == 2){\n        // vertical blur (quarter res)\n        gl_FragColor = vec4(bloomBlur(fragNorm, vec2(0.0, 1.0)), 1.0);\n\n    } else {\n        // composite: scene + bloom, then tonemap + gamma\n        vec3 scene = IMG_NORM_PIXEL(sceneBuf, fragNorm).rgb;\n        vec3 bloom = IMG_NORM_PIXEL(blurY,   fragNorm).rgb;\n\n        vec3 col = scene + bloom * uBloomIntensity;\n\n        col = col / (1.0 + col);              // Reinhard tonemap\n        col = pow(col, vec3(0.4545));         // gamma\n        gl_FragColor = vec4(col, 1.0);\n    }\n}\n",
    "generator": {
      "model": "Claude Opus 4.8",
      "provider": null,
      "prompt": null,
      "params": null
    }
  }
}