Skip to content

Commit 20c6bcd

Browse files
pcwaltonalice-i-cecilemockersf
authored
Allow volumetric fog to be localized to specific, optionally voxelized, regions. (#14099)
Currently, volumetric fog is global and affects the entire scene uniformly. This is inadequate for many use cases, such as local smoke effects. To address this problem, this commit introduces *fog volumes*, which are axis-aligned bounding boxes (AABBs) that specify fog parameters inside their boundaries. Such volumes can also specify a *density texture*, a 3D texture of voxels that specifies the density of the fog at each point. To create a fog volume, add a `FogVolume` component to an entity (which is included in the new `FogVolumeBundle` convenience bundle). Like light probes, a fog volume is conceptually a 1×1×1 cube centered on the origin; a transform can be used to position and resize this region. Many of the fields on the existing `VolumetricFogSettings` have migrated to the new `FogVolume` component. `VolumetricFogSettings` on a camera is still needed to enable volumetric fog. However, by itself `VolumetricFogSettings` is no longer sufficient to enable volumetric fog; a `FogVolume` must be present. Applications that wish to retain the old global fog behavior can simply surround the scene with a large fog volume. By way of implementation, this commit converts the volumetric fog shader from a full-screen shader to one applied to a mesh. The strategy is different depending on whether the camera is inside or outside the fog volume. If the camera is inside the fog volume, the mesh is simply a plane scaled to the viewport, effectively falling back to a full-screen pass. If the camera is outside the fog volume, the mesh is a cube transformed to coincide with the boundaries of the fog volume's AABB. Importantly, in the latter case, only the front faces of the cuboid are rendered. Instead of treating the boundaries of the fog as a sphere centered on the camera position, as we did prior to this patch, we raytrace the far planes of the AABB to determine the portion of each ray contained within the fog volume. We then raymarch in shadow map space as usual. If a density texture is present, we modulate the fixed density value with the trilinearly-interpolated value from that texture. Furthermore, this patch introduces optional jitter to fog volumes, intended for use with TAA. This modifies the position of the ray from frame to frame using interleaved gradient noise, in order to reduce aliasing artifacts. Many implementations of volumetric fog in games use this technique. Note that this patch makes no attempt to write a motion vector; this is because when a view ray intersects multiple voxels there's no single direction of motion. Consequently, fog volumes can have ghosting artifacts, but because fog is "ghostly" by its nature, these artifacts are less objectionable than they would be for opaque objects. A new example, `fog_volumes`, has been added. It demonstrates a single fog volume containing a voxelized representation of the Stanford bunny. The existing `volumetric_fog` example has been updated to use the new local volumetrics API. ## Changelog ### Added * Local `FogVolume`s are now supported, to localize fog to specific regions. They can optionally have 3D density voxel textures for precise control over the distribution of the fog. ### Changed * `VolumetricFogSettings` on a camera no longer enables volumetric fog; instead, it simply enables the processing of `FogVolume`s within the scene. ## Migration Guide * A `FogVolume` is now necessary in order to enable volumetric fog, in addition to `VolumetricFogSettings` on the camera. Existing uses of volumetric fog can be migrated by placing a large `FogVolume` surrounding the scene. --------- Co-authored-by: Alice Cecile <[email protected]> Co-authored-by: François Mockers <[email protected]>
1 parent ee15be8 commit 20c6bcd

File tree

9 files changed

+1160
-523
lines changed

9 files changed

+1160
-523
lines changed

Cargo.toml

+11
Original file line numberDiff line numberDiff line change
@@ -3262,6 +3262,17 @@ description = "Demonstrates how to enqueue custom draw commands in a render phas
32623262
category = "Shaders"
32633263
wasm = true
32643264

3265+
[[example]]
3266+
name = "fog_volumes"
3267+
path = "examples/3d/fog_volumes.rs"
3268+
doc-scrape-examples = true
3269+
3270+
[package.metadata.example.fog_volumes]
3271+
name = "Fog volumes"
3272+
description = "Demonstrates fog volumes"
3273+
category = "3D Rendering"
3274+
wasm = false
3275+
32653276
[[example]]
32663277
name = "physics_in_fixed_timestep"
32673278
path = "examples/movement/physics_in_fixed_timestep.rs"

assets/volumes/bunny.ktx2

1 MB
Binary file not shown.

crates/bevy_pbr/src/lib.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@ pub use prepass::*;
5757
pub use render::*;
5858
pub use ssao::*;
5959
pub use ssr::*;
60-
pub use volumetric_fog::*;
60+
pub use volumetric_fog::{
61+
FogVolume, FogVolumeBundle, VolumetricFogPlugin, VolumetricFogSettings, VolumetricLight,
62+
};
6163

6264
pub mod prelude {
6365
#[doc(hidden)]

0 commit comments

Comments
 (0)