{
  "license": "CC0-1.0",
  "shader": {
    "id": "de93r21k",
    "title": "Clifford Cage",
    "license": "CC0-1.0",
    "provenance_type": "witnessed_generation",
    "made_with": "glslop",
    "status": "active",
    "compile_ok": true,
    "tags": [
      "4d",
      "polytope",
      "wireframe",
      "neon",
      "geometry"
    ],
    "parents": [],
    "author": "zazi5inxhmgi",
    "author_name": "ufffd",
    "author_url": "/u/ufffd",
    "created_at": "2026-06-18T16:48:33.333Z",
    "poster_url": "/posters/de93r21k.avif",
    "stats": {
      "slops": 0,
      "views": 108,
      "forks": 0
    },
    "self": "/api/v1/shaders/de93r21k",
    "isf": "/*{\n  \"DESCRIPTION\": \"Clifford Cage: the 24-cell — a regular 4-dimensional polytope with no 3D analog — drawn as a glowing wireframe. It tumbles by a true isoclinic (Clifford) double-rotation in 4-space and is perspective-projected to 3D, so edges swell and shrink as they swing toward and away through the 4th dimension. The rotation returns to start after one turn: a seamless 16s loop.\",\n  \"CREDIT\": \"glslop agent (Claude)\",\n  \"CATEGORIES\": [\"4D\", \"polytope\", \"wireframe\", \"neon\", \"geometry\"],\n  \"INPUTS\": [\n    { \"NAME\": \"speed\", \"TYPE\": \"float\", \"DEFAULT\": 1.0,  \"MIN\": 0.0,  \"MAX\": 3.0 },\n    { \"NAME\": \"glow\",  \"TYPE\": \"float\", \"DEFAULT\": 1.0,  \"MIN\": 0.3,  \"MAX\": 3.0 },\n    { \"NAME\": \"hue\",   \"TYPE\": \"float\", \"DEFAULT\": 0.0,  \"MIN\": 0.0,  \"MAX\": 1.0 },\n    { \"NAME\": \"tube\",  \"TYPE\": \"float\", \"DEFAULT\": 0.04, \"MIN\": 0.012,\"MAX\": 0.1  },\n    { \"NAME\": \"zoom\",  \"TYPE\": \"float\", \"DEFAULT\": 1.0,  \"MIN\": 0.5,  \"MAX\": 2.0 }\n  ]\n}*/\n\n#define PI  3.14159265359\n#define TAU 6.28318530718\n#define NV  24\n\nconst float PERIOD = 16.0;\n\nmat2 rot(float a){ float c = cos(a), s = sin(a); return mat2(c, -s, s, c); }\n\nvec3 pal(float t){\n  return 0.5 + 0.5 * cos(TAU * (t + vec3(0.0, 0.33, 0.66)));\n}\n\n// the 24 vertices of the 24-cell: all permutations of (+-1,+-1,0,0)\nvec4 vert24(int k){\n  int pp = k / 4;\n  int ss = k - pp * 4;\n  float s0 = mod(float(ss), 2.0) * 2.0 - 1.0;\n  float s1 = floor(float(ss) / 2.0) * 2.0 - 1.0;\n  if (pp == 0) return vec4(s0, s1, 0.0, 0.0);\n  if (pp == 1) return vec4(s0, 0.0, s1, 0.0);\n  if (pp == 2) return vec4(s0, 0.0, 0.0, s1);\n  if (pp == 3) return vec4(0.0, s0, s1, 0.0);\n  if (pp == 4) return vec4(0.0, s0, 0.0, s1);\n  return vec4(0.0, 0.0, s0, s1);\n}\n\n// min distance from ray (ro,rd unit) to segment [A,B]; returns dist, writes t along ray\nfloat segDist(vec3 ro, vec3 rd, vec3 A, vec3 B, out float tray){\n  vec3 d2 = B - A;\n  vec3 r  = ro - A;\n  float e = dot(d2, d2);\n  float f = dot(d2, r);\n  float b = dot(rd, d2);\n  float c = dot(rd, r);\n  float den = e - b * b;                       // a=dot(rd,rd)=1\n  float s = (den > 1e-5) ? (b * f - c * e) / den : 0.0;\n  s = max(s, 0.0);\n  float u = clamp((b * s + f) / e, 0.0, 1.0);\n  s = max(dot(A + d2 * u - ro, rd), 0.0);\n  tray = s;\n  vec3 pr = ro + rd * s;\n  vec3 ps = A + d2 * u;\n  return length(pr - ps);\n}\n\nvoid main(){\n  vec2 uv = (gl_FragCoord.xy - 0.5 * RENDERSIZE.xy) / RENDERSIZE.y;\n\n  float ph = fract(TIME * speed / PERIOD);\n  float th = TAU * ph;\n\n  // ---- build & transform the 24 vertices (rotate in 4D, project to 3D) ----\n  vec4  base[NV];\n  vec3  proj[NV];\n  float rotw[NV];\n  for (int k = 0; k < NV; k++){\n    vec4 v = vert24(k);\n    base[k] = v;\n    // fixed tilt that mixes all four axes so the isoclinic spin is legible\n    v.xz = rot(0.62) * v.xz;\n    v.yw = rot(1.13) * v.yw;\n    // isoclinic (Clifford) rotation: xy and zw turn by the SAME angle\n    v.xy = rot(th) * v.xy;\n    v.zw = rot(th) * v.zw;\n    rotw[k] = v.w;                              // 4th-dim depth -> drives colour\n    proj[k] = v.xyz / (2.6 - v.w);             // 4D perspective projection\n  }\n\n  // ---- camera ----\n  vec3 ro = vec3(0.0, 0.0, 3.4 / zoom);\n  vec3 ta = vec3(0.0);\n  vec3 ww = normalize(ta - ro);\n  vec3 uu = normalize(cross(vec3(0.0, 1.0, 0.0), ww));\n  vec3 vv = cross(ww, uu);\n  vec3 rd = normalize(uv.x * uu + uv.y * vv + 1.6 * ww);\n\n  // ---- draw edges: pairs at 4D squared-distance 2 are connected ----\n  float w0 = tube * tube;\n  vec3 col = vec3(0.0);\n  for (int i = 0; i < NV; i++){\n    for (int j = 0; j < NV; j++){\n      if (j <= i) continue;\n      vec4 dv = base[i] - base[j];\n      if (abs(dot(dv, dv) - 2.0) > 0.05) continue;   // not an edge\n      float tray;\n      float d = segDist(ro, rd, proj[i], proj[j], tray);\n      float g = w0 / (d * d + w0);\n      g = g * g;                                       // thin bright cores\n      float fog = exp(-0.22 * max(tray - 2.0, 0.0));   // depth cue\n      float wMid = 0.5 * (rotw[i] + rotw[j]);          // 4D depth of this edge\n      col += pal(hue + ph + 0.30 * wMid) * g * fog * 0.9;\n    }\n  }\n\n  col *= glow;\n  col += vec3(0.85, 0.92, 1.0) * pow(max(max(col.r, col.g), col.b) * 0.45, 3.0);\n\n  col = col / (1.0 + col);\n  col = pow(col, vec3(0.82));\n  col *= 1.0 - 0.16 * dot(uv, uv);\n\n  gl_FragColor = vec4(col, 1.0);\n}\n",
    "generator": {
      "model": "claude-opus-4-8",
      "provider": null,
      "prompt": null,
      "params": null
    }
  }
}