camera-dof-device-lattice
camera-dof-device-lattice
Camera DOF — the DEVICE lattice. camera-dof-lattice.promo's idea (a 3D grid built with `repeat` + `vary`, a lens that racks through it) with devices in place of the mirror balls, and a camera that never parks: it dives down a corridor, orbits a laptop, flies through a column gap, trucks along the back wall, pushes onto a phone and climbs out over the top — racking focus from screen to screen and opening / closing the depth of field as it goes.
Read the rig's notes
THE LATTICE · 4 × 3 × 3 = 36 devices, 1 unit = 1 mm, real hardware sizes
x = 560·(ix − 1.5) → −840 −280 280 840
y = 440·(iy − 1) → −440 0 440
z = −720·iz → 0 −720 −1440
type = (ix + iy + iz) % 4 → 0 laptop · 1 iphone · 2 ipad · 3 chrome
so every row holds one of each and the kinds run in diagonal stripes. One
`repeat` per kind walks its 9 cells: iy = i % 3, iz = floor(i / 3),
ix = (kind − iy − iz) mod 4. The phones are two repeats (even / odd i) so
they alternate between two screens. Devices work inside `repeat` as-is (the
pre-pass clones the whole element, overlay and all, and suffixes every id),
and each screen is a `template` expanded before the repeat runs.
layer z=0 layer z=−720 layer z=−1440
y 440 ipad chrome laptop phone chrome laptop phone ipad laptop phone ipad chrome
y 0 phone ipad chrome laptop ipad chrome laptop phone chrome laptop phone ipad
y−440 laptop phone ipad chrome phone ipad chrome laptop ipad chrome laptop phone
x: −840 −280 280 840
Measured in the runtime (world AABB half-extents about the rig origin):
laptop 177 × 119 × 168 (open lid; its SCREEN centre sits at +9 y, −125 z,
leaning back ~20°) · iphone 39 × 80 × 7 (glass +6 z) · ipad
108 × 140 × 5 (glass +4 z) · chrome height=240 → 173 × 120, content
centre −12 y.
FREE SPACE — the camera only travels where no device can be:
· the slabs between layers, z ∈ (−552, −168) and (−1272, −888): nothing
reaches them (laptops are the deepest, ±168), so any x / y is safe there
— the truck runs in z = −1060;
· the column gaps x = 0, ±560 (≥ 100 mm to the widest device) and the row
gaps y = ±220 (≥ 80 mm); where a column gap meets a row gap is a
corridor through all three layers (the dive uses x=0 / y=220, ≥ 110 mm);
· everything above y = 600 and outside the grid.
Every kf pair was checked against the 36 measured boxes, sampled along the
eased segment (tightest: 97 mm, past lap-4's back corner at ~12.7 s), and
again along the smoothed path frame(smooth=0.12) actually plays (≥ 96 mm; the
chase lags the track by ≤ 73 mm on the fastest segment, the climb-out).
THE SCREENS · one app, Cadence (a music service), on every glass. Tailwind
HTML (camera-dof-device-lattice.screens.html) → html2ui's converter via
scripts/html-screens.mts (…sections.json → …screens.json) → the templates
below. Five screens: phone now-playing, phone home, iPad album, laptop
artist dashboard, chrome web player. Screens are ui3d(overlay=screen)
stages, so every piece of UI sits ON a device's glass — in focus exactly
when its device is. Icon sizes are nudged by 0.01 where two different
glyphs share a size + colour: ui surfaces are shared by a spec key that
skips `name` (layers/ui/_draw.ts SHARE_SKIP), and siblings would otherwise
all draw one glyph.
DOF · dof_pass=three (three.js's DepthOfFieldNode, gpu/post/three-dof.ts)
on the default depth pre-pass — no dof_depth=scene: the screens are
transparent ui planes that write no scene depth. `focus` on every kf is the
view-axis distance from the pose to the subject's GLASS, computed per kf
(a point or node-id focus written on a kf comes back broken in this build —
see camera-dof.promo). Where the kf looks straight at the subject it is
simply |glass − position|. dof_range / dof_blur move with the beat: 1100 /
12 outside the grid, 60 / 34 on the phone close-up.
LOOK · black-navy background, ACES, a key light, four coloured points in the
grid and the studio HDR at 0.22 for the casings. Laptops wear graphite
(#6e717a, roughness 0.7) on EVERY mesh (body-scope=all): the stock deck
carries a baseColor map so a plain finish skips it, and at the grazing
angles the truck sees, that metal deck mirrored the HDR into a white slab
that three's 16-tap MAX then spread into a glowing blob. No rim light for
the same reason — from behind it lit every lid back white. A far field of
small emissive dots (56, z −2700…−3800) gives the blur something to turn
into bokeh, the lattice example's spheres in miniature.
BEATS (one continuous move; frame(smooth=0.12) keeps velocity through kfs)
0.0– 3.4 A approach from outside, deep focus (2035) → the front iPad
3.4– 6.1 B dive down the x=0 / y=220 corridor: focus rides the iPad
(pad-1) as it swings past (570 at 4.0), racks off it — it
leaves as near blur — onto the layer-1 phone ph-2 (514)
6.1–10.85 C tilt down and orbit 105° round the layer-1 laptop (lap-4),
radius 480, focus fixed on its lid (493), slight bank
10.85–16.5 D out through the x=560 gap (the lid's edge as near-field
smear) onto the layer-2 phone ph-3 (651), then truck left
along z=−1060, racking ph-3 (396) → lap-7 (538) → web-7 (475)
16.5–22.2 E rise and push onto the Now Playing phone pn-4: 409 → 284 →
244, range 140 → 60
22.2–30.0 F climb out over the top still holding pn-4 (547), across onto
ph-2 from above (653), out in front (1891) and home (loops)
Preview: http://localhost:4444/runtime?project=promos/primitives/camera/camera-dof/camera-dof-device-lattice.promo&renderer=webgpu- Topic
- camera
- Scenes
- 1
- Kind
- reference rig
//
Camera DOF — the DEVICE lattice. camera-dof-lattice.promo's idea (a 3D grid
built with `repeat` + `vary`, a lens that racks through it) with devices in
place of the mirror balls, and a camera that never parks: it dives down a
corridor, orbits a laptop, flies through a column gap, trucks along the back
wall, pushes onto a phone and climbs out over the top — racking focus from
screen to screen and opening / closing the depth of field as it goes.
THE LATTICE · 4 × 3 × 3 = 36 devices, 1 unit = 1 mm, real hardware sizes
x = 560·(ix − 1.5) → −840 −280 280 840
y = 440·(iy − 1) → −440 0 440
z = −720·iz → 0 −720 −1440
type = (ix + iy + iz) % 4 → 0 laptop · 1 iphone · 2 ipad · 3 chrome
so every row holds one of each and the kinds run in diagonal stripes. One
`repeat` per kind walks its 9 cells: iy = i % 3, iz = floor(i / 3),
ix = (kind − iy − iz) mod 4. The phones are two repeats (even / odd i) so
they alternate between two screens. Devices work inside `repeat` as-is (the
pre-pass clones the whole element, overlay and all, and suffixes every id),
and each screen is a `template` expanded before the repeat runs.
layer z=0 layer z=−720 layer z=−1440
y 440 ipad chrome laptop phone chrome laptop phone ipad laptop phone ipad chrome
y 0 phone ipad chrome laptop ipad chrome laptop phone chrome laptop phone ipad
y−440 laptop phone ipad chrome phone ipad chrome laptop ipad chrome laptop phone
x: −840 −280 280 840
Measured in the runtime (world AABB half-extents about the rig origin):
laptop 177 × 119 × 168 (open lid; its SCREEN centre sits at +9 y, −125 z,
leaning back ~20°) · iphone 39 × 80 × 7 (glass +6 z) · ipad
108 × 140 × 5 (glass +4 z) · chrome height=240 → 173 × 120, content
centre −12 y.
FREE SPACE — the camera only travels where no device can be:
· the slabs between layers, z ∈ (−552, −168) and (−1272, −888): nothing
reaches them (laptops are the deepest, ±168), so any x / y is safe there
— the truck runs in z = −1060;
· the column gaps x = 0, ±560 (≥ 100 mm to the widest device) and the row
gaps y = ±220 (≥ 80 mm); where a column gap meets a row gap is a
corridor through all three layers (the dive uses x=0 / y=220, ≥ 110 mm);
· everything above y = 600 and outside the grid.
Every kf pair was checked against the 36 measured boxes, sampled along the
eased segment (tightest: 97 mm, past lap-4's back corner at ~12.7 s), and
again along the smoothed path frame(smooth=0.12) actually plays (≥ 96 mm; the
chase lags the track by ≤ 73 mm on the fastest segment, the climb-out).
THE SCREENS · one app, Cadence (a music service), on every glass. Tailwind
HTML (camera-dof-device-lattice.screens.html) → html2ui's converter via
scripts/html-screens.mts (…sections.json → …screens.json) → the templates
below. Five screens: phone now-playing, phone home, iPad album, laptop
artist dashboard, chrome web player. Screens are ui3d(overlay=screen)
stages, so every piece of UI sits ON a device's glass — in focus exactly
when its device is. Icon sizes are nudged by 0.01 where two different
glyphs share a size + colour: ui surfaces are shared by a spec key that
skips `name` (layers/ui/_draw.ts SHARE_SKIP), and siblings would otherwise
all draw one glyph.
DOF · dof_pass=three (three.js's DepthOfFieldNode, gpu/post/three-dof.ts)
on the default depth pre-pass — no dof_depth=scene: the screens are
transparent ui planes that write no scene depth. `focus` on every kf is the
view-axis distance from the pose to the subject's GLASS, computed per kf
(a point or node-id focus written on a kf comes back broken in this build —
see camera-dof.promo). Where the kf looks straight at the subject it is
simply |glass − position|. dof