Skip to content
Docs
Open Promoeyes
camera-dof

camera-dof

Camera depth-of-field primitives — the whole DOF surface, one knob per scene.

Read the rig's notes
Every length here is a MILLIMETRE (packages/core/units.ts). That is the whole
reason the numbers look the way they do: the panel sits 791mm from the lens,
not 9.3 of anything.

DOF is not a <postprocessing> step you add: writing ANY of `focus`,
`dof_range` or `dof_blur` on a <camera> (or on any camera <kf>) auto-injects
the pass and drives it from camera.userData.dof every frame
(engine/yaml-runtime, "Shallow DOF"). There is nothing else to turn on, and
this reel runs the default pass — camera_dof (gpu/post/camera-dof.ts).

THE THREE AUTHORED VALUES — the only ones that animate
  focus       the sharp distance, in mm. Three spellings, all live:
                focus=791            a distance
                focus="0 0 17"       a world POINT — whatever sits there
                focus="chaser"       a NODE id — tracks that node's position
              Point/node forms re-resolve every frame against the live
              camera pose (lib/focus-target.ts), so a moving camera or a
              moving subject needs no hand-computed distances. A FRAMED kf
              needs none of them: framing is focus, resolved per frame.
  dof_range   mm — how far from the focal plane blur reaches full strength,
              i.e. the depth of the sharp band. Typical 25-50% of `focus`;
              the runtime warns under 5%, which blurs the whole frame.
  dof_blur    mm ON THE FRAME — the blur ceiling, measured on the 1.92 x
              1.08 m full-frame wall, so `dof_blur=28.1` is a 28mm disc on a
              1080mm-tall frame at any resolution and wherever focus sits.
              It is a CEILING: it must not grow when the camera racks close.
All three interpolate per <kf> on the camera's <frame> keyframes — that is
what a rack focus IS here. `aperture`/`max_blur` are the pass's raw internal
pair and are still accepted for old reels; the mm knobs win when both are
present (lib/postprocessing/dof-units.ts).

THE PASS · camera_dof. Smoothstep CoC over `dof_range`, gathered at HALF
resolution with a Vogel disc (spiral rotated per pixel) whose tap count is
sized to the disc's AREA each frame — about one tap per 4 texels, <= 128 —
then composited full-res against the sharp buffer, keyed on each pixel's own
CoC so thin in-focus text stays sharp over a soft background. Scatter-as-
gather weighting, so a sharp subject cannot smear a halo into the soft field
around it. The depth it keys on is its own pre-pass: ui3d cards write depth
where their body is, not across the padding that holds their shadow. No
highlight model: an out-of-focus specular spreads and dims rather than
staying blown. `falloff` on an explicit <step name=camera_dof> shoulders the
ramp. (dof_pass=three — three.js's DepthOfFieldNode — suits highlights on a
dark field, camera-dof-lattice; on this bright ground it blurs the
focal-plane text and erodes the devices.)

THE STAGE · one lens (fov 34 at "0 12.75 808") and one light rig in every
scene, and four depth planes that never move:

    laptop  z=-467  -> screen at 1530      ipad   z=-170  ->  978
    panel   z=  17  ->          791        iphone z= 306  ->  502

The laptop is the one to watch: the rig origin is 1275mm out, but an open lid
leans its SCREEN about 255mm further back, so the plane you focus on is 1530
— measured, not assumed. The five scattered accents do sit on their nominal
planes (1275 / 978 / 791 / 502 / 417), which is why the far spheres go soft
while the laptop screen is sharp.

Scenes dress those planes two ways — a device desk (laptop · tablet ·
floating panel · phone) and a wall of floating UI behind a browser — plus
five scattered primitives, one per plane, so the falloff also reads on plain
geometry. Subjects, haze lobes and accents carry `match` ids the whole way,
so match-move gaps morph the set.

Every piece of type sits on the plane it is talking about, which is why a
readout goes soft the moment its beat ends.

A NOTE ON focus TARGETS · the point and node-id forms resolve per frame on
the CAMERA (scenes 5 and 6 prove it). Written on a <kf> instead they come
back as the resolver's 0.001 floor in this build and the frame goes flat —
so a rack across keyframes uses distances, as scene 7 does.

