Skip to content

feat(effects): defocus the tilted screen by its depth - #692

Draft
EtienneLescot wants to merge 6 commits into
feat/3d-depth-gradientfrom
feat/3d-depth-of-field
Draft

EtienneLescot wants to merge 6 commits into
feat/3d-depth-gradientfrom
feat/3d-depth-of-field

Conversation

@EtienneLescot

@EtienneLescot EtienneLescot commented Sep 16, 2026

Copy link
Copy Markdown
Collaborator

Depth of field driven by the real rotation angle: none when flat, strong at steep angles. Goldens on Linux and macOS.

Chantier 3D, PR 5b. Spec complète et branche d intégration : #682. Empilée sur feat/3d-depth-gradient, à merger après.

🤖 Generated with Claude Code

A 3D-tilted zoom now blurs the parts of the screen that sit away from the
zoom focus, by their real depth. The blur is zero on flat zooms (mode 8 is
not drawn there) and grows with the actual tilt angle.

- regions: depth_mb fills k = DOF_COC_PER_DEPTH / P, so the shader gets a
  circle of confusion in source texels that ignores resolution and zoom.
- All three backends: while a tilted frame is drawn with the effect on, one
  mode-0 draw fills a half-resolution RGBA8 pyramid (5 levels, sized from
  the decoder texture, so UVs are unchanged). The mip chain is built with
  GenerateMips (D3D11), generate_mipmaps (Metal), or the generalised wgpu
  per-level loop. The pyramid is bound explicitly on every mode-8 draw:
  t2, texture(2), or wgpu binding 4.
- Shaders (HLSL/MSL/WGSL): under half a texel of blur, mode 8 keeps
  today's sample_yuv byte for byte. Above that it fades to the pyramid at
  log2(coc) - 1, capped at LOD 1.5.
- Settings: project effect "Depth of field", on by default, next to motion
  blur. It is disabled with a reason when the project has no 3D zoom. The
  setting goes through settings, persistence, presets (older presets keep
  it on), the scene contract and scene.rs, with strings in 14 locales.
- DOF_ON_CPU_BACKEND is the shared switch for WARP/lavapipe. The measured
  cost is under the 10 ms threshold, so the effect stays on there.

With the effect off, and with no rotation, the output is byte-identical to
the base (tilted_depth_slot_inert). tilted_depth_of_field checks that the
far corner is defocused while the near corner is unchanged, and measures
the A/B cost.
Composes a 2-texel checkerboard through the Metal compositor with an iso zoom focused on the near corner: the far corner must lose at least 30% of its detail, the near corner must not change a byte, and a flat zoom must render identically with the setting on or off. It is the first compile and run of fill_dof_pyramid, generate_mipmaps and the mode-8 texture(2) binding. Same logic validated on D3D11 with the same checkerboard (far 46.7 -> 0.00, near unchanged).
…d at 4K

The pyramid follows the source texture, not the render size, so the preview (panel-sized render read with readback_direct) and a 4K export are measured next to the 1080p export shape. OPENSCREEN_DOF_SOURCE_4K enables the 4K case.
@coderabbitai

coderabbitai Bot commented Sep 16, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant