atmosphere: set dynamic fog density based on altitude

This commit is contained in:
yuni 2024-11-29 19:48:50 +01:00
parent a98c1d3d3a
commit 5dd2936e52
2 changed files with 24 additions and 6 deletions

View file

@ -16,7 +16,7 @@ use crate::prelude::*;
use bevy::core_pipeline::bloom::{BloomCompositeMode, BloomSettings}; use bevy::core_pipeline::bloom::{BloomCompositeMode, BloomSettings};
use bevy::core_pipeline::tonemapping::Tonemapping; use bevy::core_pipeline::tonemapping::Tonemapping;
use bevy::input::mouse::{MouseMotion, MouseWheel}; use bevy::input::mouse::{MouseMotion, MouseWheel};
use bevy::pbr::{CascadeShadowConfigBuilder, DirectionalLightShadowMap}; use bevy::pbr::{CascadeShadowConfigBuilder, DirectionalLightShadowMap, VolumetricFogSettings, VolumetricLight};
use bevy::prelude::*; use bevy::prelude::*;
use bevy::transform::TransformSystem; use bevy::transform::TransformSystem;
use bevy::window::PrimaryWindow; use bevy::window::PrimaryWindow;
@ -33,6 +33,7 @@ impl Plugin for CameraPlugin {
app.add_systems(Startup, setup_camera); app.add_systems(Startup, setup_camera);
app.add_systems(Update, handle_input.run_if(in_control).run_if(game_running)); app.add_systems(Update, handle_input.run_if(in_control).run_if(game_running));
app.add_systems(Update, tweak_scene); app.add_systems(Update, tweak_scene);
app.add_systems(Update, update_volumetric_fog);
app.add_systems( app.add_systems(
Update, Update,
update_map_only_object_visibility update_map_only_object_visibility
@ -148,7 +149,8 @@ pub fn setup_camera(
transform: Transform::from_xyz(0.0, 0.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y), transform: Transform::from_xyz(0.0, 0.0, 8.0).looking_at(Vec3::ZERO, Vec3::Y),
..default() ..default()
}, },
bevy::pbr::VolumetricFogSettings { VolumetricFogSettings {
fog_color: Color::srgb(0.78, 0.76, 0.7),
// This value is explicitly set to 0 since we have no environment map light // This value is explicitly set to 0 since we have no environment map light
ambient_intensity: 0.0, ambient_intensity: 0.0,
absorption: 0.1, absorption: 0.1,
@ -810,6 +812,22 @@ fn tweak_scene(
for (light, mut directional_light) in lights.iter_mut() { for (light, mut directional_light) in lights.iter_mut() {
// Shadows are needed for volumetric lights to work. // Shadows are needed for volumetric lights to work.
directional_light.shadows_enabled = true; directional_light.shadows_enabled = true;
commands.entity(light).insert(bevy::pbr::VolumetricLight); commands.entity(light).insert(VolumetricLight);
}
}
pub fn update_volumetric_fog(settings: Res<Settings>, mut q_fog: Query<&mut VolumetricFogSettings>) {
let mut fog = if let Ok(x) = q_fog.get_single_mut() {
x
} else {
return;
};
if let Some(x) = settings.atmo_altitude {
// exponential regression with [(-1e5, 1.0), (0, 0.2), (20e5, 0.01)]
let density = 0.2 * 0.9999839f32.powf(x as f32);
fog.density = density;
} else {
fog.density = 0.0;
} }
} }

View file

@ -11,7 +11,7 @@
// This module manages visual effects. // This module manages visual effects.
use crate::prelude::*; use crate::prelude::*;
use bevy::pbr::NotShadowReceiver; //use bevy::pbr::NotShadowReceiver;
use bevy::prelude::*; use bevy::prelude::*;
use bevy_xpbd_3d::prelude::*; use bevy_xpbd_3d::prelude::*;
use std::time::Duration; use std::time::Duration;
@ -103,8 +103,8 @@ pub fn setup(
mut commands: Commands, mut commands: Commands,
mut ew_effect: EventWriter<SpawnEffectEvent>, mut ew_effect: EventWriter<SpawnEffectEvent>,
mut graphs: ResMut<Assets<AnimationGraph>>, mut graphs: ResMut<Assets<AnimationGraph>>,
mut materials: ResMut<Assets<StandardMaterial>>, //mut materials: ResMut<Assets<StandardMaterial>>,
mut meshes: ResMut<Assets<Mesh>>, //mut meshes: ResMut<Assets<Mesh>>,
) { ) {
if !settings.dev_mode { if !settings.dev_mode {
ew_effect.send(SpawnEffectEvent { ew_effect.send(SpawnEffectEvent {