{
  "license": "CC0-1.0",
  "shader": {
    "id": "xpzhitla",
    "title": "Still Rendering",
    "license": "CC0-1.0",
    "provenance_type": "witnessed_generation",
    "made_with": "claude",
    "status": "active",
    "compile_ok": true,
    "render_hash": "061baa12d726fefc",
    "tags": [
      "raytracing",
      "retro",
      "landscape",
      "3d",
      "phong",
      "beach",
      "computer",
      "computers"
    ],
    "parents": [],
    "author": "u7y1evhf0znj",
    "author_name": "ksin",
    "author_url": "/u/ksin",
    "created_at": "2026-08-01T15:18:57.557Z",
    "poster_url": "/posters/xpzhitla.avif",
    "stats": {
      "slops": 1,
      "views": 169,
      "forks": 0
    },
    "self": "/api/v1/shaders/xpzhitla",
    "isf": "/*{\n  \"DESCRIPTION\": \"A mid-1990s raytracer showpiece at sunset, traced for real. A chrome sphere and a refracting glass sphere preside over a grid of dead beige CRT terminals whose phosphor screens run little demoscene programs - source code typed out character by character, plasma, a checkered tunnel, digital rain, and one showing a live view of this very scene - all mirrored in a cracked, polished veined-marble checkerboard. Beside them stands a ruined Greek arcade: drum-built columns carrying real masonry arches, each a semicircular void cut through a stone spandrel by CSG. Shark fins cut the glittering lake, eyeballs drift overhead, and an Earth hangs in a sky that runs from a molten orange horizon through violet to a black star field. Whitted-style recursive reflections and refraction, one low warm key light with long hard shadows and cool skylight fill. Sliders: orbit, lens, camera height, eyeballs, eye speed, screen glow, sky hue, water hue, waves, reflection, palette depth, dither, scanlines, vignette, sky-art (paints the terminals' programs across the sky).\",\n  \"CREDIT\": \"CC0\",\n  \"CATEGORIES\": [\"generator\", \"raytracing\", \"retro\", \"3d\", \"landscape\", \"sunset\"],\n  \"INPUTS\": [\n    { \"NAME\": \"uSpeed\",    \"TYPE\": \"float\", \"DEFAULT\": 1.00, \"MIN\": 0.0, \"MAX\": 3.0 },\n    { \"NAME\": \"uFOV\",      \"TYPE\": \"float\", \"DEFAULT\": 2.10, \"MIN\": 1.1, \"MAX\": 4.0 },\n    { \"NAME\": \"uCamHt\",    \"TYPE\": \"float\", \"DEFAULT\": 3.20, \"MIN\": 0.6, \"MAX\": 9.0 },\n    { \"NAME\": \"uEyes\",     \"TYPE\": \"float\", \"DEFAULT\": 6.00, \"MIN\": 0.0, \"MAX\": 10.0 },\n    { \"NAME\": \"uEyeSpeed\", \"TYPE\": \"float\", \"DEFAULT\": 1.00, \"MIN\": 0.0, \"MAX\": 3.0 },\n    { \"NAME\": \"uScreens\",  \"TYPE\": \"float\", \"DEFAULT\": 1.25, \"MIN\": 0.0, \"MAX\": 3.0 },\n    { \"NAME\": \"uSkyHue\",   \"TYPE\": \"float\", \"DEFAULT\": 0.00, \"MIN\": 0.0, \"MAX\": 1.0 },\n    { \"NAME\": \"uWaveHue\",  \"TYPE\": \"float\", \"DEFAULT\": 0.00, \"MIN\": 0.0, \"MAX\": 1.0 },\n    { \"NAME\": \"uWave\",     \"TYPE\": \"float\", \"DEFAULT\": 1.00, \"MIN\": 0.0, \"MAX\": 2.0 },\n    { \"NAME\": \"uGloss\",    \"TYPE\": \"float\", \"DEFAULT\": 0.90, \"MIN\": 0.0, \"MAX\": 1.0 },\n    { \"NAME\": \"uPalette\",  \"TYPE\": \"float\", \"DEFAULT\": 32.0, \"MIN\": 2.0, \"MAX\": 32.0 },\n    { \"NAME\": \"uDither\",   \"TYPE\": \"float\", \"DEFAULT\": 0.12, \"MIN\": 0.0, \"MAX\": 1.0 },\n    { \"NAME\": \"uCRT\",      \"TYPE\": \"float\", \"DEFAULT\": 0.06, \"MIN\": 0.0, \"MAX\": 1.0 },\n    { \"NAME\": \"uVignette\", \"TYPE\": \"float\", \"DEFAULT\": 0.25, \"MIN\": 0.0, \"MAX\": 1.0 },\n    { \"NAME\": \"uSkyArt\",   \"TYPE\": \"float\", \"DEFAULT\": 0.00, \"MIN\": 0.0, \"MAX\": 1.0 }\n  ]\n}*/\n\n// RAYTRACE RELIC — glslop edition.\n// A compact rebuild of a much larger scene shader: the full version runs\n// 49 hand-placed terminals and ~20 materials, which compiles to far more\n// code than a software rasteriser will accept. Here every repeated thing\n// (terminals, columns, arches, fins, eyes) is placed by MATH inside a\n// loop instead of being unrolled by hand, which keeps the program small\n// enough to compile anywhere while keeping the scene's identity.\n// GLSL ES 1.00: constant loop bounds, gl_FragColor, TIME / RENDERSIZE.\n\n#define PLAZA 8.0\n#define TAU 6.28318\n\nvec3 LD;      // toward the low sun\nfloat gT;\n\n// ---- hashes / noise -----------------------------------------\nfloat h21(vec2 p){\n    p = fract(p * vec2(123.34, 456.21));\n    p += dot(p, p + 45.32);\n    return fract(p.x * p.y);\n}\nfloat vnoise(vec2 p){\n    vec2 i = floor(p), f = fract(p);\n    f = f*f*(3.0 - 2.0*f);\n    return mix(mix(h21(i), h21(i + vec2(1.0, 0.0)), f.x),\n               mix(h21(i + vec2(0.0, 1.0)), h21(i + vec2(1.0, 1.0)), f.x), f.y);\n}\nfloat fbm(vec2 p){\n    float v = 0.0, a = 0.5;\n    for (int i = 0; i < 3; i++){ v += a*vnoise(p); p *= 2.03; a *= 0.5; }\n    return v;\n}\nvec3 hueShift(vec3 c, float a){\n    if (a < 0.001) return c;\n    vec3 k = vec3(0.57735);\n    float ca = cos(a*TAU), sa = sin(a*TAU);\n    return c*ca + cross(k, c)*sa + k*dot(k, c)*(1.0 - ca);\n}\nfloat bayer(vec2 a){\n    a = floor(a);\n    float b = fract(a.x*0.5 + a.y*a.y*0.75);\n    vec2 c = floor(0.5*a);\n    return fract(c.x*0.5 + c.y*c.y*0.75)*0.25 + b;\n}\n\n// ---- sky: sunset -> violet -> starfield, clouds, mountains ---\nvec3 skyCol(vec3 rd){\n    float h = clamp(rd.y, 0.0, 1.0);\n    vec3 c = mix(vec3(1.00, 0.45, 0.15), vec3(0.40, 0.20, 0.42), smoothstep(0.0, 0.20, h));\n    c = mix(c, vec3(0.02, 0.03, 0.11), smoothstep(0.16, 0.72, h));\n    float sd = max(dot(rd, LD), 0.0);\n    c += vec3(1.00, 0.50, 0.18) * pow(sd, 10.0) * 0.60;\n    c += vec3(1.00, 0.88, 0.66) * pow(sd, 900.0) * 7.0;\n    float sf = smoothstep(0.22, 0.70, h);\n    if (sf > 0.01)\n        c += vec3(0.90, 0.94, 1.0)\n           * smoothstep(0.9955, 0.9990, h21(floor(rd.xz/max(rd.y,0.2)*110.0))) * sf * 1.6;\n    float hz = smoothstep(0.02, 0.16, rd.y);\n    if (hz > 0.002){\n        float f = fbm(rd.xz/max(rd.y, 0.02)*0.55 + vec2(gT*0.008, gT*0.005));\n        vec3 lit = mix(vec3(0.30, 0.18, 0.30), vec3(1.00, 0.74, 0.48), smoothstep(0.40, 0.80, f));\n        lit = mix(lit, vec3(1.00, 0.42, 0.14), smoothstep(0.32, 0.03, rd.y));\n        c = mix(c, lit, smoothstep(0.42, 0.70, f)*hz*0.95);\n    }\n    // an Earth, as a lit disc in a tangent basis (no geometry)\n    vec3 pd = normalize(vec3(0.62, 0.34, -0.71));\n    vec3 T = normalize(cross(pd, vec3(0.0, 1.0, 0.0))), B = cross(T, pd);\n    vec2 q = vec2(dot(rd, T), dot(rd, B)) / 0.20;\n    float r2 = dot(q, q);\n    if (r2 < 1.0){\n        vec3 pn = normalize(T*q.x + B*q.y + pd*sqrt(1.0 - r2));\n        float land = fbm(q*1.9 + 5.0);\n        vec3 pc = mix(vec3(0.05, 0.16, 0.42), vec3(0.10, 0.30, 0.55), smoothstep(0.38, 0.48, land));\n        pc = mix(pc, mix(vec3(0.22, 0.38, 0.16), vec3(0.55, 0.46, 0.28), smoothstep(0.52, 0.68, land)),\n                 smoothstep(0.48, 0.52, land));\n        pc = mix(pc, vec3(0.95, 0.96, 1.0), smoothstep(0.52, 0.70, fbm(q*2.6 - 2.0))*0.75);\n        c = pc*(0.10 + 0.90*max(dot(pn, LD), 0.0)) + vec3(0.35, 0.55, 0.95)*pow(r2, 6.0)*0.35;\n    }\n    float sl = rd.y / max(length(rd.xz), 1e-4);\n    if (sl < 0.40){\n        float az = atan(rd.x, rd.z);\n        float h2 = max(0.085 + 0.075*sin(az*3.0 + 2.1) + 0.045*sin(az*7.3 + 0.6), 0.02);\n        float h1 = 0.075 + 0.110*sin(az*2.2 + 5.0) + 0.060*sin(az*5.9 + 1.7);\n        if (sl < h2) c = mix(vec3(0.42, 0.24, 0.30), vec3(0.30, 0.20, 0.34), clamp(sl/h2, 0.0, 1.0));\n        if (sl < h1) c = mix(mix(vec3(0.16, 0.07, 0.10), vec3(0.10, 0.07, 0.14), clamp(sl*4.0, 0.0, 1.0)),\n                             vec3(1.0, 0.78, 0.60), smoothstep(0.07, 0.14, sl));\n    }\n    return hueShift(c, uSkyHue);\n}\n\n// a low-bit \"camera feed\" of this same world, for one of the screens\nvec3 sceneFeed(vec2 uv){\n    vec2 q = uv*2.0 - 1.0;\n    float a = gT*0.15;\n    vec3 ro = vec3(sin(a)*13.0, 3.4, cos(a)*13.0);\n    vec3 fw = normalize(vec3(0.0, 0.9, 0.0) - ro);\n    vec3 rt = normalize(cross(fw, vec3(0.0, 1.0, 0.0)));\n    vec3 rd = normalize(fw*1.55 + rt*q.x + cross(rt, fw)*q.y*0.62);\n    vec3 c;\n    if (rd.y < -0.001){\n        float d = -ro.y/rd.y;\n        vec3 p = ro + rd*d;\n        float e = max(abs(p.x), abs(p.z));\n        if (e < PLAZA) c = mix(vec3(0.20, 0.11, 0.11), vec3(0.90, 0.86, 0.80),\n                               mod(floor(p.x) + floor(p.z), 2.0));\n        else           c = mix(vec3(0.72, 0.64, 0.46), vec3(0.02, 0.09, 0.15),\n                               smoothstep(PLAZA, PLAZA + 3.2, e));\n        c *= clamp(15.0/d, 0.20, 1.0);\n    } else c = skyCol(rd);\n    return floor(c*7.0 + 0.5)/7.0 * 1.2;\n}\n\n// ---- what each terminal is running --------------------------\nvec3 screenArt(vec2 uv, float seed){\n    float sd = fract(sin(seed*12.9898 + 4.1)*43758.5453);\n    if (seed > 90.0) return sceneFeed(uv);          // the pillar-top set\n    // three independent hashes per machine: which program it runs, and\n    // then its own zoom, speed and palette rotation — so two terminals on\n    // the same program still don't look like each other\n    float h2 = fract(sin(seed*78.233 + 1.7)*24634.633);\n    float h3 = fract(sin(seed*41.317 + 9.2)*17231.117);\n    float zoom  = 0.65 + 1.10*h2;\n    float rate  = 0.55 + 1.30*h3;\n    float t = (gT + seed*3.7)*rate;\n    // program picked by INDEX, not by hash: with 25 machines a hash\n    // leaves some programs unseen, and the fractal was one of the missing\n    // ones. mod() cycles through all eight so each is on screen somewhere.\n    float prog = mod(seed, 8.0);\n    vec3 ph = (sd < 0.34) ? vec3(0.34, 1.00, 0.42)\n            : (sd < 0.67) ? vec3(1.00, 0.70, 0.20) : vec3(0.60, 0.80, 1.00);\n    vec2 q = uv*2.0 - 1.0;\n    vec3 c;\n    if (prog < 1.0){\n        // source code, typed out fast, scrolling up\n        float S = 6.5 + 2.0*sd, scr = t*S + sd*80.0;\n        float row = floor((1.0 - uv.y)*17.0 + scr), col = floor(uv.x*30.0);\n        float ind = floor(h21(vec2(row, 1.7))*5.0)*2.0;\n        float len = 5.0 + h21(vec2(row, 4.2))*19.0;\n        float lc = col - ind;\n        float on = step(0.0, lc)*step(lc, len)\n                 * step(0.22, h21(vec2(floor(lc*0.25), row)))\n                 * step(0.18, h21(vec2(col, row)));\n        float typed = fract(scr)*(len + 3.0);\n        if (abs(row - floor(scr)) < 0.5) on *= step(lc, typed);\n        float cur = (abs(row - floor(scr)) < 0.5 && abs(lc - typed) < 0.9) ? 1.0 : 0.0;\n        float tone = 0.55 + 0.65*h21(vec2(col*3.1, row*1.3));\n        if (h21(vec2(row, 9.9)) < 0.14) tone *= 0.45;      // comment line\n        c = ph*(0.10 + on*tone*2.0) + vec3(1.0)*cur*1.8;\n    } else if (prog < 2.0){\n        vec2 g = uv*6.0*zoom;\n        float v = sin(g.x + t*1.7) + sin(g.y + t*1.3)\n                + sin((g.x + g.y)*0.7 + t*2.1) + sin(length(g - 3.0)*2.0 - t*2.4);\n        c = (0.5 + 0.5*cos(TAU*(vec3(0.0, 0.33, 0.67) + v*0.25 + sd)))*1.25;\n    } else if (prog < 3.0){\n        float r = max(length(q), 1e-3);\n        float ck = mod(floor(atan(q.y, q.x)/3.14159*9.0) + floor((0.35/r + t*0.8)*3.0), 2.0);\n        c = mix(vec3(0.04, 0.02, 0.12), ph, ck) * clamp(r*1.9, 0.0, 1.0);\n    } else if (prog < 4.0){\n        // digital rain\n        float cx = floor(uv.x*(10.0 + 12.0*h2));\n        float head = fract(h21(vec2(cx, 5.0)) + t*(0.6 + h21(vec2(cx, 1.0))*1.6)*0.4);\n        float rw = floor((1.0 - uv.y)*20.0);\n        c = ph * step(0.35, h21(vec2(cx, rw + floor(t*9.0))))\n               * smoothstep(0.5, 0.0, fract(head - rw/20.0)) * 1.6;\n    } else if (prog < 5.0){\n        // oscilloscope over a graticule\n        float w = 0.55*sin(q.x*(4.0 + 5.0*h2) + t*5.0)*sin(q.x*2.0 - t*1.3);\n        vec2 g = abs(fract(uv*8.0) - 0.5);\n        c = ph*0.22*smoothstep(0.46, 0.5, max(g.x, g.y))\n          + ph*smoothstep(0.10, 0.0, abs(q.y - w))*1.7;\n    } else if (prog < 6.0){\n        // metaballs\n        float fsum = 0.0;\n        for (int k = 0; k < 3; k++){\n            float fk = float(k);\n            vec2 bp = 0.6*vec2(sin(t*(0.7 + 0.3*fk) + fk*2.0), cos(t*(0.5 + 0.4*fk) + fk));\n            fsum += 0.14/max(dot(q - bp, q - bp), 0.01);\n        }\n        c = mix(vec3(0.01, 0.0, 0.04), ph*1.25, smoothstep(1.0, 1.9, fsum));\n    } else if (prog < 7.0){\n        // concentric interference rings\n        float d1 = length(q - vec2(0.35*sin(t*0.7), 0.30*cos(t*0.9)));\n        float d2 = length(q + vec2(0.32*cos(t*0.6), 0.28*sin(t*1.1)));\n        float w = sin(d1*(14.0*zoom) - t*3.0) * sin(d2*(12.0*zoom) + t*2.2);\n        c = ph * smoothstep(0.12, 0.92, 0.5 + 0.5*w) * 1.35\n              * (0.45 + 0.55*smoothstep(1.3, 0.1, length(q)));\n    } else {\n        // the fractal: a Julia set with its seed orbiting\n        vec2 z = q*(1.45/zoom);\n        vec2 k = 0.7885*vec2(cos(t*0.35), sin(t*0.35));\n        float it = 0.0;\n        for (int i = 0; i < 16; i++){\n            if (dot(z, z) < 4.0){\n                z = vec2(z.x*z.x - z.y*z.y, 2.0*z.x*z.y) + k;\n                it += 1.0;\n            }\n        }\n        float fr = it/16.0;\n        c = (0.5 + 0.5*cos(TAU*(vec3(0.0, 0.40, 0.70) + fr*2.5 + sd)))*step(fr, 0.999);\n    }\n    // per-machine palette rotation on top of the phosphor choice\n    c = hueShift(c, h3*0.16);\n    return c;\n}\n\n// Eye positions. ring 0 = the big outer drifters, ring 1 = a tighter\n// swarm of small ones orbiting close over the chrome ball.\nvec3 eyePos(float fe, float ring){\n    float a1 = h21(vec2(fe, 1.3 + ring*5.0));\n    float a2 = h21(vec2(fe, 7.7 + ring*3.0));\n    float sp = uEyeSpeed*(0.25 + 0.60*a1);\n    float an = gT*sp*(0.45 + ring*0.55) + fe*2.39 + ring*1.1;\n    float rr = (ring < 0.5) ? (3.0 + 5.6*a2 + 0.85*sin(gT*sp*0.31 + fe*1.9))\n                            : (2.9 + 1.5*a2 + 0.40*sin(gT*sp*0.60 + fe*2.3));\n    float hy = (ring < 0.5) ? (6.20 + 2.4*a1 + 0.75*sin(gT*sp*0.90 + fe*1.7))\n                            : (4.05 + 0.9*a1 + 0.45*sin(gT*sp*1.20 + fe*2.1));\n    return vec3(cos(an)*rr + 0.55*sin(gT*sp*0.53 + fe*2.7), hy,\n                sin(an)*rr + 0.55*cos(gT*sp*0.47 + fe*3.3));\n}\nfloat eyeRad(float fe, float ring){\n    return (ring < 0.5) ? (0.26 + 0.24*h21(vec2(fe, 7.7)))\n                        : (0.13 + 0.10*h21(vec2(fe, 2.4)));\n}\n// ---- primitives ---------------------------------------------\nfloat iSph(vec3 ro, vec3 rd, vec3 c, float r){\n    vec3 oc = ro - c;\n    float b = dot(oc, rd), h = b*b - dot(oc, oc) + r*r;\n    if (h < 0.0) return -1.0;\n    h = sqrt(h);\n    float t = -b - h;\n    if (t < 0.001) t = -b + h;\n    return t > 0.001 ? t : -1.0;\n}\nfloat iBox(vec3 ro, vec3 rd, vec3 c, vec3 b, out vec3 n){\n    vec3 o = ro - c, m = 1.0/rd, k = abs(m)*b, t1 = -m*o - k, t2 = -m*o + k;\n    float tN = max(max(t1.x, t1.y), t1.z), tF = min(min(t2.x, t2.y), t2.z);\n    n = vec3(0.0);\n    if (tN > tF || tF < 0.001) return -1.0;\n    n = -sign(rd)*step(t1.yzx, t1.xyz)*step(t1.zxy, t1.xyz);\n    return tN > 0.001 ? tN : tF;\n}\nfloat iCyl(vec3 ro, vec3 rd, vec3 c, float r, float h){\n    vec2 oc = ro.xz - c.xz;\n    float a = dot(rd.xz, rd.xz);\n    if (a < 1e-6) return -1.0;\n    float b = dot(oc, rd.xz), k = dot(oc, oc) - r*r, d = b*b - a*k;\n    if (d < 0.0) return -1.0;\n    float s = sqrt(d), t = (-b - s)/a, y = ro.y + rd.y*t;\n    if (t > 0.001 && y >= c.y && y <= c.y + h) return t;\n    t = (-b + s)/a; y = ro.y + rd.y*t;\n    if (t > 0.001 && y >= c.y && y <= c.y + h) return t;\n    return -1.0;\n}\n\n// scene state written by the intersector, read by the shader\nvec3 gScrC, gScrS; float gScrSeed, gScrAxis;\n\nvoid hSph(vec3 ro, vec3 rd, vec3 c, float r, float mid,\n          inout float best, inout float id, inout vec3 n){\n    float t = iSph(ro, rd, c, r);\n    if (t > 0.0 && t < best){ best = t; id = mid; n = normalize(ro + rd*t - c); }\n}\nvoid hBox(vec3 ro, vec3 rd, vec3 c, vec3 b, float mid,\n          inout float best, inout float id, inout vec3 n){\n    vec3 bn; float t = iBox(ro, rd, c, b, bn);\n    if (t > 0.001 && t < best){ best = t; id = mid; n = bn; }\n}\nvoid hCyl(vec3 ro, vec3 rd, vec3 c, float r, float h, float mid,\n          inout float best, inout float id, inout vec3 n){\n    float t = iCyl(ro, rd, c, r, h);\n    if (t > 0.0 && t < best){\n        best = t; id = mid;\n        vec3 p = ro + rd*t;\n        n = normalize(vec3(p.x - c.x, 0.0, p.z - c.z));\n    }\n    // cap it, so a snapped column isn't a hollow pipe\n    if (abs(rd.y) > 1e-6){\n        float tc = (c.y + h - ro.y)/rd.y;\n        if (tc > 0.001 && tc < best){\n            vec2 d = (ro.xz + rd.xz*tc) - c.xz;\n            if (dot(d, d) <= r*r){ best = tc; id = mid; n = vec3(0.0, 1.0, 0.0); }\n        }\n    }\n}\n// a REAL arch: box minus a z-axis cylinder, so the opening is carved\n// through solid stone and the intrados curves\nvoid hArch(vec3 ro, vec3 rd, vec3 c, vec3 b, float hy, float hr,\n           inout float best, inout float id, inout vec3 n){\n    vec3 o = ro - c, m = 1.0/rd, k = abs(m)*b, t1 = -m*o - k, t2 = -m*o + k;\n    float bN = max(max(t1.x, t1.y), t1.z), bF = min(min(t2.x, t2.y), t2.z);\n    if (bN > bF || bF < 0.001 || bN >= best) return;\n    vec2 oc = ro.xy - vec2(c.x, c.y + hy);\n    float a = dot(rd.xy, rd.xy), cN = 1e9, cF = -1e9;\n    if (a > 1e-8){\n        float bb = dot(oc, rd.xy), cc = dot(oc, oc) - hr*hr, hh = bb*bb - a*cc;\n        if (hh > 0.0){ float s = sqrt(hh); cN = (-bb - s)/a; cF = (-bb + s)/a; }\n    } else if (dot(oc, oc) < hr*hr){ cN = -1e9; cF = 1e9; }\n    float t = bN;\n    if (t > cN && t < cF){                       // entered through the void\n        t = cF;\n        if (t > bF || t < 0.001 || t >= best) return;\n        best = t; id = 6.0;\n        n = vec3(-normalize((ro + rd*t).xy - vec2(c.x, c.y + hy)), 0.0);\n        return;\n    }\n    if (t < 0.001 || t >= best) return;\n    best = t; id = 6.0;\n    n = -sign(rd)*step(t1.yzx, t1.xyz)*step(t1.zxy, t1.xyz);\n}\nvoid hTri(vec3 ro, vec3 rd, vec3 v0, vec3 v1, vec3 v2, float mid,\n          inout float best, inout float id, inout vec3 n){\n    vec3 e1 = v1 - v0, e2 = v2 - v0, pv = cross(rd, e2);\n    float det = dot(e1, pv);\n    if (abs(det) < 1e-7) return;\n    float inv = 1.0/det;\n    vec3 tv = ro - v0;\n    float u = dot(tv, pv)*inv;\n    if (u < 0.0 || u > 1.0) return;\n    vec3 qv = cross(tv, e1);\n    float v = dot(rd, qv)*inv;\n    if (v < 0.0 || u + v > 1.0) return;\n    float t = dot(e2, qv)*inv;\n    if (t > 0.001 && t < best){\n        best = t; id = mid; n = normalize(cross(e1, e2));\n        if (dot(n, rd) > 0.0) n = -n;\n    }\n}\n\n// a beige CRT: pedestal, neck, tapered tube, bezel, screen, keyboard, mouse\nvoid hMon(vec3 ro, vec3 rd, vec3 b, float axis, float sgn, float seed, float kb,\n          inout float best, inout float id, inout vec3 n){\n    vec3 f = (axis < 0.5) ? vec3(0.0, 0.0, sgn) : vec3(sgn, 0.0, 0.0);\n    if (iSph(ro, rd, b + vec3(0.0, 0.51, 0.0) + f*0.28, 1.14) < 0.0) return;\n    hBox(ro, rd, b + vec3(0.0, 0.05, 0.0), vec3(0.30, 0.05, 0.28), 7.0, best, id, n);\n    // neck spans 0.10 to 0.30 so it actually MEETS the stand below it and\n    // the tube above it — it used to start at 0.16 and float\n    hBox(ro, rd, b + vec3(0.0, 0.20, 0.0), vec3(0.12, 0.10, 0.12), 7.0, best, id, n);\n    vec3 cf = (axis < 0.5) ? vec3(0.44, 0.36, 0.26) : vec3(0.26, 0.36, 0.44);\n    vec3 cr = (axis < 0.5) ? vec3(0.32, 0.27, 0.22) : vec3(0.22, 0.27, 0.32);\n    hBox(ro, rd, b + vec3(0.0, 0.66, 0.0) + f*0.16, cf, 7.0, best, id, n);\n    hBox(ro, rd, b + vec3(0.0, 0.62, 0.0) - f*0.28, cr, 7.0, best, id, n);\n    float dep = 0.16 + ((axis < 0.5) ? cf.z : cf.x);\n    hBox(ro, rd, b + vec3(0.0, 0.66, 0.0) + f*(dep + 0.02),\n         (axis < 0.5) ? vec3(0.40, 0.32, 0.025) : vec3(0.025, 0.32, 0.40), 7.0, best, id, n);\n    vec3 sc = b + vec3(0.0, 0.66, 0.0) + f*(dep + 0.055);\n    vec3 ss = (axis < 0.5) ? vec3(0.33, 0.25, 0.02) : vec3(0.02, 0.25, 0.33);\n    float b0 = best;\n    hBox(ro, rd, sc, ss, 8.0, best, id, n);\n    // hand the winning glass its own frame so the material can build\n    // SCREEN-LOCAL uv (world-space uv makes distant sets render blank)\n    if (best < b0){ gScrC = sc; gScrS = ss; gScrSeed = seed; gScrAxis = axis; }\n    if (kb > 0.5){          // floor sets only: nothing holds these up\n        vec3 kc = b + f*(dep + 0.50);\n        hBox(ro, rd, kc + vec3(0.0, 0.030, 0.0),\n             (axis < 0.5) ? vec3(0.34, 0.030, 0.145) : vec3(0.145, 0.030, 0.34), 9.0, best, id, n);\n        hBox(ro, rd, kc - f*0.095 + vec3(0.0, 0.075, 0.0),\n             (axis < 0.5) ? vec3(0.34, 0.022, 0.05) : vec3(0.05, 0.022, 0.34), 9.0, best, id, n);\n        hBox(ro, rd, kc + ((axis < 0.5) ? vec3(0.48, 0.04, 0.0) : vec3(0.0, 0.04, 0.48)),\n             vec3(0.075, 0.04, 0.10), 7.0, best, id, n);\n    }\n}\n\n// Two rings, each EVENLY spaced around its own circumference: 13 at r5.2\n// and 20 at r7.9. A single spiral (one angular step for both radii) packs\n// badly — push it past ~23 machines and pairs start overlapping. Solving\n// the rings separately fits 25 with every pair >2.45 apart (a unit is\n// ~2.2 across). The loop then skips the arcade sector, the pillar, the\n// marble edge and both spheres.\nvec3 monPos(int i){\n    float fi = float(i);\n    if (fi < 13.0) return vec3(cos(fi*0.4833)*5.2, 0.0, sin(fi*0.4833)*5.2);\n    float k = fi - 13.0;\n    return vec3(cos(k*0.31416)*7.9, 0.0, sin(k*0.31416)*7.9);\n}\n\n// ---- the scene ----------------------------------------------\n// A sphere's centre height must equal its radius to sit on the floor.\n// Enlarging both meant moving the glass out: at r 1.75 + 1.30 the old\n// 2.75-unit gap would have had them interpenetrating.\n#define CHROME vec3(0.0, 1.75, 0.0)\n#define CH_R 1.75\n#define GLASS  vec3(-3.2, 1.30, 1.6)\n#define GBALL_R 1.30\n\nfloat hitScene(vec3 ro, vec3 rd, out float id, out vec3 n){\n    float best = 1e9; id = -1.0; n = vec3(0.0, 1.0, 0.0);\n    if (rd.y < -0.0001){\n        float t = -ro.y/rd.y;\n        if (t > 0.001){ best = t; id = 0.0; n = vec3(0.0, 1.0, 0.0); }\n    }\n    hSph(ro, rd, CHROME, CH_R, 1.0, best, id, n);\n    hSph(ro, rd, GLASS,  GBALL_R, 2.0, best, id, n);\n    // terminals\n    vec3 mg;\n    if (iBox(ro, rd, vec3(0.0, 0.6, 0.0), vec3(8.6, 0.75, 8.6), mg) > 0.0){\n        for (int i = 0; i < 33; i++){\n            vec3 mp = monPos(i);\n            if (mp.z < -5.2) continue;                       // arcade sector\n            if (distance(mp.xz, vec2(6.6, 1.4)) < 1.8) continue;   // the pillar\n            if (max(abs(mp.x), abs(mp.z)) > 7.9) continue;    // keep off the sand\n            if (length(mp.xz) < CH_R + 1.30) continue;        // the chrome ball\n            if (distance(mp.xz, GLASS.xz) < GBALL_R + 1.30) continue;  // the glass ball\n            float ax = (abs(mp.x) > abs(mp.z)) ? 1.0 : 0.0;  // face outward\n            hMon(ro, rd, mp, ax, (ax > 0.5) ? sign(mp.x) : sign(mp.z),\n                 float(i), 1.0, best, id, n);\n        }\n    }\n    // a pillar with one more terminal on top, showing the scene itself\n    // Built to the same order as the arcade columns rather than as a bare\n    // cylinder: square plinth, round torus base, a shaft of four drums\n    // that taper as they rise (entasis, and fluted — material 5), then\n    // echinus and abacus. The abacus top lands at 2.40, which is where\n    // the terminal already sat, so the machine doesn't move.\n    hBox(ro, rd, vec3(6.6, 0.09, 1.4), vec3(0.46, 0.09, 0.46), 6.0, best, id, n);  // plinth\n    hCyl(ro, rd, vec3(6.6, 0.18, 1.4), 0.40, 0.10, 6.0, best, id, n);              // torus base\n    for (int d = 0; d < 4; d++){\n        float fd = float(d);\n        hCyl(ro, rd, vec3(6.6, 0.28 + 0.45*fd, 1.4), 0.34 - 0.04*fd/3.0, 0.45,\n             5.0, best, id, n);                                                    // fluted drums\n    }\n    hCyl(ro, rd, vec3(6.6, 2.08, 1.4), 0.40, 0.14, 6.0, best, id, n);              // echinus\n    hBox(ro, rd, vec3(6.6, 2.31, 1.4), vec3(0.48, 0.09, 0.48), 6.0, best, id, n);  // abacus\n    hMon(ro, rd, vec3(6.6, 2.40, 1.4), 1.0, -1.0, 99.0, 0.0, best, id, n);\n    // the arcade: stylobate, 4 drum-built columns, 3 masonry arches\n    vec3 ag;\n    if (iBox(ro, rd, vec3(-3.2, 2.3, -6.9), vec3(4.4, 2.4, 1.2), ag) > 0.0){\n        hBox(ro, rd, vec3(-3.2, 0.18, -6.9), vec3(4.0, 0.18, 0.95), 6.0, best, id, n);\n        hBox(ro, rd, vec3(-3.2, 0.50, -6.9), vec3(3.8, 0.16, 0.80), 6.0, best, id, n);\n        for (int i = 0; i < 4; i++){\n            float x = -6.4 + float(i)*1.6;\n            float sh = (i == 3) ? 1.6 : 2.7;          // one snapped short\n            hBox(ro, rd, vec3(x, 0.73, -6.9), vec3(0.42, 0.07, 0.42), 6.0, best, id, n);\n            for (int d = 0; d < 4; d++){\n                float fd = float(d);\n                hCyl(ro, rd, vec3(x, 0.80 + sh/4.0*fd, -6.9),\n                     0.30 - 0.03*fd/3.0, sh/4.0, 5.0, best, id, n);\n            }\n            if (i != 3){\n                hCyl(ro, rd, vec3(x, 0.80 + sh, -6.9), 0.34, 0.12, 6.0, best, id, n);\n                hBox(ro, rd, vec3(x, 3.68, -6.9), vec3(0.40, 0.08, 0.40), 6.0, best, id, n);\n            }\n        }\n        for (int i = 0; i < 3; i++)\n            hArch(ro, rd, vec3(-5.6 + float(i)*1.6, 3.90, -6.9),\n                  vec3(0.80, 0.40, 0.26), -0.35, 0.54, best, id, n);\n        hBox(ro, rd, vec3(-4.0, 4.46, -6.9), vec3(2.75, 0.16, 0.46), 6.0, best, id, n);\n    }\n    // eyeballs — continuous drift only, and high enough to clear the arcade\n    vec3 eg;\n    if (iBox(ro, rd, vec3(0.0, 7.4, 0.0), vec3(11.5, 3.3, 11.5), eg) > 0.0){\n        for (int i = 0; i < 10; i++){\n            if (float(i) >= uEyes) break;\n            float fe = float(i);\n            hSph(ro, rd, eyePos(fe, 0.0), eyeRad(fe, 0.0), 10.0, best, id, n);\n        }\n        // a tighter swarm of little ones circling just above the chrome\n        for (int i = 0; i < 8; i++){\n            if (float(i) >= uEyes*0.8) break;\n            float fe = float(i);\n            hSph(ro, rd, eyePos(fe, 1.0), eyeRad(fe, 1.0), 10.0, best, id, n);\n        }\n    }\n    // beach balls, bobbing where the marble meets the sand\n    for (int i = 0; i < 5; i++){\n        float fb2 = float(i);\n        float ba = fb2*1.257 + 0.6;\n        // >=10.3 keeps them clear of the outer terminal ring (which\n        // reaches 9.05) and puts them out on the sand / in the shallows\n        float br = 10.3 + 0.9*h21(vec2(fb2, 3.3));\n        float rad = 0.42 + 0.20*h21(vec2(fb2, 8.1));\n        hSph(ro, rd, vec3(cos(ba)*br,\n                          rad + 0.10*abs(sin(gT*1.1 + fb2*2.0)),\n                          sin(ba)*br), rad, 12.0, best, id, n);\n    }\n    // shark fins. The shore is a CHEBYSHEV boundary but these swim a\n    // EUCLIDEAN circle, so the radius must clear 13.35*sqrt(2) = 18.9 or\n    // they surface on the beach.\n    for (int i = 0; i < 6; i++){\n        float fs = float(i);\n        float an = gT*(0.050 + 0.018*fs) + fs*1.9;\n        float rr = 20.0 + 2.8*fs + 1.2*sin(gT*0.3 + fs);\n        vec3 fb = vec3(cos(an)*rr, -0.08, sin(an)*rr);\n        vec3 dr = vec3(-sin(an), 0.0, cos(an));\n        vec3 tp = fb - dr*0.55 + vec3(0.0, 1.40, 0.0);\n        hTri(ro, rd, fb + dr*0.80, tp, fb - dr*0.95, 11.0, best, id, n);\n        hTri(ro, rd, fb - dr*0.95, tp, fb - dr*0.40 + vec3(0.0, 0.55, 0.0), 11.0, best, id, n);\n    }\n    return best;\n}\n\nfloat shadowRay(vec3 p){\n    vec3 dn;\n    if (iSph(p, LD, CHROME, CH_R) > 0.0) return 0.0;\n    if (iBox(p, LD, vec3(0.0, 0.6, 0.0), vec3(8.6, 0.75, 8.6), dn) > 0.001){\n        for (int i = 0; i < 33; i++){\n            vec3 b = monPos(i);\n            if (iBox(p, LD, b + vec3(0.0, 0.55, 0.0), vec3(0.45, 0.55, 0.45), dn) > 0.001)\n                return 0.0;\n        }\n    }\n    if (iBox(p, LD, vec3(-4.0, 4.06, -6.9), vec3(2.75, 0.56, 0.50), dn) > 0.001) return 0.0;\n    if (iCyl(p, LD, vec3(6.6, 0.0, 1.4), 0.42, 2.40) > 0.001) return 0.0;\n    float s = 1.0;\n    if (iSph(p, LD, GLASS, GBALL_R) > 0.0) s *= 0.45;    // glass only tints\n    return s;\n}\n\n// ---- the tracer ---------------------------------------------\nvec3 trace(vec3 ro, vec3 rd){\n    vec3 col = vec3(0.0), att = vec3(1.0);\n    for (int i = 0; i < 4; i++){\n        float id; vec3 n;\n        float t = hitScene(ro, rd, id, n);\n        if (id < 0.0){\n            vec3 sky = skyCol(rd);\n            if (uSkyArt > 0.001 && rd.y > 0.02){\n                // reuse a terminal's program as a sky panel. Seeds stay\n                // under 90 so this can't reach sceneFeed -> skyCol, which\n                // would be recursion (illegal in GLSL).\n                float band = floor(atan(rd.x, rd.z)/TAU*4.0 + 4.0);\n                vec2 suv = vec2(fract(atan(rd.x, rd.z)/TAU*4.0),\n                                clamp(rd.y*1.7, 0.0, 1.0));\n                sky = mix(sky, screenArt(suv, band*3.0 + 1.0),\n                          uSkyArt*smoothstep(0.02, 0.35, rd.y)*0.75);\n            }\n            col += att*sky; break;\n        }\n        vec3 p = ro + rd*t, rr = reflect(rd, n);\n        float sh = (i < 1) ? shadowRay(p + n*0.002) : 1.0;\n        float dif = max(dot(n, LD), 0.0)*sh;\n        float spec = pow(max(dot(rr, LD), 0.0), 90.0)*sh;\n\n        if (id < 2.5 && id > 1.5){\n            // glass: fresnel reflection, then refract through and carry on\n            float c = clamp(-dot(rd, n), 0.0, 1.0);\n            float fr = 0.04 + 0.96*pow(1.0 - c, 5.0);\n            col += att*(skyCol(rr)*fr*0.85 + vec3(1.0)*spec*1.6);\n            vec3 ri = refract(rd, n, 0.667);\n            vec3 oc = p - GLASS;\n            float b = dot(oc, ri);\n            float t2 = -b + sqrt(max(b*b - dot(oc, oc) + GBALL_R*GBALL_R, 0.0));\n            vec3 p2 = p + ri*t2;\n            vec3 ro2 = refract(ri, -normalize(p2 - GLASS), 1.5);\n            if (dot(ro2, ro2) < 0.5) ro2 = ri;\n            att *= exp(-t2*vec3(0.50, 0.05, 0.22))*(1.0 - fr*0.7);\n            ro = p2 + ro2*0.002; rd = ro2;\n        } else {\n            vec3 alb, tint = vec3(1.0);\n            float kr, ks = 1.0, gs = uGloss;\n            vec3 emis = vec3(0.0);\n            if (id < 0.5){\n                float e = max(abs(p.x), abs(p.z));\n                float ea = atan(p.z, p.x);\n                float esh = 11.3 + 1.1*sin(ea*3.0 + 0.5) + 0.6*sin(ea*6.0 + 2.0) + 0.35*sin(ea*11.0);\n                if (e > esh){\n                    n = normalize(vec3(uWave*(0.030*sin(p.x*1.4 + gT*1.2) + 0.018*sin((p.x + p.z)*2.7 - gT*1.7)),\n                                       1.0,\n                                       uWave*(0.026*sin(p.z*1.1 - gT*0.9) + 0.014*sin((p.z - p.x)*3.1 + gT*1.4))));\n                    rr = reflect(rd, n);\n                    dif = max(dot(n, LD), 0.0)*sh;\n                    spec = pow(max(dot(rr, LD), 0.0), 200.0)*sh;\n                    alb = hueShift(vec3(0.01, 0.07, 0.12), uWaveHue);\n                    kr = (0.10 + 0.85*pow(1.0 - clamp(-dot(rd, n), 0.0, 1.0), 3.0))*(0.25 + 0.75*uGloss);\n                    tint = hueShift(vec3(0.75, 0.90, 1.0), uWaveHue);\n                    ks = 3.0; gs = 1.0;\n                } else if (e > PLAZA){\n                    vec3 sc = vec3(0.75, 0.67, 0.48);\n                    sc *= 1.0 + vnoise(p.xz*7.0)*0.13 + vnoise(p.xz*24.0)*0.06 - 0.09\n                        + 0.05*sin(e*7.0 + vnoise(p.xz*2.0)*4.0);\n                    float wet = smoothstep(esh - 1.6, esh - 0.1, e);\n                    sc = mix(sc, vec3(0.40, 0.38, 0.32), wet*0.75);\n                    sc = mix(sc, vec3(0.96, 0.98, 1.0),\n                             clamp(smoothstep(esh - 0.35, esh - 0.08, e)\n                                 * smoothstep(esh + 0.05, esh - 0.08, e), 0.0, 1.0)*0.85);\n                    alb = sc; kr = 0.02 + wet*0.10; ks = 0.15 + wet*0.6;\n                    tint = vec3(0.8, 0.9, 1.0);\n                } else {\n                    // polished veined marble, cracked\n                    float vv = smoothstep(0.34, 0.66, fbm(p.xz*1.7 + vec2(fbm(p.xz*0.6)*2.4)));\n                    vec3 cA = mix(vec3(0.20, 0.11, 0.11), vec3(0.10, 0.05, 0.06), vv);\n                    vec3 cB = mix(vec3(0.93, 0.89, 0.82), vec3(0.74, 0.68, 0.60), vv);\n                    alb = mix(cA, cB, mod(floor(p.x) + floor(p.z), 2.0));\n                    float far = clamp(t*0.010 - 0.12, 0.0, 1.0);\n                    alb = mix(alb, 0.5*(cA + cB), far);\n                    kr = 0.34; ks = 1.7; tint = vec3(0.98, 0.96, 0.94);\n                    float k1 = 1.0 - smoothstep(0.0, 0.013, abs(fbm(p.xz*0.85 + 11.0) - 0.5));\n                    float k2 = 1.0 - smoothstep(0.0, 0.009, abs(fbm(p.xz*2.30 - 4.0) - 0.5));\n                    float ck = clamp(max(k1, k2*0.7)*(1.0 - far), 0.0, 1.0);\n                    alb = mix(alb, vec3(0.07, 0.05, 0.05), ck*0.72);\n                    kr *= 1.0 - ck*0.92; ks *= 1.0 - ck*0.8;\n                }\n            } else if (id < 1.5){\n                alb = vec3(0.02); kr = 0.88; tint = vec3(0.95, 0.97, 1.0); ks = 1.8;\n            } else if (id < 5.5){\n                // fluted column shaft\n                float a2 = atan(n.z, n.x);\n                float fl = mix(1.0, 0.70 + 0.30*abs(sin(a2*10.0)), clamp(1.0 - abs(n.y)*1.6, 0.0, 1.0));\n                alb = vec3(0.92, 0.90, 0.86)*fl*(0.88 + 0.12*vnoise(vec2(a2*2.5, p.y*3.0)));\n                kr = 0.10; ks = 1.1;\n            } else if (id < 6.5){\n                alb = vec3(0.93, 0.91, 0.87)*(0.88 + vnoise(p.xz*2.2 + p.y*1.8)*0.16);\n                kr = 0.10; ks = 1.1;\n            } else if (id < 7.5){\n                // yellowed beige plastic with moulded vents\n                alb = mix(vec3(0.80, 0.76, 0.63), vec3(0.66, 0.59, 0.44), vnoise(p.xz*3.5 + p.y*2.5));\n                alb *= 0.86 + 0.14*step(0.35, fract(p.y*30.0));\n                kr = 0.04; ks = 0.65;\n            } else if (id < 8.5){\n                // the glass: screen-local uv, then whatever it's running\n                vec3 dl = (p - gScrC)/max(gScrS, vec3(1e-4));\n                vec2 uv = clamp(((gScrAxis < 0.5) ? dl.xy : dl.zy)*0.5 + 0.5, 0.0, 1.0);\n                vec3 art = screenArt(uv, gScrSeed);\n                vec2 cq = uv*2.0 - 1.0;\n                alb = art*0.04;\n                emis = art*(0.78 + 0.22*sin(uv.y*190.0))\n                     * (0.94 + 0.06*sin(gT*13.0 + gScrSeed*31.0))\n                     * smoothstep(2.1, 0.6, dot(cq, cq))*uScreens;\n                kr = 0.10; ks = 1.4; tint = vec3(0.80, 0.86, 1.0);\n            } else if (id < 9.5){\n                // keyboard: per-key grid on the top face only\n                if (n.y > 0.5){\n                    vec2 kk = fract(vec2(p.x*11.0, p.z*11.0)) - 0.5;\n                    alb = mix(vec3(0.42, 0.40, 0.36),\n                              vec3(0.78, 0.75, 0.66)*(0.92 + 0.08*h21(floor(vec2(p.x, p.z)*11.0))),\n                              step(max(abs(kk.x), abs(kk.y)), 0.36));\n                } else alb = vec3(0.72, 0.68, 0.57);\n                kr = 0.03; ks = 0.5;\n            } else if (id < 12.5 && id > 11.5){\n                // beach ball: six vertical wedges in primary colours\n                float wa = atan(n.z, n.x)/TAU + 0.5;\n                float wi = floor(fract(wa)*6.0);\n                vec3 wc = (wi < 1.0) ? vec3(0.92, 0.18, 0.16)\n                        : (wi < 2.0) ? vec3(0.97, 0.94, 0.90)\n                        : (wi < 3.0) ? vec3(0.14, 0.40, 0.85)\n                        : (wi < 4.0) ? vec3(0.97, 0.94, 0.90)\n                        : (wi < 5.0) ? vec3(0.98, 0.78, 0.12)\n                                     : vec3(0.97, 0.94, 0.90);\n                alb = mix(wc, vec3(0.97, 0.95, 0.92), smoothstep(0.72, 0.97, abs(n.y)));\n                kr = 0.10; ks = 1.5;\n            } else if (id < 10.5){\n                // eyeball, pupil aimed at the courtyard\n                float d = dot(n, normalize(vec3(0.0, 1.0, 0.0) - p + vec3(1e-3)));\n                alb = mix(vec3(0.95, 0.93, 0.91), vec3(0.72, 0.10, 0.08),\n                          smoothstep(0.52, 0.92, fbm(n.xy*8.0 + n.z*4.0))*0.55);\n                alb = mix(alb, vec3(0.16, 0.46, 0.62), smoothstep(0.70, 0.85, d));\n                alb = mix(alb, vec3(0.02, 0.02, 0.03), smoothstep(0.90, 0.955, d));\n                kr = 0.12; ks = 2.6;\n            } else {\n                alb = vec3(0.15, 0.18, 0.23)*(0.80 + 0.35*max(n.y, 0.0));   // shark\n                kr = 0.12; ks = 1.2; tint = vec3(0.8, 0.9, 1.0);\n            }\n            kr *= gs;\n            vec3 SUN = hueShift(vec3(1.05, 0.74, 0.42), uSkyHue);\n            vec3 AMB = hueShift(vec3(0.16, 0.20, 0.34), uSkyHue);\n            col += att*(alb*(AMB*0.55 + SUN*1.15*dif)*(1.0 - kr) + SUN*spec*ks + emis);\n            att *= kr*tint;\n            ro = p + n*0.002; rd = rr;\n        }\n        if (max(att.x, max(att.y, att.z)) < 0.02) break;\n    }\n    return col;\n}\n\nvoid main(){\n    vec2 R = RENDERSIZE.xy;\n    vec2 pc = gl_FragCoord.xy;\n    gT = TIME + 11.0;\n    LD = normalize(vec3(-0.62, 0.27, -0.44));\n\n    float ang = 0.55 + gT*0.22*uSpeed;\n    vec2 uv = (2.0*pc - R)/R.y;\n    vec3 cp = vec3(sin(ang)*11.9, uCamHt + 0.45*sin(ang*0.6), cos(ang)*11.9);\n    vec3 fw = normalize(vec3(0.0, 1.0, 0.0) - cp);\n    vec3 rt = normalize(cross(fw, vec3(0.0, 1.0, 0.0)));\n    vec3 col = trace(cp, normalize(fw*uFOV + rt*uv.x + cross(rt, fw)*uv.y));\n\n    col = pow(clamp(col, 0.0, 1.0), vec3(0.4545));\n    float L = max(2.0, floor(uPalette + 0.5));\n    col = floor(col*(L - 1.0) + 0.5 + (bayer(pc) - 0.5)*uDither)/(L - 1.0);\n    col *= 1.0 - uCRT*0.4*(0.5 + 0.5*sin(pc.y*3.14159));\n    vec2 q = pc/R;\n    col *= mix(1.0, pow(16.0*q.x*q.y*(1.0 - q.x)*(1.0 - q.y), 0.35), uVignette);\n    gl_FragColor = vec4(col, 1.0);\n}\n",
    "generator": {
      "model": "claude-opus-5",
      "provider": null,
      "prompt": null,
      "params": null
    }
  }
}