-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Allow fog density texture to be scrolled over time with an offset (#1…
…4868) # Objective - The goal of this PR is to make it possible to move the density texture of a `FogVolume` over time in order to create dynamic effects like fog moving in the wind. - You could theoretically move the `FogVolume` itself, but this is not ideal, because the `FogVolume` AABB would eventually leave the area. If you want an area to remain foggy while also creating the impression that the fog is moving in the wind, a scrolling density texture is a better solution. ## Solution - The PR adds a `density_texture_offset` field to the `FogVolume` component. This offset is in the UVW coordinates of the density texture, meaning that a value of `(0.5, 0.0, 0.0)` moves the 3d texture by half along the x-axis. - Values above 1.0 are wrapped, a 1.5 offset is the same as a 0.5 offset. This makes it so that the density texture wraps around on the other side, meaning that a repeating 3d noise texture can seamlessly scroll forever. It also makes it easy to move the density texture over time by simply increasing the offset every frame. ## Testing - A `scrolling_fog` example has been added to demonstrate the feature. It uses the offset to scroll a repeating 3d noise density texture to create the impression of fog moving in the wind. - The camera is looking at a pillar with the sun peaking behind it. This highlights the effect the changing density has on the volumetric lighting interactions. - Temporal anti-aliasing combined with the `jitter` option of `VolumetricFogSettings` is used to improve the quality of the effect. --- ## Showcase https://github.com/user-attachments/assets/3aa50ebd-771c-4c99-ab5d-255c0c3be1a8
- Loading branch information
Showing
7 changed files
with
151 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
//! Showcases a `FogVolume`'s density texture being scrolled over time to create | ||
//! the effect of fog moving in the wind. | ||
//! | ||
//! The density texture is a repeating 3d noise texture and the `density_texture_offset` | ||
//! is moved every frame to achieve this. | ||
//! | ||
//! The example also utilizes the jitter option of `VolumetricFogSettings` in tandem | ||
//! with temporal anti-aliasing to improve the visual quality of the effect. | ||
//! | ||
//! The camera is looking at a pillar with the sun peaking behind it. The light | ||
//! interactions change based on the density of the fog. | ||
|
||
use bevy::core_pipeline::bloom::BloomSettings; | ||
use bevy::core_pipeline::experimental::taa::{TemporalAntiAliasBundle, TemporalAntiAliasPlugin}; | ||
use bevy::pbr::{DirectionalLightShadowMap, FogVolume, VolumetricFogSettings, VolumetricLight}; | ||
use bevy::prelude::*; | ||
|
||
/// Initializes the example. | ||
fn main() { | ||
App::new() | ||
.add_plugins(DefaultPlugins.set(WindowPlugin { | ||
primary_window: Some(Window { | ||
title: "Bevy Scrolling Fog".into(), | ||
..default() | ||
}), | ||
..default() | ||
})) | ||
.insert_resource(DirectionalLightShadowMap { size: 4096 }) | ||
.add_plugins(TemporalAntiAliasPlugin) | ||
.add_systems(Startup, setup) | ||
.add_systems(Update, scroll_fog) | ||
.run(); | ||
} | ||
|
||
/// Spawns all entities into the scene. | ||
fn setup( | ||
mut commands: Commands, | ||
mut meshes: ResMut<Assets<Mesh>>, | ||
mut materials: ResMut<Assets<StandardMaterial>>, | ||
assets: Res<AssetServer>, | ||
) { | ||
// Spawn camera with temporal anti-aliasing and a VolumetricFogSettings configuration. | ||
commands.spawn(( | ||
Camera3dBundle { | ||
transform: Transform::from_xyz(0.0, 2.0, 0.0) | ||
.looking_at(Vec3::new(-5.0, 3.5, -6.0), Vec3::Y), | ||
camera: Camera { | ||
hdr: true, | ||
..default() | ||
}, | ||
msaa: Msaa::Off, | ||
..default() | ||
}, | ||
TemporalAntiAliasBundle::default(), | ||
BloomSettings::default(), | ||
VolumetricFogSettings { | ||
ambient_intensity: 0.0, | ||
jitter: 0.5, | ||
..default() | ||
}, | ||
)); | ||
|
||
// Spawn a directional light shining at the camera with the VolumetricLight component. | ||
commands.spawn(( | ||
DirectionalLightBundle { | ||
transform: Transform::from_xyz(-5.0, 5.0, -7.0) | ||
.looking_at(Vec3::new(0.0, 0.0, 0.0), Vec3::Y), | ||
directional_light: DirectionalLight { | ||
shadows_enabled: true, | ||
..default() | ||
}, | ||
..default() | ||
}, | ||
VolumetricLight, | ||
)); | ||
|
||
// Spawn ground mesh. | ||
commands.spawn(PbrBundle { | ||
transform: Transform::from_xyz(0.0, -0.5, 0.0), | ||
mesh: meshes.add(Cuboid::new(64.0, 1.0, 64.0)), | ||
material: materials.add(StandardMaterial { | ||
base_color: Color::BLACK, | ||
perceptual_roughness: 1.0, | ||
..default() | ||
}), | ||
..default() | ||
}); | ||
|
||
// Spawn pillar standing between the camera and the sun. | ||
commands.spawn(PbrBundle { | ||
transform: Transform::from_xyz(-10.0, 4.5, -11.0), | ||
mesh: meshes.add(Cuboid::new(2.0, 9.0, 2.0)), | ||
material: materials.add(Color::BLACK), | ||
..default() | ||
}); | ||
|
||
// Spawn FogVolume with repeating 3d noise density texture. | ||
commands.spawn(( | ||
SpatialBundle { | ||
visibility: Visibility::Visible, | ||
transform: Transform::from_xyz(0.0, 32.0, 0.0).with_scale(Vec3::splat(64.0)), | ||
..default() | ||
}, | ||
FogVolume { | ||
density_texture: Some(assets.load("volumes/fog_noise.ktx2")), | ||
density_factor: 0.05, | ||
..default() | ||
}, | ||
)); | ||
} | ||
|
||
/// Moves fog density texture offset every frame. | ||
fn scroll_fog(time: Res<Time>, mut query: Query<&mut FogVolume>) { | ||
for mut fog_volume in query.iter_mut() { | ||
fog_volume.density_texture_offset += Vec3::new(0.0, 0.0, 0.04) * time.delta_seconds(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters