Skip to content
Docs
Open Promoeyes
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