diff --git a/flow-state/_audioprobe.html b/flow-state/_audioprobe.html
new file mode 100644
index 0000000..c91a1ff
--- /dev/null
+++ b/flow-state/_audioprobe.html
@@ -0,0 +1,52 @@
+
+
+
audio probe
+
+running…
+
+
+
diff --git a/flow-state/_captureprobe.html b/flow-state/_captureprobe.html
new file mode 100644
index 0000000..fae7e36
--- /dev/null
+++ b/flow-state/_captureprobe.html
@@ -0,0 +1,128 @@
+
+
+capture probe
+
+
+running…
+
+
+
diff --git a/flow-state/_decodetest.html b/flow-state/_decodetest.html
new file mode 100644
index 0000000..67673df
--- /dev/null
+++ b/flow-state/_decodetest.html
@@ -0,0 +1,85 @@
+
+
+decode test
+
+running…
+
+
+
diff --git a/flow-state/_encprobe.html b/flow-state/_encprobe.html
new file mode 100644
index 0000000..ddee619
--- /dev/null
+++ b/flow-state/_encprobe.html
@@ -0,0 +1,131 @@
+
+
+encoder probe
+
+running…
+
+
+
+
diff --git a/flow-state/_exporttest.html b/flow-state/_exporttest.html
new file mode 100644
index 0000000..ed30332
--- /dev/null
+++ b/flow-state/_exporttest.html
@@ -0,0 +1,43 @@
+
+
+export test
+
+
+running…
+
+
+
diff --git a/flow-state/_muxprobe.html b/flow-state/_muxprobe.html
new file mode 100644
index 0000000..98e23aa
--- /dev/null
+++ b/flow-state/_muxprobe.html
@@ -0,0 +1,95 @@
+
+
+mux probe
+
+
+running…
+
+
+
diff --git a/flow-state/_playtest.html b/flow-state/_playtest.html
new file mode 100644
index 0000000..7e2f108
--- /dev/null
+++ b/flow-state/_playtest.html
@@ -0,0 +1,60 @@
+
+
+play test
+
+
+running…
+
+
+
diff --git a/flow-state/src/scenes/shader/classic-wave.js b/flow-state/src/scenes/shader/classic-wave.js
index a9b2767..34111c0 100644
--- a/flow-state/src/scenes/shader/classic-wave.js
+++ b/flow-state/src/scenes/shader/classic-wave.js
@@ -7,9 +7,8 @@ export const classicWave = {
family: 'flow',
kind: 'fragment',
// Personality: see look/Personality.js.
- // Grain is this scene's ONLY expression of the style trait — it draws no
- // hard edges to weight — so it keeps a share of it rather than opting out.
- texture: 0.35,
+ // Smooth concentric colour: grain only mutes the ramp it is built on.
+ texture: 0,
traits: ['shape', 'camera', 'style'],
params: {
@@ -47,9 +46,18 @@ vec4 scene(vec2 uv, vec2 p) {
float spoke = u_spokes > 0 ? sin(angle * float(u_spokes) + t) * u_beat : 0.0;
float v = 0.5 + 0.5 * sin(wave + spoke);
- v = mix(v, smoothstep(0.2, 0.8, v), u_softness);
- vec3 col = palRamp(t * u_colorRoll + d * 0.25) * v;
+ // TRAIT style: the track's hand on the crests. The scene's own u_softness
+ // decides HOW MUCH the wave is contrasted; the track decides what that
+ // contrast looks like — u_sigSoft widens the transition, u_sigLine tightens
+ // it. Centred on 0.5 so changing the hand does not change the exposure.
+ float edge = mix(0.06, 0.42, sat(u_sigSoft)) * mix(1.3, 0.6, sat(u_sigLine));
+ v = mix(v, smoothstep(0.5 - edge, 0.5 + edge, v), u_softness);
+
+ // ...and independently of u_softness, which a track is free to sample at
+ // zero: a heavier line concentrates the crest rather than letting it bloom
+ // across the whole ring.
+ vec3 col = palRamp(t * u_colorRoll + d * 0.25) * pow(v, mix(1.0, 2.2, sat(u_sigLine)));
// Core glow, the part that reads as the "hit".
col += pal(0) * (1.0 - smoothstep(0.0, 0.7, d)) * u_bloomCore * 0.6;
diff --git a/flow-state/src/scenes/shader/kaleido-tunnel.js b/flow-state/src/scenes/shader/kaleido-tunnel.js
index 9f0bc53..e4313b7 100644
--- a/flow-state/src/scenes/shader/kaleido-tunnel.js
+++ b/flow-state/src/scenes/shader/kaleido-tunnel.js
@@ -6,9 +6,8 @@ export const kaleidoTunnel = {
family: 'geometric',
kind: 'fragment',
// Personality: see look/Personality.js.
- // Grain is this scene's ONLY expression of the style trait — it draws no
- // hard edges to weight — so it keeps a share of it rather than opting out.
- texture: 0.35,
+ // Hard grid lines on flat colour: grain reads as dirt on the lens.
+ texture: 0,
traits: ['shape', 'camera', 'style'],
params: {
@@ -49,7 +48,13 @@ vec4 scene(vec2 uv, vec2 p) {
float ringLines = abs(fract(z * u_rings * 0.1) - 0.5) * 2.0;
float wallLines = abs(fract(wall * sides) - 0.5) * 2.0;
- float grid = smoothstep(0.42, 0.0, ringLines) + smoothstep(0.42, 0.0, wallLines);
+ // TRAIT style: the grid is the whole image, so the track draws it. The
+ // threshold was a bare 0.42 — a line weight with no name. u_sigLine sets how
+ // much of the cell the line occupies, u_sigSoft how far it feathers.
+ float weight = mix(0.22, 0.6, sat(u_sigLine));
+ float feather = weight * mix(0.15, 1.0, sat(u_sigSoft));
+ float grid = smoothstep(weight, max(weight - feather, 0.0), ringLines)
+ + smoothstep(weight, max(weight - feather, 0.0), wallLines);
vec3 col = palRamp(z * 0.05 + wall * 0.2) * 0.35;
col += pal(int(mod(floor(z * u_rings * 0.1), 6.0))) * grid * 0.7;
diff --git a/flow-state/src/scenes/shader/silk-ribbon.js b/flow-state/src/scenes/shader/silk-ribbon.js
index bcff392..97ad36a 100644
--- a/flow-state/src/scenes/shader/silk-ribbon.js
+++ b/flow-state/src/scenes/shader/silk-ribbon.js
@@ -9,9 +9,8 @@ export const silkRibbon = {
family: 'minimal',
kind: 'fragment',
// Personality: see look/Personality.js.
- // Grain is this scene's ONLY expression of the style trait — it draws no
- // hard edges to weight — so it keeps a share of it rather than opting out.
- texture: 0.35,
+ // A soft drape of light. Grain furs the one thing it is made of.
+ texture: 0,
traits: ['camera', 'style'],
params: {
@@ -57,8 +56,16 @@ vec4 scene(vec2 uv, vec2 p) {
best = min(best, d);
}
+ // TRAIT style: the ribbon is drawn in the track's hand. u_sigLine sets
+ // how wide the strand is, u_sigSoft how fast it falls off — a sharp
+ // track gets a filament with a defined edge, a soft one gets a haze.
+ // This is the scene's whole art direction, so it is not scaled by any
+ // of its own params: there is no setting at which the track stops
+ // showing.
+ float w = u_thickness * mix(0.55, 1.7, sat(u_sigLine));
+ float falloff = mix(2.6, 0.9, sat(u_sigSoft));
vec3 hc = pal(int(fk) % 3);
- col += hc * exp(-best * best / (u_thickness * u_thickness));
+ col += hc * exp(-pow(best / w, falloff * 2.0));
col += pal(3) * exp(-best * best * 60.0) * u_glow * 0.6;
}
diff --git a/flow-state/src/scenes/shader/slow-orb.js b/flow-state/src/scenes/shader/slow-orb.js
index a410ff6..7185696 100644
--- a/flow-state/src/scenes/shader/slow-orb.js
+++ b/flow-state/src/scenes/shader/slow-orb.js
@@ -10,9 +10,10 @@ export const slowOrb = {
family: 'minimal',
kind: 'fragment',
// Personality: see look/Personality.js.
- // Grain is this scene's ONLY expression of the style trait — it draws no
- // hard edges to weight — so it keeps a share of it rather than opting out.
- texture: 0.35,
+ // One soft body in an empty frame — the emptiest scene in the library, and
+ // the one where speckle is most visible for being least justified. It keeps
+ // its own `grain` param, which exists to stop large flat areas banding.
+ texture: 0,
traits: ['shape', 'camera', 'space', 'style'],
params: {
@@ -44,13 +45,22 @@ vec4 scene(vec2 uv, vec2 p) {
float wobble = fbm(q * 2.4 + t, 4) * u_wobble;
float d = (sigShape(q / max(u_size, 1e-3)) * u_size) * (1.0 + wobble);
- float body = smoothstep(u_softness * 0.5, -u_softness * 0.5, d);
+ // TRAIT style: the body's edge is drawn in the track's hand. The scene's
+ // u_softness says how soft this orb is; u_sigSoft says how soft this VIDEO
+ // is, and the two multiply.
+ float edge = u_softness * mix(0.35, 1.5, sat(u_sigSoft));
+ float body = smoothstep(edge * 0.5, -edge * 0.5, d);
float glow = exp(-max(d, 0.0) * (5.0 / max(u_halo, 0.05))) * u_halo;
+ // A rim in the track's line weight, so a sharp-handed track gets a defined
+ // limb against the halo instead of only a softer gradient.
+ float rim = sigEdge(d) * u_sigLine;
+
vec3 col = pal(0) * 0.05;
col = mix(col, pal(1), body * 0.85);
col += pal(2) * body * body * 0.5;
col += pal(3) * glow * 0.35;
+ col += pal(2) * rim * 0.5;
// Fine grain keeps large flat areas from banding.
col = sigAir(col, p, smoothstep(0.0, 1.6, length(q)));