//! 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>, mut materials: ResMut>, assets: Res, ) { // 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