Preview: http://localhost:4444/runtime?project=promos/primitives/camera/camera-dof/camera-dof.promo
Topic
camera
Scenes
8
Kind
reference rig
//
    Camera depth-of-field primitives — the whole DOF surface, one knob per scene.

    Every length here is a MILLIMETRE (packages/core/units.ts). That is the whole
    reason the numbers look the way they do: the panel sits 791mm from the lens,
    not 9.3 of anything.

    DOF is not a <postprocessing> step you add: writing ANY of `focus`,
    `dof_range` or `dof_blur` on a <camera> (or on any camera <kf>) auto-injects
    the pass and drives it from camera.userData.dof every frame
    (engine/yaml-runtime, "Shallow DOF"). There is nothing else to turn on, and
    this reel runs the default pass — camera_dof (gpu/post/camera-dof.ts).

    THE THREE AUTHORED VALUES — the only ones that animate
      focus       the sharp distance, in mm. Three spellings, all live:
                    focus=791            a distance
                    focus="0 0 17"       a world POINT — whatever sits there
                    focus="chaser"       a NODE id — tracks that node's position
                  Point/node forms re-resolve every frame against the live
                  camera pose (lib/focus-target.ts), so a moving camera or a
                  moving subject needs no hand-computed distances. A FRAMED kf
                  needs none of them: framing is focus, resolved per frame.
      dof_range   mm — how far from the focal plane blur reaches full strength,
                  i.e. the depth of the sharp band. Typical 25-50% of `focus`;
                  the runtime warns under 5%, which blurs the whole frame.
      dof_blur    mm ON THE FRAME — the blur ceiling, measured on the 1.92 x
                  1.08 m full-frame wall, so `dof_blur=28.1` is a 28mm disc on a
                  1080mm-tall frame at any resolution and wherever focus sits.
                  It is a CEILING: it must not grow when the camera racks close.
    All three interpolate per <kf> on the camera's <frame> keyframes — that is
    what a rack focus IS here. `aperture`/`max_blur` are the pass's raw internal
    pair and are still accepted for old reels; the mm knobs win when both are
    present (lib/postprocessing/dof-units.ts).

    THE PASS · camera_dof. Smoothstep CoC over `dof_range`, gathered at HALF
    resolution with a Vogel disc (spiral rotated per pixel) whose tap count is
    sized to the disc's AREA each frame — about one tap per 4 texels, <= 128 —
    then composited full-res against the sharp buffer, keyed on each pixel's own
    CoC so thin in-focus text stays sharp over a soft background. Scatter-as-
    gather weighting, so a sharp subject cannot smear a halo into the soft field
    around it. The depth it keys on is its own pre-pass: ui3d cards write depth
    where their body is, not across the padding that holds their shadow. No
    highlight model: an out-of-focus specular spreads and dims rather than
    staying blown. `falloff` on an explicit <step name=camera_dof> shoulders the
    ramp. (dof_pass=three — three.js's DepthOfFieldNode — suits highlights on a
    dark field, camera-dof-lattice; on this bright ground it blurs the
    focal-plane text and erodes the devices.)

    THE STAGE · one lens (fov 34 at "0 12.75 808") and one light rig in every
    scene, and four depth planes that never move:

        laptop  z=-467  -> screen at 1530      ipad   z=-170  ->  978
        panel   z=  17  ->          791        iphone z= 306  ->  502

    The laptop is the one to watch: the rig origin is 1275mm out, but an open lid
    leans its SCREEN about 255mm further back, so the plane you focus on is 1530
    — measured, not assumed. The five scattered accents do sit on their nominal
    planes (1275 / 978 / 791 / 502 / 417), which is why the far spheres go soft
    while the laptop screen is sharp.

    Scenes dress those planes two ways — a device desk (laptop · tablet ·
    floating panel · phone) and a wall of floating UI behind a browser — plus
    five scattered primitives, one per plane, so the falloff also reads on plain
    geometry. Su