5.7 KiB
5.7 KiB
Round 4: Cinema
The juror's critique (before)
Shots: round4/before-*.webp, round4/before-sheet.webp.
- Murky world. The whole frame sat in one purple haze with no true blacks and no contrast range. The sun was a pale, flat disc that looked like clip-art. Nothing in the frame said "night".
- Empty destination. The road ended at nothing. Wireframe hills and grey districts read like a synthwave template. Nothing pulled the eye to the vanishing point.
- A lonely road. No other traffic and no light moving through the frame, so speed came only from the grid scrolling.
- One card, eight times. Every chapter used the same rounded glass card over the world. Chapter changes were invisible: the panel swapped and the world carried on unchanged.
- Generic hero. A standard gradient name with no title-card moment and no opening shot.
- Flat sound. The soundtrack did not react when you took an exit.
The transformation
The site now plays like the opening of a film: crane shot, title card, then a drive where every chapter is an exit you physically pass through.
- Film grade and lens (all tiers).
src/scene/cinematic-grade.tsswaps three's CustomToneMapping chunk for ACES followed by a deeper toe, an S-curve, cool shadows, warm highlights and a saturation lift. The low tier, which has no post-processing, gets the same grade.- On post-processing tiers,
LensFinishPassreplaces OutputPass one for one and allocates no extra render target. It adds:- chromatic aberration at the frame edges;
- an anamorphic blue streak sampled from a bloom mip that already exists;
- vignette and grain;
- letterbox bars and an exposure flash.
- The destination.
world/skyline.tsis a single procedural plane that draws a two-layer city silhouette against the sun. It has lit windows, sun-caught roof edges and blinking masts, uses one draw call and no texture. - Traffic.
world/traffic.tsdraws taillight pairs, long-exposure trails and wet-road pools.- Fast cars pull away when you idle. Scroll fast and you overtake trucks.
- Three instanced draws; vehicle count is 14, 10 or 7 depending on tier.
- Wet road. The asphalt now picks up a sun glare column, headlight throw from the car, and pylon reflections that travel with the drive.
- The sun. A saturated vermilion-to-gold disc, held below the ACES shoulder so it no longer washes out to cream.
- Opening crane. On a fresh load at the top of the page, the camera starts high and looking at the sun, then cranes down to the car over 4.2 s with letterbox bars. The shot cuts straight to the chase framing in four cases:
- the visitor scrolls;
- the visitor navigates;
- a sign starts to arrive (signs latch their placement against the chase camera);
- three frames take longer than 100 ms.
- Exit gates (the chapter cut).
- On every chapter change, nine light gates in the next chapter's accent colour rush past in about two seconds. The frame flashes slightly and bloom lifts.
- The field of view stays fixed, so sign placement does not move. The gate shader warms up during the first frames.
- The audio answers with a pass-by: a band-passed air sweep that pans left to right. Its nodes are allocated in advance, so a chapter change only schedules automation.
- Title card and night plates.
- The hero name is a large Outrun chrome title with a clip-path reveal that runs only under
prefers-reduced-motion: no-preference. - Panels became sharp-cornered dark plates with an accent rule, a hairline and crop marks.
- The broken one-word-per-line portrait-strip captions are fixed at ≥1100px.
- The hero name is a large Outrun chrome title with a clip-path reveal that runs only under
Evidence
-
Typecheck clean. Vitest: 684 of 684 passed.
-
build:previewbudgets, withviolations: []:Budget Size Initial JS 95.2 KB HTML + critical CSS 40.9 KB Fonts 69.0 KB First live scene 322.8 KB Deferred non-video 596 KB -
No new textures or render targets, so GPU allocation is unchanged.
-
FPS on Intel Arc iGPU, headed, before → after:
Section Before After start 168 152 infrastructure 187 176 selected-builds 185 173 toolkit 175 179 contact 200 184 p95 frame time is 8.4 ms everywhere.
-
Browser suite (
npm run test:browser, 65 or 64 failures against the 63-entry baseline). Compared with the baseline:- Fixed: two desktop keyboard-focus tests.
- Pass alone, fail sometimes under 4 workers on SwiftShader:
journey-integration:473(sign bounds about 16–36 px past the limit);journey-integration:508;arrival-finale;contact-refinements:22;- mobile
bfcache:50; - the known
:391flake.
- Why: these assertions are timing- and geometry-sensitive, and the margin shrank because the scene costs more per frame.
- No test was edited.
-
After shots:
round4/after-*.webp,round4/after-sheet.webp,round4/after-mobile-sheet.webp.
Honest regressions and open items
- FPS is about 6–9% lower, mainly from the lens pass and the traffic.
- Several browser tests (listed above) are now load-sensitive. They need either a cheaper path for software GL or wider timing margins in the tests, and I did neither.
- The first frame at
starthas one worst-case spike of about 196 ms from shader compiles. - The letterbox and lens effects appear only on post-processing tiers. The low tier gets the grade, the skyline, the gates and reduced traffic.
- The hero copy at 390 px still overlaps the car once the crane settles. This was true before this round too.
- Not done this round:
- a new car model or Blender asset pass;
- a nav and soundtrack-button redesign;
- consolidating the 12 stylesheets (the new CSS is one appended block in
route.css).