Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commitdd348ac6c3

README.md

bokehBlur

The render feature behind DepthOfField and @builtin::systems.depthOfField.depthOfField. Two compute passes run after lighting:

orderpassoutput
300dof_cocthe signed circle of confusion each pixel projects, in pixels
302dof_gathera disc gather at that radius, and the composite

The circle of confusion

A point at distance d images as a disc whose diameter follows from focal length, aperture and where the lens is focused — the thin-lens relation. Deriving the blur radius that way is what makes fStop and focalLength behave the way they do on a camera instead of being two more arbitrary sliders.

It is stored signed: negative in front of the focal plane, positive behind it. The two fields are not symmetric — a near blur spills over what it occludes and a far blur does not — and the sign is what lets the gather tell them apart.

The sky sits at the far plane and takes the full far-field radius rather than a distance that would divide badly.

The gather

Taps follow a golden-angle spiral: even coverage of the disc with no stored sample table and no directional structure for the eye to catch.

Each tap contributes only if its OWN circle of confusion is wide enough to reach the pixel gathering it — scatter expressed as a gather. Without that test a sharp foreground bleeds outward onto a blurred background, which is the classic tell of a defocus that was applied rather than photographed.

Weights are 1/spread², so a wide circle contributes proportionally less per sample than a tight one — energy spread over a larger disc. The centre pixel is weighted by the same rule as every tap; seeding it at 1 while taps carry 1/spread² would let it outweigh the whole disc.

Parameters arrive through the dof_params buffer, packed by @builtin::systems.depthOfField.depthOfField.