{
  "license": "CC0-1.0",
  "shader": {
    "id": "o0m8aryj",
    "title": "Liquid Aurora",
    "license": "CC0-1.0",
    "provenance_type": "user_upload",
    "made_with": "glslop",
    "status": "active",
    "compile_ok": true,
    "tags": [
      "aurora",
      "nebula",
      "domain-warp",
      "fbm",
      "iridescent",
      "abstract"
    ],
    "parents": [],
    "author": "zazi5inxhmgi",
    "author_name": "ufffd",
    "author_url": "/u/ufffd",
    "created_at": "2026-06-16T16:08:08.533Z",
    "poster_url": "/posters/o0m8aryj.avif",
    "stats": {
      "slops": 1,
      "views": 143,
      "forks": 0
    },
    "self": "/api/v1/shaders/o0m8aryj",
    "isf": "/*{\n  \"DESCRIPTION\": \"Liquid Aurora — domain-warped fractal flow field with iridescent, glassy color. A slow-breathing curtain of light that folds over itself.\",\n  \"CREDIT\": \"made with glslop\",\n  \"CATEGORIES\": [\"abstract\", \"noise\", \"color\"],\n  \"INPUTS\": [\n    { \"NAME\": \"speed\",     \"TYPE\": \"float\", \"DEFAULT\": 1.0,  \"MIN\": 0.0, \"MAX\": 3.0 },\n    { \"NAME\": \"warp\",      \"TYPE\": \"float\", \"DEFAULT\": 1.0,  \"MIN\": 0.0, \"MAX\": 2.5 },\n    { \"NAME\": \"zoom\",      \"TYPE\": \"float\", \"DEFAULT\": 1.6,  \"MIN\": 0.5, \"MAX\": 4.0 },\n    { \"NAME\": \"glow\",      \"TYPE\": \"float\", \"DEFAULT\": 1.0,  \"MIN\": 0.0, \"MAX\": 2.0 },\n    { \"NAME\": \"hueShift\",  \"TYPE\": \"float\", \"DEFAULT\": 0.0,  \"MIN\": 0.0, \"MAX\": 1.0 }\n  ]\n}*/\n\n// ---- value noise (cheap, ES 1.00 friendly) ---------------------------------\nfloat hash(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}\n\nfloat vnoise(vec2 p){\n  vec2 i = floor(p);\n  vec2 f = fract(p);\n  f = f * f * (3.0 - 2.0 * f);          // smoothstep interpolation\n  float a = hash(i + vec2(0.0, 0.0));\n  float b = hash(i + vec2(1.0, 0.0));\n  float c = hash(i + vec2(0.0, 1.0));\n  float d = hash(i + vec2(1.0, 1.0));\n  return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);\n}\n\n// fractal brownian motion, 5 octaves (constant loop bound for ES 1.00)\nfloat fbm(vec2 p){\n  float sum = 0.0;\n  float amp = 0.55;\n  mat2 rot = mat2(0.80, 0.60, -0.60, 0.80);   // rotate each octave to break grid\n  for (int i = 0; i < 5; i++){\n    sum += amp * vnoise(p);\n    p = rot * p * 2.02 + 7.13;\n    amp *= 0.5;\n  }\n  return sum;\n}\n\n// smooth iridescent palette (Inigo Quilez cosine palette) — teal/violet/gold aurora\nvec3 palette(float t){\n  vec3 a = vec3(0.50, 0.45, 0.50);\n  vec3 b = vec3(0.55, 0.50, 0.55);\n  vec3 c = vec3(1.0, 1.0, 1.0);\n  vec3 d = vec3(0.10, 0.55, 0.85);\n  return a + b * cos(6.28318 * (c * t + d));\n}\n\nvoid main(){\n  vec2 uv = isf_FragNormCoord;                 // 0..1\n  vec2 p = (uv - 0.5);\n  p.x *= RENDERSIZE.x / RENDERSIZE.y;          // aspect-correct\n  p *= zoom;\n\n  float t = TIME * 0.18 * speed;\n\n  // ---- domain warp: feed noise back into itself twice ----------------------\n  vec2 q = vec2(\n    fbm(p + vec2(0.0, 0.0) + t),\n    fbm(p + vec2(5.2, 1.3) - t * 0.7)\n  );\n\n  vec2 r = vec2(\n    fbm(p + warp * q + vec2(1.7, 9.2) + 0.15 * t),\n    fbm(p + warp * q + vec2(8.3, 2.8) - 0.12 * t)\n  );\n\n  float f = fbm(p + warp * r);\n  // fbm sits roughly in [0.2, 0.8]; remap to use the full 0..1 range for contrast\n  f = clamp((f - 0.22) / 0.56, 0.0, 1.0);\n\n  // ---- color: layer hue by warp depth + flow, add depth via q,r magnitudes -\n  float depth = dot(q, q) + dot(r, r);\n  float hue = 1.3 * f + 0.75 * depth + 0.25 * sin(t * 1.3) + hueShift;\n  vec3 col = palette(hue);\n\n  // strong contrast: collapse troughs to near-black void, saturate the body\n  float body = smoothstep(0.08, 0.70, f);\n  vec3 deep = vec3(0.01, 0.015, 0.04);\n  col = mix(deep, col * (0.35 + 1.1 * f), body);\n\n  // boost saturation around the mean so curtains read vivid, not milky\n  float lum = dot(col, vec3(0.299, 0.587, 0.114));\n  col = mix(vec3(lum), col, 1.55);\n\n  // ---- ridged \"curtain\" highlights -----------------------------------------\n  float ridge = 1.0 - abs(2.0 * f - 1.0);\n  ridge = pow(ridge, 4.0);\n  col += glow * 1.4 * ridge * vec3(0.45, 0.95, 0.85) * (0.5 + 0.8 * depth);\n\n  // flowing violet bloom from the warp magnitude\n  col += glow * 0.45 * pow(length(r), 1.5) * vec3(0.85, 0.35, 1.0);\n\n  // sparse hot cores where both warp fields align\n  float core = smoothstep(0.55, 0.62, f) * (1.0 - smoothstep(0.62, 0.72, f));\n  col += glow * core * vec3(1.0, 0.9, 0.7) * 1.2;\n\n  // ---- exposure + vignette + filmic tone -----------------------------------\n  col *= 0.82;                                  // pull back exposure, avoid wash-out\n  float vig = smoothstep(1.45, 0.15, length(uv - 0.5) * 1.7);\n  col *= mix(0.18, 1.0, vig);\n\n  // ACES-ish filmic curve — keeps highlights from clipping, deepens blacks\n  col = (col * (2.51 * col + 0.03)) / (col * (2.43 * col + 0.59) + 0.14);\n  col = clamp(col, 0.0, 1.0);\n  col = pow(col, vec3(0.4545));                 // gamma to sRGB\n\n  gl_FragColor = vec4(col, 1.0);\n}\n"
  }
}