// Organic family: an abstract plant — a plume of swaying stalks with teardrop // leaves and a glowing bloom at each crown. // // Abstract on purpose: no soil, no foreground, just the silhouette of growth. // Every petal and the crown are stamped in the track's signature form, so a // hexagonal track grows hexagonal flora. The stalk bends on bass and the bloom // pulses on the beat — the plant dances to the track rather than the camera // shaking. export const flora = { name: 'Flora', family: 'organic', kind: 'fragment', // Personality: see look/Personality.js. traits: ['shape', 'camera', 'style'], params: { count: { type: 'float', range: [1, 5], default: 3, uniform: 'u_count', bias: 'density' }, height: { type: 'float', range: [0.6, 2.0], default: 1.1, uniform: 'u_height', bias: 'energy' }, stem: { type: 'float', range: [0.008, 0.05], default: 0.02, uniform: 'u_stem' }, sway: { type: 'float', range: [0.05, 0.5], default: 0.2, uniform: 'u_sway', bias: 'motion' }, swayRate:{ type: 'float', range: [0.1, 1.2], default: 0.6, uniform: 'u_swayRate', rate: true }, leaf: { type: 'float', range: [0.12, 0.5], default: 0.26, uniform: 'u_leaf' }, bud: { type: 'float', range: [0, 1], default: 0.55, uniform: 'u_bud', bias: 'energy' }, palette: { type: 'palette', count: 4 }, }, reactive: { sway: { feature: 'bandLow', amount: 0.25, response: 'smooth' }, bud: { feature: 'beat', amount: 0.3, response: 'smooth' }, }, shader: ` // Horizontal lean of a spine at parametric height h (0 base .. 1 tip), seeded // per plant and swaying more toward the crown like a real stem. Returns a value // scaled by u_sway later, so the reactive bend applies to every part at once. float swayAt(float h, float phase, float t) { return sin(t * (0.35 + fract(phase * 1.7)) + phase) + h * sin(t * (0.35 + fract(phase * 0.6)) + phase * 2.1); } // A petal: an elongated blossom drawn in the track's signature form, growing // forward along dir from a node and clipped to a blade shape. float petal(vec2 p, vec2 node, vec2 dir, float len, float width) { vec2 off = p - node; float along = dot(off, dir); vec2 perp = vec2(-dir.y, dir.x); float across = dot(off, perp); float taper = 0.6 + 0.4 * sat(along / max(len, 1e-3)); vec2 q = vec2(along / max(len, 1e-3), across / max(width * taper, 1e-3)); float form = sigForm(q * 0.5, vec2(0.0), 0.5); float clip = smoothstep(0.0, -0.1, along) * smoothstep(len + 0.12, len * 0.72, along); return form * clip; } vec4 scene(vec2 uv, vec2 p) { float t = u_time * u_swayRate + u_seed; float beat = u_beat; p = sigCamera(p); // Soft vertical wash behind the plants. vec3 col = mix(pal(0) * 0.03, pal(1) * 0.06, sat((p.y + 1.0) * 0.5)); for (int i = 0; i < 5; i++) { if (i >= int(u_count)) break; float fi = float(i); float s = u_seed + fi * 43.7; float baseX = (hash11(s * 1.7) - 0.5) * 1.25; float height = u_height * (0.55 + 0.45 * hash11(s * 3.1)); float baseY = -0.92; // Stem, sampled so the bend follows the sway curve rather than a chord. float stemMask = 0.0; for (int j = 0; j < 12; j++) { float hj = (float(j) + 0.5) / 12.0; float cx = baseX + swayAt(hj, s, t) * u_sway; float cy = baseY + hj * height; float d = length(p - vec2(cx, cy)); float taper = max(u_stem * (1.0 - hj * 0.8) + 0.002, 0.003); stemMask = max(stemMask, smoothstep(taper + 0.004, taper - 0.004, d)); } col = mix(col, mix(pal(1), pal(3), 0.3), stemMask); // Stalk tip, reused for the petal rows and the bloom. float tipX = baseX + swayAt(1.0, s, t) * u_sway; float tipY = baseY + height; // Petals up the upper half, alternating sides. for (int l = 0; l < 6; l++) { float fll = float(l); float node = 0.45 + floor(fll * 0.5) * 0.12; float side = fract(fll * 0.5) < 0.5 ? -1.0 : 1.0; float nx = baseX + swayAt(node, s, t) * u_sway; float ny = baseY + node * height; vec2 dir = normalize(vec2(side, 0.55)); float len = u_leaf * 2.0; float m = petal(p, vec2(nx, ny), dir, len, u_leaf); vec3 leafCol = mix(pal(2), pal(3), fract(s * 0.4)); col = mix(col, leafCol, m); col += pal(3) * m * (0.2 + 0.3 * beat); } // Bloom: a small corona of signature forms around the crown. float bloom = 0.0; for (int k = 0; k < 6; k++) { float a = 6.2831853 * (float(k) + 0.5) / 6.0 + s; vec2 off = vec2(cos(a), sin(a)) * u_leaf * (0.30 + 0.2 * beat); bloom += sigForm(p - vec2(tipX, tipY), off, u_leaf * 0.5); } col = mix(col, pal(2), sat(bloom) * u_bud * (0.6 + 0.4 * beat)); } col += sigGrain(uv); return vec4(col, 1.0); } `, }; export default flora;