// Minimal family: a survey drawing of a landscape — nested contour lines on a // ground plane running to the horizon, every fifth one heavier, and water // standing in the low ground. // // Horizon Lines is a bundle of parallel rules and Ridge Terrain is stacked // silhouettes: both describe a landscape by what it hides. Contours describe it // by what it measures, so the lines are closed, nested and never cross, and the // shape of the land is legible from the spacing alone. The water level is the // slow tide of the piece — the same terrain drowning and draining. export const contourMap = { name: 'Contour Map', family: 'minimal', kind: 'fragment', // Drafting, not photography. texture: 0.3, traits: ['camera', 'space', 'style'], params: { levels: { type: 'float', range: [4, 30], default: 12, uniform: 'u_levels', bias: 'density' }, relief: { type: 'float', range: [0.4, 3.0], default: 1.2, uniform: 'u_relief' }, sea: { type: 'float', range: [0.1, 0.9], default: 0.42, uniform: 'u_sea' }, indexN: { type: 'int', range: [3, 8], default: 5, uniform: 'u_indexN' }, weight: { type: 'float', range: [0.03, 0.3], default: 0.1, uniform: 'u_weight' }, shore: { type: 'float', range: [0, 1.4], default: 0.6, uniform: 'u_shore', bias: 'energy' }, drift: { type: 'float', range: [0.002, 0.03], default: 0.008, uniform: 'u_drift', bias: 'motion', rate: true }, palette: { type: 'palette', count: 5 }, }, reactive: { shore: { feature: 'loudness', amount: 0.3, response: 'smooth' }, relief: { feature: 'bandLow', amount: 0.2, response: 'smooth' }, }, shader: ` // The land. Slow enough that the survey is being redrawn rather than animated. float land(vec2 g, float t) { return fbm(g * u_relief + vec2(t, t * 0.6), 4); } vec4 scene(vec2 uv, vec2 p) { float t = u_time * u_drift + u_seed; p = sigCamera(p); float horizon = sigHorizonY() * 0.4 + 0.35; float below = horizon - p.y; // Sky: the paper the survey is drawn on, lit from the horizon. vec3 col = mix(pal(1) * 0.2, pal(0) * 0.07, sat((p.y - horizon) * 1.4 + 0.15)); col += pal(3) * exp(-abs(p.y - horizon) * 10.0) * 0.15; if (below > 0.002) { float depth = 1.0 / max(below, 0.03); vec2 g = vec2(p.x * depth, depth) * 0.5; float h = land(g, t); // Contours. The band is measured in HEIGHT, not in pixels, which is // what makes the lines crowd on steep ground and spread on flat ground // without anything having to compute a gradient. float f = h * u_levels; float band = abs(fract(f) - 0.5) * 2.0; float index = abs(fract(f / float(u_indexN)) - 0.5) * 2.0; float w = u_weight * (0.35 + u_sigLine * 1.8); float line = smoothstep(w, w * 0.2, band); float heavy = smoothstep(w * 1.6, w * 0.3, index); vec3 ground = pal(0) * 0.1; ground += palRamp(0.3 + h * 0.3) * line * 0.5; ground += pal(4) * heavy * 0.35; // Water standing in everything below the level. A flat tone, because // water has no contours — which is exactly what makes the level legible. float wet = smoothstep(u_sea + 0.02, u_sea - 0.02, h); vec3 water = mix(pal(2) * 0.7, pal(3) * 0.45, sat(below)); // Water takes the sky, so a flooded frame is a bright one and the level // is legible from across the room. water += pal(3) * exp(-below * 1.6) * u_shore * 0.5; ground = mix(ground, water, wet); // Shoreline: the one bright edge in the drawing. float edge = smoothstep(0.05, 0.0, abs(h - u_sea)); ground += pal(3) * edge * u_shore * 0.8; col = mix(col, ground, smoothstep(0.0, 0.03, below)); } col = sigAir(col, p, sat(1.0 - below * 0.9)); col += sigGrain(uv); return vec4(col, 1.0); } `, }; export default contourMap;