{
  "license": "CC0-1.0",
  "shader": {
    "id": "xfka82ty",
    "title": "OilSpillage",
    "license": "CC0-1.0",
    "provenance_type": "bred",
    "made_with": "glslop",
    "status": "active",
    "compile_ok": true,
    "render_hash": "d62a2d5b92274402",
    "tags": [
      "fluid",
      "viscous",
      "fluid simulation"
    ],
    "parents": [
      "a2shq2m0"
    ],
    "author": "7xl7dy8oavdn",
    "author_name": "joohnjack",
    "author_url": "/u/joohnjack",
    "created_at": "2026-07-23T00:14:24.028Z",
    "poster_url": "/posters/xfka82ty.avif",
    "stats": {
      "slops": 0,
      "views": 237,
      "forks": 0
    },
    "supersedes": "a2shq2m0",
    "self": "/api/v1/shaders/xfka82ty",
    "isf": "/*{\n  \"DESCRIPTION\": \"Viscous Oil & Deep Currents\",\n  \"CREDIT\": \"Converted to ISF\",\n  \"CATEGORIES\": [\"generator\"],\n  \"INPUTS\": [\n    { \"NAME\": \"speed\", \"TYPE\": \"float\", \"DEFAULT\": 1.0, \"MIN\": 0.0, \"MAX\": 4.0 },\n    { \"NAME\": \"colorShift\", \"TYPE\": \"float\", \"DEFAULT\": 0.0, \"MIN\": 0.0, \"MAX\": 5.0 },\n    { \"NAME\": \"zoom\", \"TYPE\": \"float\", \"DEFAULT\": 1.0, \"MIN\": 0.2, \"MAX\": 4.0 },\n    { \"NAME\": \"fluidDetail\", \"TYPE\": \"float\", \"DEFAULT\": 0.35, \"MIN\": 0.0, \"MAX\": 1.0, \"LABEL\": \"Warp Distortion\" },\n    { \"NAME\": \"cellIntensity\", \"TYPE\": \"float\", \"DEFAULT\": 0.4, \"MIN\": 0.0, \"MAX\": 1.0, \"LABEL\": \"Cell Visibility\" },\n    { \"NAME\": \"neonIntensity\", \"TYPE\": \"float\", \"DEFAULT\": 2.5, \"MIN\": 0.0, \"MAX\": 8.0, \"LABEL\": \"Deep Glow Power\" },\n    { \"NAME\": \"neonColor\", \"TYPE\": \"color\", \"DEFAULT\": [0.1, 0.8, 1.0, 1.0], \"LABEL\": \"Deep Glow Color\" },\n    { \"NAME\": \"specularBright\", \"TYPE\": \"float\", \"DEFAULT\": 1.8, \"MIN\": 0.0, \"MAX\": 5.0, \"LABEL\": \"Highlight Brightness\" }\n  ]\n}*/\n\n// --- VISCOUS OIL & DEEP CURRENTS ---\n\n// ==========================================\n// UTILITIES & NOISE\n// ==========================================\n\nvec2 r(vec2 v, float t) {\n    float s = sin(t), c = cos(t);\n    return mat2(c, -s, s, c) * v;\n}\n\nvec3 aces(vec3 c) { \n    mat3 m1 = mat3(0.59719, 0.07600, 0.02840, 0.35458, 0.90834, 0.13383, 0.04823, 0.01566, 0.83777);\n    mat3 m2 = mat3(1.60475, -0.10208, -0.00327, -0.53108, 1.10813, -0.07276, -0.07367, -0.00605, 1.07602);\n    vec3 v = m1 * c;\n    vec3 a = v * (v + 0.0245786) - 0.000090537;\n    vec3 b = v * (0.983729 * v + 0.4329510) + 0.238081;\n    return m2 * (a / b);\n}\n\nfloat no(vec3 p) {\n    const float PHI = 1.618033988;\n    const mat3 GOLD = mat3(\n        -0.571464913, +0.814921382, +0.096597072,\n        -0.278044873, -0.303026659, +0.911518454,\n        +0.772087367, +0.494042493, +0.399753815\n    );\n    return dot(cos(GOLD * p), sin(PHI * p * GOLD));\n}\n\nfloat hash21(vec2 p) {\n    p = fract(p * vec2(233.14, 713.41));\n    p += dot(p, p + 23.45);\n    return fract(p.x * p.y);\n}\n\nvec2 random2(vec2 p) {\n    return vec2(hash21(p), hash21(p + vec2(12.34, 56.78)));\n}\n\n// ==========================================\n// ADVANCED FLUID DYNAMICS\n// ==========================================\n\nfloat voronoi(vec2 x) {\n    vec2 n = floor(x);\n    vec2 f = fract(x);\n    float minDist = 1.0;\n    \n    for(int j = -1; j <= 1; j++) {\n        for(int i = -1; i <= 1; i++) {\n            vec2 g = vec2(float(i), float(j));\n            vec2 o = random2(n + g);\n            o = 0.5 + 0.5 * sin((TIME * speed) * 1.0 + 6.2831 * o);\n            vec2 res = g + o - f;\n            minDist = min(minDist, dot(res, res));\n        }\n    }\n    return minDist; \n}\n\nvec3 palette(in float t) {\n    vec3 a = vec3(0.2, 0.4, 0.6); \n    vec3 b = vec3(0.2, 0.4, 0.4); \n    vec3 c = vec3(1.0, 1.0, 1.0);\n    vec3 d = vec3(0.1, 0.8, 0.0); \n    return a + b * cos(6.28318 * (c * t + d));\n}\n\nfloat map(vec2 p) {\n    float t = TIME * speed;\n    vec2 q = vec2(no(vec3(p, t * 0.1)), no(vec3(p + 4.2, t * 0.08)));\n    vec2 w = vec2(no(vec3(p + q * 2.0, t * 0.07)), no(vec3(p - q * 2.0, t * 0.12)));\n    \n    // Connected to new fluidDetail input\n    p += w * fluidDetail;\n    \n    float rippleDist = length(p + vec2(2.5, 1.5));\n    \n    float microFlow = sin(p.x * 12.0 + t * 1.0) * cos(p.y * 12.0 - t * 0.8) * 0.015;\n    \n    float h = sin(rippleDist * 14.0 - t * 1.5 + w.x * 4.0);\n    h += cos(rippleDist * 9.0 + t * 1.2 - w.y * 4.0) * 0.5; \n    h = h * 0.33 + 0.5; \n    \n    float cells = voronoi(p * 3.5 + w * 2.0);\n    cells = smoothstep(0.0, 1.0, cells);\n    \n    // Connected to new cellIntensity input\n    h = mix(h, cells, cellIntensity * cells); \n    \n    return pow(max(h + microFlow, 0.0), 1.2); \n}\n\nvec3 getNormal(vec2 p) {\n    vec2 e = vec2(0.01, 0.0);\n    float dx = map(p + e.xy) - map(p - e.xy);\n    float dy = map(p + e.yx) - map(p - e.yx);\n    vec3 n = normalize(vec3(dx, dy, 0.35));\n    \n    float flowNoise = no(vec3(p * 8.0, (TIME * speed) * 0.8)) * 0.02;\n    n.xy += flowNoise;\n    \n    return normalize(n);\n}\n\nvec3 getFluidColor(vec2 uv) {\n    float t = TIME * speed;\n    float dist = length(uv);\n    float height = map(uv);\n    vec3 normal = getNormal(uv);\n    \n    float isPolarized = sin(dist * 5.0 - t * 1.5 + normal.x * 2.0) * 0.5 + 0.5;\n    \n    float lightX = sin(t * 0.5) * 1.5;\n    float lightY = cos(t * 0.3) * 1.5;\n    vec3 lightDir = normalize(vec3(lightX, lightY, 1.2));\n    vec3 viewDir = vec3(0.0, 0.0, 1.0);\n    \n    float diff = max(dot(normal, lightDir), 0.0);\n    float fresnel = 1.0 - max(dot(normal, viewDir), 0.0);\n    \n    float baseColorIndex = dist * 0.3                        \n                         + sin(uv.x * 3.0 + uv.y * 4.0 + t * 0.3) * 0.2  \n                         + fresnel * 0.9                    \n                         - t * 0.15                      \n                         + height * 0.8                     \n                         + isPolarized * 0.6\n                         + colorShift; \n                         \n    float chromOffset = dist * 0.08 + fresnel * 0.04; \n    vec3 oilColor;\n    oilColor.r = palette(baseColorIndex - chromOffset).r;\n    oilColor.g = palette(baseColorIndex).g;\n    oilColor.b = palette(baseColorIndex + chromOffset).b;\n    \n    vec3 col = oilColor * (diff * 0.6 + 0.3); \n    \n    vec3 glowPhase = vec3(3.0, 1.5, 0.5) + isPolarized * vec3(2.0, -2.0, 1.0);\n    vec3 shader2Glow = (1.0 + 1.5 * sin(height * 6.0 + length(uv * 6.0) + t * 0.8 + glowPhase));\n    float creviceMask = smoothstep(0.5, 0.05, height);\n    col += shader2Glow * creviceMask * 0.4;\n\n    float specR = pow(max(dot(reflect(-lightDir, normal + vec3(0.03, 0.0, 0.0)), viewDir), 0.0), 22.0);\n    float specG = pow(max(dot(reflect(-lightDir, normal), viewDir), 0.0), 28.0);\n    float specB = pow(max(dot(reflect(-lightDir, normal - vec3(0.03, 0.0, 0.0)), viewDir), 0.0), 34.0);\n    \n    // Connected to new specularBright input\n    vec3 prismaticSpec = vec3(specR, specG, specB) * specularBright * vec3(0.85, 0.95, 1.0); \n    \n    col += prismaticSpec; \n    col += pow(fresnel, 3.5) * palette(baseColorIndex + 0.4) * 0.7;\n    col *= height * 0.7 + 0.3;\n    \n    float deepMask = smoothstep(0.2, -0.05, height); \n    float deepNoise = no(vec3(uv * 10.0 - normal.xy * 2.0, t * 1.0));\n    \n    // Connected to neonColor and neonIntensity inputs\n    vec3 deepNeon = neonColor.rgb * (deepNoise * 0.5 + 0.5); \n    col += deepNeon * deepMask * neonIntensity;\n\n    vec3 polarizedCol = col.brg * vec3(1.5, 0.8, 1.3); \n    col = mix(col, polarizedCol, isPolarized * 0.7);\n\n    return col;\n}\n\n// ==========================================\n// MAIN COMPOSITION\n// ==========================================\n\nvoid main() {\n    vec2 uv = ((gl_FragCoord.xy - 0.5 * RENDERSIZE.xy) / RENDERSIZE.y) * zoom;\n    float dist = length(uv);\n    \n    vec3 finalColor = getFluidColor(uv);\n    \n    finalColor *= smoothstep(1.4 * zoom, 0.15 * zoom, dist);\n    \n    finalColor = aces(finalColor);\n\n    gl_FragColor = vec4(finalColor, 1.0);\n}"
  }
}