Files
wsg/docs/user/effects/dof.md
T
Jérôme Bousquié d4c2d93fc5 eng doc
2026-09-25 20:06:10 +02:00

2.0 KiB
Raw Blame History

DoF (depth of field)

Depth of field simulates camera-lens behavior: objects at the focus distance are sharp, everything else is progressively blurred (the cinematic "bokeh" look). DoF is a post-process that operates on the HDR texture + depth buffer, before tone mapping.

Prerequisite: like bloom, DoF reads the HDR texture (and the depth buffer for the focus/blur computation). Enable HDR together with it.

Activation

DoF is opt-in through the builder. Without it, no DoF textures are allocated and the pipeline cost is zero:

use wsg_lib::prelude::*;

let app = AppBuilder::new()
    .with_hdr(ToneMapper::Aces)
    .with_dof(DoFConfig::cinematic(4.0))  // sharp at 4.0 world units
    .build()
    .await?;

DoFConfig

Field Type Meaning
focus_distance f32 World distance where the image is perfectly sharp
aperture f32 Blur intensity (0.0–1.0, clamped). Scales the circle of confusion
max_blur f32 Maximum blur radius in pixels (clamps the CoC)

Presets:

DoFConfig::new(focus_distance, aperture, max_blur)  // custom
DoFConfig::cinematic(focus_distance)                // aperture 0.3, max blur 12 px (cutscenes)
DoFConfig::subtle(focus_distance)                   // aperture 0.1, max blur 8 px (gameplay)

Runtime change

The dof example switches focus presets with the keys 1–4 (near / mid / far / infinity) and follows the zoom:

cargo run -p wsg-lib --example dof

Cost

  • Without DoF (default): zero overhead — no textures, no pass.
  • With DoF: 1 extra fullscreen pass + 2 intermediate textures (the bokeh buffer), before tone mapping.

Limitations (MVP)

  • A single focus distance per frame (no per-pixel focus / rack-focus over time).
  • The blur is a fixed-radius Gaussian scaled by the circle of confusion.