bevy/examples/3d
Patrick Walton 19bfa41768
Implement volumetric fog and volumetric lighting, also known as light shafts or god rays. (#13057)
This commit implements a more physically-accurate, but slower, form of
fog than the `bevy_pbr::fog` module does. Notably, this *volumetric fog*
allows for light beams from directional lights to shine through,
creating what is known as *light shafts* or *god rays*.

To add volumetric fog to a scene, add `VolumetricFogSettings` to the
camera, and add `VolumetricLight` to directional lights that you wish to
be volumetric. `VolumetricFogSettings` has numerous settings that allow
you to define the accuracy of the simulation, as well as the look of the
fog. Currently, only interaction with directional lights that have
shadow maps is supported. Note that the overhead of the effect scales
directly with the number of directional lights in use, so apply
`VolumetricLight` sparingly for the best results.

The overall algorithm, which is implemented as a postprocessing effect,
is a combination of the techniques described in [Scratchapixel] and
[this blog post]. It uses raymarching in screen space, transformed into
shadow map space for sampling and combined with physically-based
modeling of absorption and scattering. Bevy employs the widely-used
[Henyey-Greenstein phase function] to model asymmetry; this essentially
allows light shafts to fade into and out of existence as the user views
them.

Volumetric rendering is a huge subject, and I deliberately kept the
scope of this commit small. Possible follow-ups include:

1. Raymarching at a lower resolution.

2. A post-processing blur (especially useful when combined with (1)).

3. Supporting point lights and spot lights.

4. Supporting lights with no shadow maps.

5. Supporting irradiance volumes and reflection probes.

6. Voxel components that reuse the volumetric fog code to create voxel
shapes.

7. *Horizon: Zero Dawn*-style clouds.

These are all useful, but out of scope of this patch for now, to keep
things tidy and easy to review.

A new example, `volumetric_fog`, has been added to demonstrate the
effect.

## Changelog

### Added

* A new component, `VolumetricFog`, is available, to allow for a more
physically-accurate, but more resource-intensive, form of fog.

* A new component, `VolumetricLight`, can be placed on directional
lights to make them interact with `VolumetricFog`. Notably, this allows
such lights to emit light shafts/god rays.

![Screenshot 2024-04-21
162808](https://github.com/bevyengine/bevy/assets/157897/7a1fc81d-eed5-4735-9419-286c496391a9)

![Screenshot 2024-04-21
132005](https://github.com/bevyengine/bevy/assets/157897/e6d3b5ca-8f59-488d-a3de-15e95aaf4995)

[Scratchapixel]:
https://www.scratchapixel.com/lessons/3d-basic-rendering/volume-rendering-for-developers/intro-volume-rendering.html

[this blog post]: https://www.alexandre-pestana.com/volumetric-lights/

[Henyey-Greenstein phase function]:
https://www.pbr-book.org/4ed/Volume_Scattering/Phase_Functions#TheHenyeyndashGreensteinPhaseFunction
2024-05-16 17:13:18 +00:00
..
3d_scene.rs Migrate from LegacyColor to bevy_color::Color (#12163) 2024-02-29 19:35:12 +00:00
3d_shapes.rs Add meshing for Cone (#11820) 2024-05-13 18:00:59 +00:00
3d_viewport_to_world.rs Use Dir3 for local axis methods in GlobalTransform (#13264) 2024-05-06 20:52:05 +00:00
animated_material.rs Add hue traits (#12399) 2024-03-22 00:36:46 +00:00
anti_aliasing.rs Migrate from LegacyColor to bevy_color::Color (#12163) 2024-02-29 19:35:12 +00:00
atmospheric_fog.rs Migrate from LegacyColor to bevy_color::Color (#12163) 2024-02-29 19:35:12 +00:00
auto_exposure.rs Implement Auto Exposure plugin (#12792) 2024-05-03 17:45:17 +00:00
blend_modes.rs Migrate from LegacyColor to bevy_color::Color (#12163) 2024-02-29 19:35:12 +00:00
bloom_3d.rs Improve Bloom 3D lighting (#11981) 2024-03-07 15:20:38 +00:00
clearcoat.rs Implement clearcoat per the Filament and the KHR_materials_clearcoat specifications. (#13031) 2024-05-05 22:57:05 +00:00
color_grading.rs Fix CI error on new color grading example (#13180) 2024-05-02 13:40:45 +00:00
deferred_rendering.rs Implement GPU frustum culling. (#12889) 2024-04-28 12:50:00 +00:00
depth_of_field.rs Implement fast depth of field as a postprocessing effect. (#13009) 2024-05-13 18:23:56 +00:00
fog.rs Migrate from LegacyColor to bevy_color::Color (#12163) 2024-02-29 19:35:12 +00:00
generate_custom_mesh.rs Clarify comment about camera coordinate system (#13056) 2024-04-23 14:58:28 +00:00
irradiance_volumes.rs separating finite and infinite 3d planes (#12426) 2024-04-18 14:13:22 +00:00
lighting.rs Implement fast depth of field as a postprocessing effect. (#13009) 2024-05-13 18:23:56 +00:00
lightmaps.rs fix example lightmaps after color migration (#12265) 2024-03-03 21:36:11 +00:00
lines.rs Intern mesh vertex buffer layouts so that we don't have to compare them over and over. (#12216) 2024-03-01 20:56:21 +00:00
load_gltf.rs New Exposure and Lighting Defaults (and calibrate examples) (#11868) 2024-02-15 20:42:48 +00:00
meshlet.rs Example setup for tooling (#13088) 2024-05-02 20:10:09 +00:00
motion_blur.rs Fix motion blur on wasm (#13099) 2024-05-12 21:03:36 +00:00
orthographic.rs Migrate from LegacyColor to bevy_color::Color (#12163) 2024-02-29 19:35:12 +00:00
parallax_mapping.rs Move close_on_esc to bevy_dev_tools (#12855) 2024-04-03 01:29:06 +00:00
parenting.rs Migrate from LegacyColor to bevy_color::Color (#12163) 2024-02-29 19:35:12 +00:00
pbr.rs Migrate from LegacyColor to bevy_color::Color (#12163) 2024-02-29 19:35:12 +00:00
reflection_probes.rs Migrate from LegacyColor to bevy_color::Color (#12163) 2024-02-29 19:35:12 +00:00
render_to_texture.rs #12502 Remove limit on RenderLayers. (#13317) 2024-05-16 16:15:47 +00:00
shadow_biases.rs Implement percentage-closer filtering (PCF) for point lights. (#12910) 2024-04-10 20:16:08 +00:00
shadow_caster_receiver.rs Remove redundant imports (#12817) 2024-04-01 19:59:08 +00:00
skybox.rs Migrate from LegacyColor to bevy_color::Color (#12163) 2024-02-29 19:35:12 +00:00
spherical_area_lights.rs Migrate from LegacyColor to bevy_color::Color (#12163) 2024-02-29 19:35:12 +00:00
split_screen.rs Fix "dark grey" colors becoming lighter in various examples (#12333) 2024-03-06 05:19:59 +00:00
spotlight.rs Adding explanation to seeded rng used in examples (#12593) 2024-03-26 19:40:18 +00:00
ssao.rs Migrate from LegacyColor to bevy_color::Color (#12163) 2024-02-29 19:35:12 +00:00
texture.rs Migrate from LegacyColor to bevy_color::Color (#12163) 2024-02-29 19:35:12 +00:00
tonemapping.rs Implement filmic color grading. (#13121) 2024-05-02 12:18:59 +00:00
transmission.rs Implement filmic color grading. (#13121) 2024-05-02 12:18:59 +00:00
transparency_3d.rs Implement alpha to coverage (A2C) support. (#12970) 2024-04-15 20:37:52 +00:00
two_passes.rs Migrate from LegacyColor to bevy_color::Color (#12163) 2024-02-29 19:35:12 +00:00
update_gltf_scene.rs New Exposure and Lighting Defaults (and calibrate examples) (#11868) 2024-02-15 20:42:48 +00:00
vertex_colors.rs Migrate from LegacyColor to bevy_color::Color (#12163) 2024-02-29 19:35:12 +00:00
visibility_range.rs Implement visibility ranges, also known as hierarchical levels of detail (HLODs). (#12916) 2024-05-03 00:11:35 +00:00
volumetric_fog.rs Implement volumetric fog and volumetric lighting, also known as light shafts or god rays. (#13057) 2024-05-16 17:13:18 +00:00
wireframe.rs Use WireframeColor to override global color (#13034) 2024-04-20 13:59:12 +00:00