Add five visualizers to the scene library
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
// Structural family: a field of standing pylons receding to the track's
|
||||
// horizon. The columns converge on a vanishing point, giving real perspective
|
||||
// depth, and each column carries a crown in the signature form so a hexagonal
|
||||
// track grows hexagonal pylons. The beat walks a pulse of light down the rows
|
||||
// rather than flashing the whole frame.
|
||||
|
||||
export const pylonGrid = {
|
||||
name: 'Pylon Grid',
|
||||
family: 'structural',
|
||||
kind: 'fragment',
|
||||
// Personality: see look/Personality.js.
|
||||
traits: ['shape', 'space'],
|
||||
|
||||
params: {
|
||||
columns: { type: 'float', range: [3, 16], default: 8, uniform: 'u_columns', bias: 'density' },
|
||||
rows: { type: 'float', range: [2, 10], default: 6, uniform: 'u_rows', bias: 'density' },
|
||||
spread: { type: 'float', range: [0.6, 1.6], default: 1.1, uniform: 'u_spread' },
|
||||
height: { type: 'float', range: [0.3, 1.4], default: 0.85, uniform: 'u_height', bias: 'energy' },
|
||||
pulse: { type: 'float', range: [0, 1.2], default: 0.5, uniform: 'u_pulse', bias: 'energy' },
|
||||
speed: { type: 'float', range: [0.05, 0.8], default: 0.3, uniform: 'u_speed', bias: 'motion', rate: true },
|
||||
palette: { type: 'palette', count: 4 },
|
||||
},
|
||||
|
||||
reactive: {
|
||||
pulse: { feature: 'beat', amount: 0.4, response: 'smooth' },
|
||||
rows: { feature: 'bandLow', amount: 0.25 },
|
||||
},
|
||||
|
||||
shader: `
|
||||
// Distance to a thin vertical strut from (cx, y0) up to (cx, y1).
|
||||
float strut(vec2 p, float cx, float y0, float y1, float w) {
|
||||
float xd = abs(p.x - cx);
|
||||
float yd = max(max(y0 - p.y, p.y - y1), 0.0);
|
||||
float d = sqrt(xd * xd + yd * yd);
|
||||
return smoothstep(w + 0.004, w - 0.004, d);
|
||||
}
|
||||
|
||||
vec4 scene(vec2 uv, vec2 p) {
|
||||
float t = u_time * u_speed + u_seed;
|
||||
float hy = sigHorizonY();
|
||||
vec3 col = pal(0) * 0.05;
|
||||
|
||||
for (int r = 0; r < 10; r++) {
|
||||
if (float(r) >= u_rows) break;
|
||||
float fr = float(r);
|
||||
|
||||
// Perspective: the last row sits on the horizon, the first at the bottom
|
||||
// of the frame, everything between scaling by its depth fraction.
|
||||
float f = fr / max(u_rows - 1.0, 1.0); // 0 near .. 1 far
|
||||
float y0 = mix(-1.08, hy + 0.06, f); // row baseline
|
||||
float scale = mix(1.0, 0.12, f); // perspective shrink
|
||||
float depthShade = mix(1.0, 0.35, f); // far rows dim
|
||||
|
||||
for (int c = 0; c < 16; c++) {
|
||||
if (float(c) >= u_columns) break;
|
||||
float fc = float(c);
|
||||
float cx = (fc / max(u_columns - 1.0, 1.0) - 0.5) * 2.0 * u_spread * scale;
|
||||
|
||||
float h = u_height * scale;
|
||||
float yTop = y0 + h;
|
||||
|
||||
// The beat pulse walks a glow down the depth axis, row by row, so the
|
||||
// light travels rather than strobing the whole frame.
|
||||
float walk = sat(1.0 - abs(fr - mod(u_beatPhase * 6.0 + t * 0.4, u_rows)));
|
||||
float inten = (0.35 + 0.65 * walk) * depthShade * (0.7 + 0.3 * u_beat);
|
||||
|
||||
float w = 0.02 * scale + 0.006;
|
||||
col += pal(int(mod(fc, 4.0))) * strut(p, cx, y0, yTop, w) * inten;
|
||||
|
||||
// Crown stamped in the track's signature form.
|
||||
vec2 crown = vec2(cx, yTop);
|
||||
float size = (0.06 + 0.2 * scale) * (1.0 + u_beat * 0.4);
|
||||
col += pal(3) * sigForm(p, crown, size) * inten * (0.6 + u_pulse);
|
||||
col += pal(int(mod(fr, 4.0))) * exp(-dot(p - crown, p - crown) * 60.0) * u_pulse * depthShade;
|
||||
}
|
||||
}
|
||||
|
||||
// Ground haze and the shared air between here and the horizon.
|
||||
col = sigAir(col, p, smoothstep(0.0, 1.6, abs(p.y - hy)));
|
||||
col += sigGrain(uv);
|
||||
return vec4(col, 1.0);
|
||||
}
|
||||
`,
|
||||
};
|
||||
Reference in New Issue
Block a user