// Organic family: domain-warped plasma. The workhorse sustain scene — it holds
// up for minutes because the warp keeps folding new structure into itself rather
// than cycling.

export const plasmaBloom = {
    name: 'Plasma Bloom',
    family: 'organic',
    kind: 'fragment',
    // Personality: see look/Personality.js.
    traits: ['camera', 'space', 'style'],

    params: {
        scale:   { type: 'float', range: [0.8, 6],    default: 2.4, uniform: 'u_scale', bias: 'density' },
        warp:    { type: 'float', range: [0, 3],      default: 1.2, uniform: 'u_warp' },
        speed:   { type: 'float', range: [0.02, 0.5], default: 0.1, uniform: 'u_speed', bias: 'motion', rate: true },
        bands:   { type: 'float', range: [1, 10],     default: 3.5, uniform: 'u_bands'  },
        softness:{ type: 'float', range: [0, 1],      default: 0.5, uniform: 'u_softness' },
        glow:    { type: 'float', range: [0, 1.5],    default: 0.4, uniform: 'u_glow', bias: 'energy' },
        palette: { type: 'palette', count: 6 },
    },

    reactive: {
        warp:  { feature: 'bandLow',  amount: 0.35 },
        glow:  { feature: 'beat',     amount: 0.35, response: 'spike' },
        bands: { feature: 'centroid', amount: 0.2,  response: 'smooth' },
    },

    shader: `
vec4 scene(vec2 uv, vec2 p) {
    float t = u_time * u_speed + u_seed;
    p = sigCamera(p);

    // Two rounds of domain warping. One looks like noise; two looks organic.
    vec2 q = vec2(fbm(p * u_scale + t, 4), fbm(p * u_scale + vec2(5.2, 1.3) - t, 4));
    vec2 r = vec2(fbm(p * u_scale + q * u_warp * 2.0 + vec2(1.7, 9.2) + t * 0.6, 5),
                  fbm(p * u_scale + q * u_warp * 2.0 + vec2(8.3, 2.8) - t * 0.4, 5));

    float v = fbm(p * u_scale + r * u_warp * 2.0, 5);
    float shaped = sin(v * u_bands * 3.14159 + t * 1.5) * 0.5 + 0.5;
    shaped = mix(shaped, smoothstep(0.25, 0.75, shaped), u_softness);

    vec3 col = palRamp(shaped * 0.6 + length(r) * 0.25);
    col *= 0.35 + 0.75 * shaped;
    col += pal(4) * pow(shaped, 5.0) * u_glow;

    // Dark corners so the bloom has somewhere to sit.
    col *= 0.55 + 0.45 * exp(-dot(p, p) * 0.4);

    col = sigAir(col, p, smoothstep(0.0, 1.8, length(p)));
    col += sigGrain(uv);
    return vec4(col, 1.0);
}
`,
};

export default plasmaBloom;
