// Ported from party-stage's "Deep Nebula". Changes on port:
//   - LED-grid mask removed (it existed to sell a screen inside a 3D room)
//   - hardcoded vec3 colours replaced with palette lookups
//   - magic numbers lifted into declared params
//   - beat reactivity moved from a single u_beat multiply to the reactive block

export const nebula = {
    name: 'Deep Nebula',
    family: 'organic',
    kind: 'fragment',
    // Personality: see look/Personality.js.
    consumes: ['ink'],
    traits: ['camera', 'space', 'style'],

    params: {
        scale:    { type: 'float', range: [4, 24],   default: 12,   uniform: 'u_scale', bias: 'density' },
        swirl:    { type: 'float', range: [0, 3],    default: 1.0,  uniform: 'u_swirl', bias: 'motion' },
        rings:    { type: 'float', range: [0, 1],    default: 0.5,  uniform: 'u_rings' },
        speed:    { type: 'float', range: [0.1, 1.5],default: 0.5,  uniform: 'u_speed', bias: 'motion', rate: true },
        depth:    { type: 'float', range: [0, 1],    default: 0.4,  uniform: 'u_depth' },
        palette:  { type: 'palette', count: 4 },
    },

    reactive: {
        swirl: { feature: 'bandLow',  amount: 0.20 },
        rings: { feature: 'flux',     amount: 0.25, response: 'smooth' },
    },

    shader: `
vec4 scene(vec2 uv, vec2 p) {
    // The track's camera films this scene too.
    p = sigCamera(p);
    float r = length(p);
    float a = atan(p.y, p.x);
    float t = u_time * u_speed + u_seed;

    // Layered drift, the "nebula" body.
    float n = fbm(p * u_scale * 0.25 + vec2(t * 0.2, -t * 0.15), 5);
    float n2 = fbm(p * u_scale * 0.6 - vec2(t * 0.1, t * 0.25) + n, 4);
    float body = sin(r * u_scale - t * 2.0 + n * 6.0 * u_swirl) * 0.5 + 0.5;
    body = mix(body, n2, u_depth);

    vec3 col = mix(pal(0), pal(1), sat(body));
    col = mix(col, pal(2), sat(n2 * n2) * u_depth);

    // Concentric pulse, tied to onset energy rather than a fixed rate.
    float ring = smoothstep(0.4, 0.5, abs(fract(r * 2.0 - t * 3.0) - 0.5));
    col += pal(1) * ring * u_rings * 0.6;

    // Core glow.
    float edge = 1.0 - smoothstep(0.1, 0.9, r);
    col += pal(3) * edge * 0.5 * 0.5;

    // Vignette the far field so the frame has a subject.
    col *= 0.5 + 0.5 * (1.0 - smoothstep(0.6, 1.6, r));

    // The location's air, and its surface.
    col = sigAir(col, p, smoothstep(0.0, 1.6, r));

    return vec4(inkValue(col), 1.0);
}
`,
};

export default nebula;
