/*
{
    "uuid": "c9f7e2a1-5b3d-4fpc-8a2e-1d9b7c4e5f21",
    "author": "VSwarez",
    "color": "#ffffff",
    "movement": true,
    "description": "Space donuts,Liquidlighting Filament Cloud",
    "parameters": [
        { "name": "camyaw", "default": 0.5, "min": 0.0, "max": 1.0 },
        { "name": "scale", "default": 1.0, "min": 0.3, "max": 3.0 },
        { "name": "density", "default": 0.7, "min": 0.0, "max": 1.0 },
        { "name": "cohesion", "default": 0.8, "min": 0.0, "max": 1.0 },
        { "name": "scatter", "default": 0.35, "min": 0.0, "max": 1.0 },
        { "name": "magnet", "default": 0.9, "min": 0.0, "max": 1.0 }
    ]
}
*/
#ifdef GL_ES
precision mediump float;
#endif
#define STEPS 34
#define FAR 12.0

mat2 rot(float a)
{
    float s = sin(a), c = cos(a);
    return mat2(c,-s,s,c);
}

// ----------------------------------------------------
// Cheap organic flow - Updated to incorporate 'magnet'
// ----------------------------------------------------
vec3 warp(vec3 p, float t)
{
    // magnet controls the strength and frequency of the spatial distortion
    float mStrength = mix(0.1, 1.8, magnet);
    p.xy *= rot(sin(t * 0.3) * 0.4);
    p.x += sin(p.y * 2.0 + t * 1.1) * 0.25 * mStrength;
    p.y += cos(p.z * 1.8 - t * 0.9) * 0.22 * mStrength;
    p.z += sin(p.x * 1.6 + t * 0.7) * 0.18 * mStrength;
    return p;
}

// ----------------------------------------------------
// Filament field - Fully linking density, scatter, cohesion
// ----------------------------------------------------
float filament(vec3 p)
{
    float t = time * 0.55;
    p = warp(p, t);
    
    // Floating cloud drift
    p += vec3(
        sin(t * 0.17),
        cos(t * 0.13) * 0.4,
        sin(t * 0.21) * 0.6
    );
    
    float d = 10.0;
    
    // Scatter scales the positional offset vector of the ribbons
    float disp = mix(0.2, 1.5, scatter);
    
    // Density maps to the target thickness/radius of the strand cross section
    float thickness = mix(0.01, 0.14, density);
    
    // 12 flowing ribbons
    for(int i = 0; i < 12; i++)
    {
        float fi = float(i);
        vec3 q = p;
        
        q.x += sin(fi * 1.7 + t * 0.9) * disp;
        q.y += cos(fi * 2.3 + t * 0.7) * disp * 0.7;
        
        // Long soft tentacle curve
        q.y += sin(q.z * 2.5 + fi + t) * 0.35;
        q.x += cos(q.z * 1.8 + fi * 0.7 - t * 0.8) * 0.25;
        
        // Ribbon-like cross section using integrated thickness
        vec2 r = vec2(length(q.xy) - 0.06, q.z);
        float tube = length(r) - thickness;
        d = min(d, tube);
    }
    
    // Soft cloud envelope (already using cohesion)
    float env = length(p * vec3(0.8, 1.1, 0.8)) - mix(1.8, 1.1, cohesion);
    return max(d, env);
}

// ----------------------------------------------------
vec3 normal(vec3 p)
{
    vec2 e = vec2(0.01, 0.0);
    return normalize(vec3(
        filament(p + e.xyy) - filament(p - e.xyy),
        filament(p + e.yxy) - filament(p - e.yxy),
        filament(p + e.yyx) - filament(p - e.yyx)
    ));
}

// ----------------------------------------------------
void main()
{
    vec2 uv = (texCoord - 0.5) * vec2(resolution.x / resolution.y, 1.0);
    uv /= scale;
    
    float yaw = (camyaw - 0.5) * 6.28318;
    vec3 ro = vec3(sin(yaw) * 4.0, 0.0, cos(yaw) * 4.0);
    vec3 ta = vec3(0.0);
    vec3 ww = normalize(ta - ro);
    vec3 uu = normalize(cross(ww, vec3(0, 1, 0)));
    vec3 vv = cross(uu, ww);
    vec3 rd = normalize(uu * uv.x + vv * uv.y + ww * 1.5);
    
    float t = 0.0;
    bool hit = false;
    for(int i = 0; i < STEPS; i++)
    {
        vec3 p = ro + rd * t;
        float d = filament(p);
        if(d < 0.003)
        {
            hit = true;
            break;
        }
        if(t > FAR) break;
        t += max(d * 0.9, 0.02);
    }
    
    if(!hit)
    {
        fragColor = vec4(0.0);
        return;
    }
    
    vec3 p = ro + rd * t;
    vec3 n = normal(p);
    vec3 viewDir = normalize(ro - p);
    
    // Cinematic liquid-metal lighting
    vec3 L1 = normalize(vec3(0.7, 0.8, 0.5));
    vec3 L2 = normalize(vec3(-0.5, 0.3, -0.8));
    float diff = max(dot(n, L1), 0.0) * 0.9 + max(dot(n, L2), 0.0) * 0.25;
    
    vec3 h = normalize(L1 + viewDir);
    float spec = pow(max(dot(n, h), 0.0), 72.0);
    float rim = pow(1.0 - max(dot(viewDir, n), 0.0), 2.5);
    
    // Proper VS2 colour linking
    vec3 base = color.rgb;
    
    // Metallic monochrome support
    float lum = dot(base, vec3(0.299, 0.587, 0.114));
    vec3 metal = mix(vec3(lum), base, 0.85);
    
    // Soft brushed reflection
    metal += sin(p.z * 40.0 + p.x * 12.0) * 0.03;
    vec3 col = metal * (0.15 + diff);
    col += vec3(1.0) * spec * 1.8;
    col += vec3(1.0) * rim * 0.9;
    
    // Slight warm/cool interference
    col += vec3(0.08, 0.05, 0.12) * sin(p.y * 8.0 + time * 0.5);
    col = pow(col, vec3(0.92));
    
    fragColor = vec4(col, alpha * color.a);
}

