{
  "license": "CC0-1.0",
  "shader": {
    "id": "8dmk070r",
    "title": "Aurora",
    "license": "CC0-1.0",
    "provenance_type": "witnessed_generation",
    "made_with": "claude-code",
    "status": "active",
    "compile_ok": true,
    "tags": [
      "aurora",
      "sky",
      "noise",
      "atmosphere",
      "stars"
    ],
    "parents": [],
    "author": "zazi5inxhmgi",
    "author_name": "ufffd",
    "author_url": "/u/ufffd",
    "created_at": "2026-06-20T05:32:18.957Z",
    "poster_url": "/posters/8dmk070r.avif",
    "stats": {
      "slops": 0,
      "views": 117,
      "forks": 2
    },
    "self": "/api/v1/shaders/8dmk070r",
    "isf": "/*{\n  \"DESCRIPTION\": \"Aurora over a mountain range, mirrored in a still rippling lake under a field of stars.\",\n  \"CREDIT\": \"claude-opus-4-8\",\n  \"INPUTS\": [\n    { \"NAME\": \"speed\",     \"TYPE\": \"float\", \"DEFAULT\": 0.5, \"MIN\": 0.0, \"MAX\": 2.0 },\n    { \"NAME\": \"bands\",     \"TYPE\": \"float\", \"DEFAULT\": 5.0, \"MIN\": 2.0, \"MAX\": 9.0 },\n    { \"NAME\": \"intensity\", \"TYPE\": \"float\", \"DEFAULT\": 0.8, \"MIN\": 0.2, \"MAX\": 1.6 },\n    { \"NAME\": \"hue\",       \"TYPE\": \"float\", \"DEFAULT\": 0.4, \"MIN\": 0.0, \"MAX\": 1.0 }\n  ]\n}*/\n\nconst float HY = 0.46;   // horizon height (uv.y)\n\nfloat hash(vec2 p){ p = fract(p * vec2(123.34, 456.21)); p += dot(p, p + 45.32); return fract(p.x * p.y); }\nfloat noise(vec2 p){\n  vec2 i = floor(p), f = fract(p); f = f * f * (3.0 - 2.0 * f);\n  float a = hash(i), b = hash(i + vec2(1.0, 0.0)), c = hash(i + vec2(0.0, 1.0)), d = hash(i + vec2(1.0, 1.0));\n  return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);\n}\nfloat fbm(vec2 p){ float s = 0.0, a = 0.5; for (int i = 0; i < 4; i++){ s += a * noise(p); p = p * 2.0 + 3.0; a *= 0.5; } return s; }\nvec3 palette(float t){ return 0.5 + 0.5 * cos(6.28318 * (t + vec3(0.0, 0.33, 0.67) + hue)); }\n\n// mountain top height above the horizon for column x (two stacked ridges)\nfloat ridge(float x){\n  float far  = 0.06 + 0.05 * fbm(vec2(x * 2.2 + 11.0, 0.0));\n  float near = 0.02 + 0.11 * fbm(vec2(x * 1.4 - 5.0, 7.0));\n  return max(far, near);\n}\n\nvec3 auroraCol(float x, float y, float t){\n  vec3 c = vec3(0.0);\n  for (int i = 0; i < 9; i++){\n    if (float(i) >= bands) break;\n    float fi = float(i);\n    float yC = 0.64 + 0.07 * fi;\n    float wob = 0.10 * noise(vec2(x * 1.5 + fi, t * 0.5 + fi * 3.0)) + 0.04 * sin(x * 3.0 + t + fi);\n    float d = abs(y - (yC + wob));\n    float curt = exp(-d * 15.0);\n    curt *= 0.55 + 0.45 * noise(vec2(x * 22.0, t + fi * 5.0));   // vertical streaks\n    c += curt * palette(0.12 * fi + 0.3 + 0.1 * x) * intensity;\n  }\n  return c * smoothstep(HY - 0.02, HY + 0.12, y);\n}\n\n// the scene above the horizon (sky + stars + aurora + mountains) at coordinate (x, y)\nvec3 sceneAbove(vec2 q, float t){\n  float x = q.x, y = q.y;\n  vec3 col = mix(vec3(0.03, 0.04, 0.10), vec3(0.0, 0.0, 0.015), clamp((y - 0.4) / 0.6, 0.0, 1.0));\n  // stars (upper sky)\n  vec2 g = floor(vec2(x, y) * 130.0);\n  float h = hash(g);\n  col += smoothstep(0.986, 1.0, h) * (0.6 + 0.4 * sin(t * 3.0 + h * 40.0)) * smoothstep(0.5, 0.75, y);\n  // aurora\n  col += auroraCol(x, y, t);\n  // mountains (solid below the ridge outline)\n  float top = HY + ridge(x);\n  if (y < top){\n    float k = top - y;                                   // depth into the mountain body\n    vec3 mnt = mix(vec3(0.05, 0.06, 0.11), vec3(0.01, 0.01, 0.03), smoothstep(0.0, 0.16, k));\n    mnt += auroraCol(x, top, t) * 0.35 * exp(-k * 26.0); // aurora rim-light on the peaks\n    col = mnt;\n  }\n  return col;\n}\n\nvoid main(){\n  vec2 uv = gl_FragCoord.xy / RENDERSIZE;\n  float asp = RENDERSIZE.x / RENDERSIZE.y;\n  float x = (uv.x - 0.5) * asp;\n  float t = TIME * speed;\n\n  vec3 col;\n  if (uv.y >= HY){\n    col = sceneAbove(vec2(x, uv.y), t);\n  } else {\n    // lake: mirror the scene across the horizon with ripple distortion\n    float depth = HY - uv.y;                              // 0 at shore -> grows downward\n    float ripple = 0.010 * sin(uv.y * 55.0 - t * 2.0) * (0.3 + depth * 1.5);\n    ripple += 0.006 * (fbm(vec2(x * 7.0, uv.y * 18.0 - t)) - 0.5);\n    vec2 rc = vec2(x + ripple, 2.0 * HY - uv.y + ripple * 0.4);\n    vec3 refl = sceneAbove(rc, t);\n    refl *= vec3(0.62, 0.72, 0.92);                       // water tint\n    refl = mix(refl, vec3(0.0, 0.02, 0.05), smoothstep(0.0, HY, depth) * 0.55);  // fade with depth\n    float spark = pow(max(0.0, fbm(vec2(x * 26.0, uv.y * 26.0 - t * 3.0)) - 0.55), 2.0);\n    refl += spark * 0.5 * vec3(0.7, 0.9, 1.0);            // specular glints\n    col = refl;\n  }\n\n  col *= 1.0 - 0.25 * dot(uv - 0.5, uv - 0.5);            // vignette\n  col = pow(max(col, 0.0), vec3(0.9));\n  gl_FragColor = vec4(col, 1.0);\n}\n",
    "generator": {
      "model": "claude-opus-4-8",
      "provider": "anthropic",
      "prompt": null,
      "params": null
    }
  }
}