{
  "license": "CC0-1.0",
  "shader": {
    "id": "0gyvybtr",
    "title": "Glass square-tube tunnel",
    "license": "CC0-1.0",
    "provenance_type": "user_upload",
    "made_with": "glslop",
    "status": "active",
    "compile_ok": true,
    "render_hash": "3c1c99d3e3831c3c",
    "tags": [
      "3D",
      "Raymarching"
    ],
    "parents": [],
    "author": "jab6zg50vals",
    "author_name": "ogcraig",
    "author_url": "/u/ogcraig",
    "created_at": "2026-07-23T13:01:09.807Z",
    "poster_url": "/posters/0gyvybtr.avif",
    "stats": {
      "slops": 1,
      "views": 347,
      "forks": 0
    },
    "self": "/api/v1/shaders/0gyvybtr",
    "isf": "/*{\n  \"DESCRIPTION\": \"Glass square-tube tunnel v5 — Lattice Edition\",\n  \"CREDIT\": \"Craig\",\n  \"CATEGORIES\": [\"generator\"],\n  \"INPUTS\": [\n    { \"NAME\": \"speed\",      \"TYPE\": \"float\", \"DEFAULT\": 0.20, \"MIN\": 0.0,  \"MAX\": 2.0 },\n    { \"NAME\": \"yawAmt\",     \"TYPE\": \"float\", \"DEFAULT\": 0.5,  \"MIN\": 0.0,  \"MAX\": 1.0 },\n    { \"NAME\": \"pitchAmt\",   \"TYPE\": \"float\", \"DEFAULT\": 0.5,  \"MIN\": 0.0,  \"MAX\": 1.0 },\n    { \"NAME\": \"ringZ\",      \"TYPE\": \"float\", \"DEFAULT\": 1.15, \"MIN\": 0.5,  \"MAX\": 3.0 },\n    { \"NAME\": \"wallR\",      \"TYPE\": \"float\", \"DEFAULT\": 1.22, \"MIN\": 0.6,  \"MAX\": 1.30 },\n    { \"NAME\": \"paneT\",      \"TYPE\": \"float\", \"DEFAULT\": 0.035,\"MIN\": 0.005,\"MAX\": 0.15 },\n    { \"NAME\": \"cellSize\",   \"TYPE\": \"float\", \"DEFAULT\": 2.70, \"MIN\": 2.60, \"MAX\": 6.0 },\n    { \"NAME\": \"stepDR\",     \"TYPE\": \"float\", \"DEFAULT\": 0.13, \"MIN\": 0.02, \"MAX\": 0.30 },\n    { \"NAME\": \"stepDW\",     \"TYPE\": \"float\", \"DEFAULT\": 0.075,\"MIN\": 0.0,  \"MAX\": 0.20 },\n    { \"NAME\": \"barW\",       \"TYPE\": \"float\", \"DEFAULT\": 0.36, \"MIN\": 0.10, \"MAX\": 0.60 },\n    { \"NAME\": \"barT\",       \"TYPE\": \"float\", \"DEFAULT\": 0.085,\"MIN\": 0.02, \"MAX\": 0.25 },\n    { \"NAME\": \"chamfer\",    \"TYPE\": \"float\", \"DEFAULT\": 0.06, \"MIN\": 0.0,  \"MAX\": 0.20 },\n    { \"NAME\": \"colRadius\",  \"TYPE\": \"float\", \"DEFAULT\": 0.28, \"MIN\": 0.05, \"MAX\": 0.60 },\n    { \"NAME\": \"colPos\",     \"TYPE\": \"float\", \"DEFAULT\": 0.95, \"MIN\": 0.40, \"MAX\": 1.40 },\n    { \"NAME\": \"focal\",      \"TYPE\": \"float\", \"DEFAULT\": 1.05, \"MIN\": 0.40, \"MAX\": 2.50 },\n    { \"NAME\": \"fish\",       \"TYPE\": \"float\", \"DEFAULT\": 0.22, \"MIN\": 0.0,  \"MAX\": 0.80 },\n    { \"NAME\": \"bounces\",    \"TYPE\": \"float\", \"DEFAULT\": 7.0,  \"MIN\": 1.0,  \"MAX\": 12.0 },\n    { \"NAME\": \"hueShift\",   \"TYPE\": \"float\", \"DEFAULT\": 0.0,  \"MIN\": 0.0,  \"MAX\": 1.0 },\n    { \"NAME\": \"saturation\", \"TYPE\": \"float\", \"DEFAULT\": 1.0,  \"MIN\": 0.0,  \"MAX\": 2.0 },\n    { \"NAME\": \"exposure\",   \"TYPE\": \"float\", \"DEFAULT\": 1.7,  \"MIN\": 0.2,  \"MAX\": 5.0 },\n    { \"NAME\": \"vignette\",   \"TYPE\": \"float\", \"DEFAULT\": 0.45, \"MIN\": 0.0,  \"MAX\": 1.0 },\n    { \"NAME\": \"gamma\",      \"TYPE\": \"float\", \"DEFAULT\": 1.15, \"MIN\": 0.5,  \"MAX\": 2.2 }\n  ]\n}*/\n\n#define STEPS 4.\n#define MOUSE_SENS_X 6.2831853\n#define MOUSE_SENS_Y 3.0\n\nvec3 gColor;\nvec3 gId;\nvec2 gCellId;\nfloat gMatid;   // 0 = colored pane, 1 = terraced frame, 2 = corner column\n\nmat2 rot(float a){ return mat2(cos(a),-sin(a),sin(a),cos(a)); }\n\n// chamfered box in 2D\nfloat cham(vec2 p, vec2 b){\n    vec2 a = abs(p) - b;\n    return max(max(a.x, a.y), (a.x + a.y)*0.7071 + chamfer);\n}\n\nfloat de(vec3 z){\n    float CELL = max(cellSize, 2.0*wallR + 0.10);\n\n    // 2D lattice: every cell is a parallel tunnel along z\n    vec2 xy = mod(z.xy + CELL*0.5, CELL) - CELL*0.5;\n    gCellId = floor((z.xy + CELL*0.5)/CELL);\n    float q  = max(abs(xy.x), abs(xy.y));\n    float zc = mod(z.z, ringZ) - ringZ*0.5;\n    gId = vec3(gCellId, floor(z.z/ringZ));\n\n    // terraced ring frame: ziggurat of chamfered frames\n    float ring = 1e9;\n    for (float k = 0.; k < STEPS; k++){\n        float rr = wallR - barT - k*stepDR;\n        float ww = barW - k*stepDW;\n        ring = min(ring, cham(vec2(q - rr, zc), vec2(barT, ww)));\n    }\n\n    // thin accent ring halfway between the big frames\n    float zc2 = mod(z.z + ringZ*0.5, ringZ) - ringZ*0.5;\n    float ring2 = cham(vec2(q - (wallR - 0.16), zc2), vec2(0.05, 0.06));\n    ring = min(ring, ring2);\n\n    // scalloped corner crystal columns\n    vec2 cq = abs(xy) - vec2(colPos);\n    float ang = atan(cq.y, cq.x);\n    float col = length(cq) - colRadius\n              - 0.07*cos(zc/ringZ*6.2831)\n              * (0.6 + 0.4*cos(ang*8.));\n\n    // thin colored pane facing each bore\n    float pane = abs(q - wallR) - paneT;\n\n    float d = min(min(ring, col), pane);\n    gMatid = d == pane ? 0. : (d == ring ? 1. : 2.);\n    return d;\n}\n\nvec3 abnormal(vec3 p){\n    vec2 dx = vec2(1.0,-1.0);\n    vec2 dp = 0.004*dx;\n    return normalize(\n          dx.xyy*de(p+dp.xyy)\n        + dx.yyx*de(p+dp.yyx)\n        + dx.yxy*de(p+dp.yxy)\n        + dx.xxx*de(p+dp.xxx)\n    );\n}\n\nvec3 hueRotate(vec3 c, float h){\n    float a = h*6.2831853;\n    float s = sin(a), co = cos(a);\n    mat3 m = mat3(\n        0.299+0.701*co+0.168*s, 0.587-0.587*co+0.330*s, 0.114-0.114*co-0.497*s,\n        0.299-0.299*co-0.328*s, 0.587+0.413*co+0.035*s, 0.114-0.114*co+0.292*s,\n        0.299-0.300*co+1.250*s, 0.587-0.588*co-1.050*s, 0.114+0.886*co-0.203*s\n    );\n    return clamp(c*m, 0.0, 4.0);\n}\n\n// discrete candy palette\nvec3 candy(float sel){\n    sel = mod(sel, 5.);\n    if (sel < 1.) return vec3(1.0, 0.08, 0.85);\n    if (sel < 2.) return vec3(1.0, 0.85, 0.05);\n    if (sel < 3.) return vec3(0.05, 0.85, 1.0);\n    if (sel < 4.) return vec3(0.45, 1.0, 0.12);\n    return vec3(0.55, 0.12, 1.0);\n}\n\nvec3 facet_color(vec3 p, float m){\n    float CELL = max(cellSize, 2.0*wallR + 0.10);\n    vec2 xy = mod(p.xy + CELL*0.5, CELL) - CELL*0.5;\n    float wall = abs(xy.x) > abs(xy.y) ? (xy.x > 0. ? 0. : 2.) : (xy.y > 0. ? 1. : 3.);\n    float h = fract(sin(dot(vec3(wall, gId.z, dot(gId.xy, vec2(13.1, 7.7))),\n                            vec3(12.9898, 78.233, 37.719)))*43758.5453);\n    vec3 pal = candy(floor(h*5.));\n    pal = hueRotate(pal, hueShift);\n    float lum = dot(pal, vec3(0.299,0.587,0.114));\n    pal = mix(vec3(lum), pal, saturation);\n    if (m > 0.5) pal = mix(pal, vec3(1.0), 0.7)*0.55;\n    if (m > 1.5) pal = vec3(0.28,0.22,0.38);\n    return pal;\n}\n\nvoid march(vec3 ro_, vec3 rd){\n    vec3 p, n, tp = vec3(1.0);\n    vec3 ld = normalize(vec3(0.35,0.55,-0.75));\n    float t = 0., numRF = 0.;\n    for(int i = 0; i < 160; i++){\n        p = ro_ + rd*t;\n        float d = de(p);\n        if (d < 0.0004){\n            float m = gMatid;\n            n = abnormal(p);\n            vec3 pal = facet_color(p, m);\n            float ndr  = abs(dot(n,rd));\n            float fres = pow(1.0-ndr, 3.0);\n            float diff = 0.35 + 0.65*max(0.0, dot(n, ld));\n            vec3  hlf  = normalize(ld - rd);\n            float spec = pow(max(0.0, dot(n, hlf)), 32.0);\n            vec3 sheen = 0.5 + 0.5*cos(14.0*ndr + vec3(0.0, 2.1, 4.2));\n\n            if (m < 0.5){\n                gColor += tp * pal * (0.70 + 0.55*fres);\n                tp *= pal*0.85;\n                if (numRF > bounces || max(tp.x,max(tp.y,tp.z)) < 0.02) break;\n                ro_ = p + rd*0.09;\n                t = 0.0; numRF++; continue;\n            } else if (m < 1.5){\n                gColor += tp * (pal*diff*0.20 + spec*1.8 + fres*(sheen*0.7+0.15));\n            } else {\n                gColor += tp * (pal*diff*0.35 + spec*2.0 + fres*sheen*0.5);\n            }\n\n            if (numRF > bounces || max(tp.x,max(tp.y,tp.z)) < 0.02) break;\n            tp *= mix(pal, vec3(1.0), 0.4)*0.5;\n            rd  = reflect(rd, n);\n            ro_ = p + n*0.003;\n            t   = 0.01;\n            numRF++;\n            continue;\n        }\n        t += d*0.9;\n        if (t > 40.0) break;\n    }\n    gColor += tp * vec3(0.75,0.78,0.8) * smoothstep(6.0, 40.0, t) * 0.5;\n}\n\nvoid main(){\n    vec2 p = (2.0*gl_FragCoord.xy - RENDERSIZE.xy)/RENDERSIZE.y;\n\n    gColor = vec3(0.0);\n\n    float yaw   = (yawAmt   - 0.5) * MOUSE_SENS_X;\n    float pitch = clamp((pitchAmt - 0.5) * MOUSE_SENS_Y, -1.5, 1.5);\n\n    vec3 ro = vec3(0.0, 0.0, TIME * speed);\n    vec3 fwd = vec3( sin(yaw)*cos(pitch), sin(pitch), cos(yaw)*cos(pitch) );\n    vec3 rgt = normalize(cross(vec3(0.0,1.0,0.0), fwd));\n    vec3 up  = cross(fwd, rgt);\n\n    vec3 rd = normalize( p.x*rgt + p.y*up + (focal - fish*dot(p,p))*fwd );\n\n    march(ro, rd);\n\n    vec3 c = 1.0 - exp(-exposure*gColor);\n    c *= 1.0 - vignette*smoothstep(0.55, 1.35, length(p));\n    c = pow(c, vec3(gamma));\n    gl_FragColor = vec4(c, 1.0);\n}"
  }
}