slice_look
The film's spine. Registered with `demo.chaff.film` as `d.look`; it runs once per rendered frame from the `FilmDirector` clock and owns four things.
slice_look — CHAFF's light, camera and look
The film's spine. Registered with demo.chaff.film as d.look; it runs once
per rendered frame from the FilmDirector clock and owns four things.
1. The head
Eye is placed and turned every film frame — fourteen stations, the drift
between them, every recoil kick, every roll, and the hard teleport on each cut.
Nothing else writes Eye.
M.headAt(t) is a pure function of film time: no state carries between
frames, so seekTo(48.5) produces exactly the frame the film would have
produced by running there, and two passes give the same 2256 frames. Every
impulse is integrated in closed form — in zero gravity a round fired is a
permanent change of velocity, so the displacement it has produced by t is
dv * (t - t_fired), summed over the rounds already gone.
Positive yaw turns toward +X, positive pitch looks up, positive roll drops the right ear.
2. The light
| Entity | What it is |
|---|---|
Sun | The habitat's tumble carries it round once every 40 s. Its level goes from 0.045 of full in act I to full in the last nine seconds — the arc of the whole film, stated as one number. |
SunBar | The blade. A 46 x 1.3 m rect riding the drum wall at the tumble's rate, so the band it throws crosses the interior at t = 10 and again at t = 50. Gated off at t = 84: past the breach there is no interior left to cross. |
BreachSpill | Sun coming back in through the torn plate, from t = 58 on. |
Strobe1..6 | Amber emergency beacons down the drum wall. A lit lamp with a hard 0.16 s flash on a 2.35 s beat, sequenced along the wall so the drum reads as long. |
GalleryStrobe1..11 | One above each charging cradle. Shot 8's ripple runs down them at 0.42 s a beacon. |
Bounce | The only fill in the film — warm ochre off the grain, and less of it once he is out of the drum. |
3. The stop
M.exposureAt(t) returns the visor's auto-tint. A base per act, then about two
stops out on each of the six rounds in M.FIRE, attacking in one frame and
releasing over a third of a second, and two and a half stops out when the
breach opens on raw sun. The one round fired at contact range in shot 12 also
returns a whiteout that fills the faceplate.
M.FIRE is the film's list of firing times — 27.10, 28.60, 30.20 (shot 5),
61.40, 63.60 (shot 10), 76.90 (shot 12). The camera's recoil and the visor's
response are both driven from it. A slice putting a muzzle flash, a casing or a
report on the screen should read it from here rather than restate it, or the
flash and the kick will land on different frames.
4. The grade and the tail
demo.chaff.grade.chaff_grade is registered at priority 300 behind a bloom at
200, and every one of its properties is written per frame from M.lookAt(t) —
four looks crossfaded, never cut. See that shader's README for what each
property does.
The tail is the last thing this slice owns. The cutscene's clock reaching 94 s
hands the camera back to FallbackCamera, which is a different lens in a
different place; past 93.9 the film holds its last frame instead, restarting
the playback if it has already let go.
Two things that had to be worked around
A cutscene shot cannot state roll. Stage.setPose builds the camera's
rotation from pos and look against world up, so a shot has a yaw and a
pitch and nothing else. This slice composes the roll back on after each seek,
in the camera's own frame — and with the opposite sign, because the camera
looks along its own -Z while Eye looks along +Z, and the viewmodel hanging
off Eye has to stay upright in the frame it is drawn in.
The seek resolves the head one frame stale. The director seeks the playback
and then runs the slices, so the seek reads Eye before this slice has moved
it. repose(t) seeks again once the head is placed. Without it the film
renders every frame from the station the head occupied on the frame before, and
each cut lands a frame late.
Scoped to this part · feeds back into the world's score.