Depth of Field
Keep a selected camera-space distance sharp while softening nearer and farther geometry.
dofCompositeShaderPass reconstructs depth from the scene attachment and applies separable
horizontal and vertical lens blur.
At a Glance​
| Property | Value |
|---|---|
| Exports | dof and dofCompositeShaderPass |
| Backends | WebGPU and WebGL2 |
| Render passes | Two separable depth-driven sampling passes |
| Required binding | depthTexture |
| Intermediate storage | One renderer-owned scratch texture |
Usage​
import {ShaderPassRenderer} from '@luma.gl/engine';
import {dofCompositeShaderPass} from '@luma.gl/engine/effects';
const renderer = new ShaderPassRenderer(device, {
shaderPasses: [dofCompositeShaderPass]
});
renderer.renderToScreen({
sourceTexture: sceneColorTexture,
bindings: {depthTexture: sceneDepthTexture},
uniforms: {
dof: {
depthRange: [0.1, 100],
focusDistance: 8,
blurCoefficient: 1.4,
pixelsPerMillimeter: 1.2
}
}
});
Parameters​
| Parameter | Default | Description |
|---|---|---|
depthRange | [0.1, 100] | Camera near and far clip distances used to reconstruct linear view depth. |
focusDistance | 1 | View-space distance of the focal plane that remains sharp. |
blurCoefficient | 1 | Lens blur strength derived from the chosen focal length and aperture. |
pixelsPerMillimeter | 1 | Conversion factor from lens-space blur size to image-space pixels. |
The implementation caps the blur radius at 20 source samples per direction. The internal
texelOffset uniform is selected by the pipeline and is intentionally excluded from the public
DofUniforms interface.
Required Inputs and Composition​
The supplied depthTexture must correspond to the same camera, viewport, and scene as the input
color texture. Apply depth of field before screen-coordinate warps and after opaque scene
rendering. Keep it before the final tone-map step when preserving HDR highlight intensity matters.
Related Effects​
- Tilt Shift approximates selective focus without a depth attachment.
- Depth-Aware Blur smooths intermediate data while preserving depth edges.
- Bloom spreads bright highlights through a separate multiscale optical pipeline.
Circular aperture bokeh​
Use bokehDof in shaderPasses and supply lens uniforms under bokehDof instead of dof
for a single-pass circular aperture. It uses 48 equal-area disk samples, avoiding the rectangular
highlights produced by separable blur. The same depth binding and public parameters apply.
The maximum blur diameter is 20 source pixels. Zero aperture preserves sharp detail.
import {bokehDof} from '@luma.gl/engine/effects';
const renderer = new ShaderPassRenderer(device, {
shaderPasses: [bokehDof],
colorFormat: 'rgba16float'
});
The normalized gather preserves HDR radiance; choose a floating-point output format and apply bloom and tone mapping afterward. This local gather does not scatter foreground silhouettes or reconstruct hidden surfaces. Large depth discontinuities can still show halos. It costs 48 color samples per defocused pixel, so use the separable pipeline when bandwidth is limited.