bevy/crates
Patrick Walton df31b808c3
Implement fast depth of field as a postprocessing effect. (#13009)
This commit implements the [depth of field] effect, simulating the blur
of objects out of focus of the virtual lens. Either the [hexagonal
bokeh] effect or a faster Gaussian blur may be used. In both cases, the
implementation is a simple separable two-pass convolution. This is not
the most physically-accurate real-time bokeh technique that exists;
Unreal Engine has [a more accurate implementation] of "cinematic depth
of field" from 2018. However, it's simple, and most engines provide
something similar as a fast option, often called "mobile" depth of
field.

The general approach is outlined in [a blog post from 2017]. We take
advantage of the fact that both Gaussian blurs and hexagonal bokeh blurs
are *separable*. This means that their 2D kernels can be reduced to a
small number of 1D kernels applied one after another, asymptotically
reducing the amount of work that has to be done. Gaussian blurs can be
accomplished by blurring horizontally and then vertically, while
hexagonal bokeh blurs can be done with a vertical blur plus a diagonal
blur, plus two diagonal blurs. In both cases, only two passes are
needed. Bokeh requires the first pass to have a second render target and
requires two subpasses in the second pass, which decreases its
performance relative to the Gaussian blur.

The bokeh blur is generally more aesthetically pleasing than the
Gaussian blur, as it simulates the effect of a camera more accurately.
The shape of the bokeh circles are determined by the number of blades of
the aperture. In our case, we use a hexagon, which is usually considered
specific to lower-quality cameras. (This is a downside of the fast
hexagon approach compared to the higher-quality approaches.) The blur
amount is generally specified by the [f-number], which we use to compute
the focal length from the film size and FOV. By default, we simulate
standard cinematic cameras of f/1 and [Super 35]. The developer can
customize these values as desired.

A new example has been added to demonstrate depth of field. It allows
customization of the mode (Gaussian vs. bokeh), focal distance and
f-numbers. The test scene is inspired by a [blog post on depth of field
in Unity]; however, the effect is implemented in a completely different
way from that blog post, and all the assets (textures, etc.) are
original.

Bokeh depth of field:
![Screenshot 2024-04-17
152535](https://github.com/bevyengine/bevy/assets/157897/702f0008-1c8a-4cf3-b077-4110f8c46584)

Gaussian depth of field:
![Screenshot 2024-04-17
152542](https://github.com/bevyengine/bevy/assets/157897/f4ece47a-520e-4483-a92d-f4fa760795d3)

No depth of field:
![Screenshot 2024-04-17
152547](https://github.com/bevyengine/bevy/assets/157897/9444e6aa-fcae-446c-b66b-89469f1a1325)

[depth of field]: https://en.wikipedia.org/wiki/Depth_of_field

[hexagonal bokeh]:
https://colinbarrebrisebois.com/2017/04/18/hexagonal-bokeh-blur-revisited/

[a more accurate implementation]:
https://epicgames.ent.box.com/s/s86j70iamxvsuu6j35pilypficznec04

[a blog post from 2017]:
https://colinbarrebrisebois.com/2017/04/18/hexagonal-bokeh-blur-revisited/

[f-number]: https://en.wikipedia.org/wiki/F-number

[Super 35]: https://en.wikipedia.org/wiki/Super_35

[blog post on depth of field in Unity]:
https://catlikecoding.com/unity/tutorials/advanced-rendering/depth-of-field/

## Changelog

### Added

* A depth of field postprocessing effect is now available, to simulate
objects being out of focus of the camera. To use it, add
`DepthOfFieldSettings` to an entity containing a `Camera3d` component.

---------

Co-authored-by: Alice Cecile <alice.i.cecile@gmail.com>
Co-authored-by: Bram Buurlage <brambuurlage@gmail.com>
2024-05-13 18:23:56 +00:00
..
bevy_a11y Add README.md to all crates (#13184) 2024-05-02 18:56:00 +00:00
bevy_animation Remove ClampColor (#13307) 2024-05-10 13:15:56 +00:00
bevy_app Separate state crate (#13216) 2024-05-09 18:06:05 +00:00
bevy_asset bevy_asset: Add missing web-sys feature and cleanup unused ones (#13281) 2024-05-12 20:53:59 +00:00
bevy_audio Add README.md to all crates (#13184) 2024-05-02 18:56:00 +00:00
bevy_color Remove ClampColor (#13307) 2024-05-10 13:15:56 +00:00
bevy_core bevy_core: Derive useful traits on FrameCount (#13291) 2024-05-10 10:00:08 +00:00
bevy_core_pipeline Implement fast depth of field as a postprocessing effect. (#13009) 2024-05-13 18:23:56 +00:00
bevy_derive Update compile test to use ui_test 0.23 (#13245) 2024-05-05 22:17:56 +00:00
bevy_dev_tools new format for ci config file (#13154) 2024-05-02 22:51:47 +00:00
bevy_diagnostic Add README.md to all crates (#13184) 2024-05-02 18:56:00 +00:00
bevy_dylib Add README.md to all crates (#13184) 2024-05-02 18:56:00 +00:00
bevy_dynamic_plugin Add README.md to all crates (#13184) 2024-05-02 18:56:00 +00:00
bevy_ecs Separate state crate (#13216) 2024-05-09 18:06:05 +00:00
bevy_encase_derive Add README.md to all crates (#13184) 2024-05-02 18:56:00 +00:00
bevy_gilrs Add README.md to all crates (#13184) 2024-05-02 18:56:00 +00:00
bevy_gizmos gizmos: take normal of normal on plane 3d before rotation (#13326) 2024-05-11 19:32:31 +00:00
bevy_gltf Add UV channel selection to StandardMaterial (#13200) 2024-05-13 18:23:09 +00:00
bevy_hierarchy Add README.md to all crates (#13184) 2024-05-02 18:56:00 +00:00
bevy_input Separate state crate (#13216) 2024-05-09 18:06:05 +00:00
bevy_internal Separate state crate (#13216) 2024-05-09 18:06:05 +00:00
bevy_log Improve tracing layer customization (#13159) 2024-05-12 21:16:56 +00:00
bevy_macro_utils Add README.md to all crates (#13184) 2024-05-02 18:56:00 +00:00
bevy_math Add meshing for Cone (#11820) 2024-05-13 18:00:59 +00:00
bevy_mikktspace Update glam version requirement from 0.25 to 0.27 (#12757) 2024-05-02 18:42:34 +00:00
bevy_pbr Add UV channel selection to StandardMaterial (#13200) 2024-05-13 18:23:09 +00:00
bevy_ptr Add README.md to all crates (#13184) 2024-05-02 18:56:00 +00:00
bevy_reflect Avoid bevy_reflect::List::iter wrapping in release mode (#13271) 2024-05-12 15:01:05 +00:00
bevy_render Implement fast depth of field as a postprocessing effect. (#13009) 2024-05-13 18:23:56 +00:00
bevy_scene Add README.md to all crates (#13184) 2024-05-02 18:56:00 +00:00
bevy_sprite Clean up 2d render phases (#12982) 2024-05-08 08:13:39 +00:00
bevy_state State example (#13322) 2024-05-13 13:03:42 +00:00
bevy_tasks multi_threaded feature rename (#12997) 2024-05-06 20:49:32 +00:00
bevy_text Add doc comments explaining the different behaviours of alignment and Anchor with text_2d (#8022) 2024-05-12 21:42:04 +00:00
bevy_time Make bevy_time optionally depend on bevy_reflect (#13263) 2024-05-12 23:19:07 +00:00
bevy_transform Use Dir3 for local axis methods in GlobalTransform (#13264) 2024-05-06 20:52:05 +00:00
bevy_ui Clean up 2d render phases (#12982) 2024-05-08 08:13:39 +00:00
bevy_utils Add README.md to all crates (#13184) 2024-05-02 18:56:00 +00:00
bevy_window Ensure clean exit (#13236) 2024-05-12 15:56:01 +00:00
bevy_winit Ensure clean exit (#13236) 2024-05-12 15:56:01 +00:00