df609424d5
4 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
89e05459c0 |
Every shot stands on something, and the frame has two ends
A section used to be one scene, and two thirds of the library is composable —
sparse by design, elements ON something. Cast as backgrounds anyway, they left
9 of 40 sampled frames under 20% painted, the darkest at 0.3%: a minute and a
half of a few bright things on black, invisible to every gate because every
gate on the stack was a limit rather than a floor.
Every section now stands on a GROUND: a canvas that fills the frame, cast per
section kind so a shot cut changes the shot and not the world. When the shot
fills the frame itself it IS the ground — two canvases stacked is two pictures
fighting. Above that, a coverage BUDGET: director appetite times the section's
energy times where the story is, capped at two frames' worth of material.
The measured facts move into the repo. scenes/metadata.json is generated from
the gallery — coverage as a shot, coverage as a bed, variety, the structural
profile — tracked in git, stamped with a fingerprint of the scenes and the
metric definitions, and refreshed from gallery.html. `surface` is derived from
it rather than declared; nine scenes claimed `canvas` while painting under a
third of the frame, and declaring it is now a lint error. The generator weights
every layering choice by measured structural distance, because family labels
and the render disagree: two `geometric` scenes can be 0.31 apart and a `flow`
and an `organic` scene 0.04.
The gallery's 0.1 red line is gone. It was right when a section was one scene
and wrong now — nineteen scenes were failing a bar for being consistent, which
is a virtue in an ingredient.
Chasing the numbers turned up four real faults:
* A scene that reads prev() cannot be a ground. It returns the whole
composited frame including the layers above it, so a datamosh under a shot
is eating it: the render stopped reproducing from a seek and two WebGL
contexts diverged by 91/255 against a tolerance of 4.
* Screen was the wrong operator for a shot over a bed. It lightens, so a
median quarter of every frame clipped to paper and whole sections rendered
100% white. Replaced by a lumakey — the shot's brightness is its alpha.
* Feedback was an accumulator: a still image settled at 2.3x its own
brightness. Fine over black, fatal over a filled ground. Normalised at 0.6,
plus a highlight shoulder so the top rolls off instead of clipping.
* useTrack never prewarmed, so a fresh Show's first frame differed from every
later render of it — the export-breaking hazard Compositor.prime documents.
Blazing is a decision now, not a side effect: directors declare an appetite for
it, a section must be loud and late in the story to earn one, and quiet kinds
never do. The ceiling gate matches that — a hard cap per section, and no more
than a fifth of them hot at all.
Rendered across twelve videos, middle of every section:
painted 51% mean, darkest 0.3% -> 87% mean, darkest 43%
clipped white 24% median, worst 100% -> 1% mean, worst 30%
separation 0.10 -> 0.44
Seven scenes can ground a section — five geometric, two organic — so every
quiet section of every video stands on one of two beds. That is the library's
largest hole and it is scene work: there is no minimal or flow canvas that
fills half the frame without reading prev().
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
||
|
|
1ca9fa2f1f |
Let scenes layer on each other, and give the camera somewhere to look
Two devices that were built, wired up, and doing nothing. OVERLAYS. buildStack gated layering on `surfaceOf(m) === 'composable'`, and no scene in the library declared `surface` — so the only thing that could ever sit on top was the one scene declaring `role: 'accent'`, and the overlay roster excluded accents by construction. Empty intersection, every time: 0/144 stacks carried an overlay. Every layered frame in every song was the same particle field. Labelled the library from the phase 12 coverage gate rather than by eye: the 37 scenes painting under 30% of the frame are composable. Particle Field loses its privileged slot and becomes one of them, keeping only `background: false`, which is the honest part — points in empty space cannot carry a section alone. The reserved accent slot is gone; one roster, two passes at it. 1 distinct overlay scene becomes 27, and the rate lands at 34% of stacks after trimming a base chance that had been tuned while the branch was dead. THE CAMERA. framing.shift moved the frame by a median of 0.029 of a half-frame at a fresh random angle every shot, so successive offsets cancelled and the median jump at a cut was 0.014. Present in every frame, visible in none. look/Camera.js is the director's camera department: the story says tension, order and which act a section is in, and this turns that into where the frame looks and how it travels there. Each director names a camera. Jump distance follows tension and act, speed follows energy, and the curve is one of four. Cuts choose between reframing and matching, so two scenes can still read as one place. Median offset 0.190, median reframe 0.135, and 94% of shots now move during the shot rather than only at the cut. Four new gates, each with a FLOOR — the device this replaces passed every existing check while doing nothing, because the only bound was a ceiling. Also lands the in-progress Epic 4 story layer it builds on: Story.js, phase 13, and the direction statistic. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
c6d96c9d40 |
A gallery, and a debug index to reach it from
Sixty-five visualizers, six renders each, one per song — each carrying that song's whole identity: its cast, ink, lattice, palette and a fresh parameter draw. Side by side, a scene that cannot be changed by the song is obvious in a way no aggregate could show, which is the complaint this answers. It scores as well as shows. Each row carries the mean structural distance between its own six frames, on the same descriptor the variety harness uses and with colour excluded, so six palettes cannot disguise one image. Sorted least-varied first, because browsing sixty-five scenes hunting for the repetitive ones is precisely what a sort order should do for you. The result names names. Thirteen scenes barely change across six songs, and they fall into two groups that were already known separately. The ink-only migrations — Analog Wow, Halftone Misprint, Pitch Shatter, Block Mosh, Scan Tear — are the shallow tier flagged in MIGRATION.md, where the whole migration was one posterisation. And Moiré Grid, Isometric Blocks, Quasicrystal, Truchet Fold, Voronoi Shatter and Apollonian Gasket are the structural twin cliques the library sweep found weeks of measurement ago, arriving here by a completely different route: the sweep compared scenes to each other, the gallery compares a scene to itself, and they agree on the same offenders. debug.html collects the tools, since there are now enough of them that knowing which to open is its own problem. It also carries the two things a newcomer would otherwise learn the hard way: which measurements are safe to steer by (direct render comparisons) and which are not (aggregate ratios), and what to do when a page renders perfectly and does nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
7e31c19d6e |
Phase 0: determinism spine
Engine core: Timeline (fixed dt, audio-mastered in realtime), seeded Rng, Renderer, Layer/ShaderLayer/SceneLayer, Compositor with blend modes, feedback and post chain. Shader scenes are compiled against a fixed uniform contract and define only `vec4 scene(vec2 uv, vec2 p)`, so adding a scene costs a shader plus a params block. Deep Nebula ported from party-stage as the first one. Gate passes, 7/7 in checks.html: - 300 frames rendered twice are bit-identical - a fresh Engine reproduces the same frames - simulated dropped frames change nothing (proves dt is fixed) - seek matches sequential playback - 320x180 vs 1280x720 agree within 0.010 (limit 0.06) - seeded rng reproducible, forked streams independent - compositor reset clears feedback history Static gates: no wall-clock or unseeded randomness in deterministic directories; scene schemas and shader sources agree in both directions. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |