music-video-gen/flow-state/index.html
Dejvino 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>
2026-08-05 10:59:30 +02:00

74 lines
3.1 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>flow-state</title>
<link rel="stylesheet" href="/src/ui/style.css">
</head>
<body>
<div id="app">
<div id="stage">
<canvas id="canvas"></canvas>
<div id="overlay">
<div id="dropzone">
<div class="dz-inner">
<div class="dz-title">flow-state</div>
<div class="dz-sub">drop an audio file, or click to choose</div>
<div class="dz-hint">mp3 · flac · wav · ogg</div>
</div>
</div>
<div id="analysing" hidden>
<div class="an-title">analysing</div>
<div class="an-step"></div>
<div class="an-bar"><div class="an-fill"></div></div>
</div>
</div>
<div id="hud" hidden></div>
</div>
<div id="transport">
<div id="timeline">
<canvas id="timeline-canvas"></canvas>
</div>
<div id="controls">
<button id="btn-play" title="Play / pause (space)"></button>
<button id="btn-prev-section" title="Previous section (←)"></button>
<button id="btn-next-section" title="Next section (→)"></button>
<button id="btn-loop" title="Loop current section (L)"></button>
<span id="time-display">0:00 / 0:00</span>
<span class="spacer"></span>
<span id="section-display"></span>
<span class="spacer"></span>
<label class="ctl">quality
<select id="sel-quality">
<option value="draft">draft</option>
<option value="full" selected>full</option>
</select>
</label>
<button id="btn-reroll" title="New seed for the whole track">reroll</button>
<button id="btn-reroll-section" title="New scene for this section only">reroll section</button>
<button id="btn-lock" title="Lock this section against rerolls">lock</button>
<button id="btn-hud" title="Toggle debug HUD (D)">hud</button>
<button id="btn-segment" title="Render 20s around the playhead at export quality">test render</button>
<button id="btn-export" class="primary" title="Export the full video">export</button>
</div>
</div>
<aside id="panel">
<div id="panel-tabs">
<button data-tab="look" class="active">look</button>
<button data-tab="scene">scene</button>
<button data-tab="post">post</button>
<button data-tab="export">export</button>
</div>
<div id="panel-body"></div>
</aside>
</div>
<input type="file" id="file-input" accept="audio/*" hidden>
<audio id="audio" hidden></audio>
<script type="module" src="/src/main.js"></script>
</body>
</html>