// Minimal family: backlit paper screens in a wooden frame. A few big panels, a
// lamp somewhere behind them, and the track's signature form showing through
// one or two as a soft silhouette. The screens slide.
//
// Moiré Grid is the other minimal built on a grid, and it is a grid of hundreds
// of lines existing to interfere. This is a grid of six or eight PANELS: the
// count is small enough to read as objects, the frame is opaque, and almost the
// whole image is flat diffuse paper. What changes is which panel the light is
// behind and how far the screens have slid — not the pattern.

export const shojiGrid = {
    name: 'Shoji Grid',
    family: 'minimal',
    kind: 'fragment',
    // Paper has a tooth, and this is the one scene that wants it.
    texture: 1.0,
    traits: ['shape', 'camera', 'style'],

    params: {
        cols:    { type: 'int',   range: [2, 7],       default: 4,    uniform: 'u_cols', bias: 'density' },
        rows:    { type: 'int',   range: [1, 4],       default: 2,    uniform: 'u_rows' },
        slide:   { type: 'float', range: [-1.2, 1.2],  default: 0.0,  uniform: 'u_slide' },
        stile:   { type: 'float', range: [0.02, 0.16], default: 0.06, uniform: 'u_stile' },
        lamp:    { type: 'float', range: [0.15, 1.6],  default: 0.7,  uniform: 'u_lamp', bias: 'energy', slowAxis: true },
        form:    { type: 'float', range: [0, 0.5],     default: 0.26, uniform: 'u_form' },
        fibre:   { type: 'float', range: [0, 1],       default: 0.45, uniform: 'u_fibre' },
        sway:    { type: 'float', range: [0.06, 0.5],  default: 0.16, uniform: 'u_sway', bias: 'motion', rate: true },
        palette: { type: 'palette', count: 5 },
    },

    reactive: {
        form:  { feature: 'loudness', amount: 0.25, response: 'smooth' },
        fibre: { feature: 'bandAir',  amount: 0.3,  response: 'smooth' },
    },

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

    // The lamp behind the screens. One soft source, wandering slowly, and the
    // only reason any panel is brighter than another.
    vec2 lampAt = vec2(sin(t * 1.6) * 0.9, cos(t * 1.13) * 0.5);
    float glowField = exp(-length(p - lampAt) * 1.3) * u_lamp;

    // The screen grid. Alternate rows slide in opposite directions, which is
    // what makes it read as panels that MOVE rather than as a printed grid.
    float ry = floor((p.y * 0.5 + 0.5) * float(u_rows));
    float dir = mod(ry, 2.0) < 0.5 ? 1.0 : -1.0;

    float gx = (p.x * 0.5 + 0.5) * float(u_cols) + u_slide * dir;
    float gy = (p.y * 0.5 + 0.5) * float(u_rows);
    vec2 cell = vec2(floor(gx), floor(gy));
    vec2 f = vec2(fract(gx), fract(gy)) - 0.5;

    // Paper: warm, flat, with the light from behind soaking through it.
    float paperN = fbm(vec2(p.x * 40.0, p.y * 6.0) + cell * 3.7, 3);
    vec3 col = pal(1) * (0.12 + glowField * 0.55);
    col += pal(3) * glowField * 0.5;
    col *= 0.85 + 0.3 * paperN * u_fibre;

    // A panel or two is lacquered darker, so the row has a rhythm.
    float shade = hash12(cell + 3.0);
    col *= mix(0.55, 1.0, smoothstep(0.25, 0.4, shade));

    // The signature form, showing through the panel it stands behind.
    if (u_form > 0.01) {
        float which = step(0.62, hash12(cell * 1.7 + 9.0));
        vec2 at = vec2(f.x * 2.0 / float(u_cols), f.y * 2.0 / float(u_rows));
        float d = sigShape(at / u_form) * u_form;
        col = mix(col, col * 0.35 + pal(4) * glowField * 0.35,
                  smoothstep(0.01, -0.01, d) * which);
        col += pal(4) * sigEdge(d) * which * glowField * 0.7;
    }

    // The frame. Opaque, in front of everything, and the thing that makes the
    // panels objects instead of regions.
    float bar = min(0.5 - abs(f.x), 0.5 - abs(f.y));
    float wood = smoothstep(u_stile, u_stile * 0.4, bar);
    col = mix(col, pal(0) * 0.14, wood);
    col += pal(4) * sigEdge(bar - u_stile) * 0.12;

    col += sigGrain(uv);
    return vec4(col, 1.0);
}
`,
};

export default shojiGrid;
