Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/examples/3d/atmospheric_fog.rs
6592 views
1
//! This example showcases atmospheric fog
2
//!
3
//! ## Controls
4
//!
5
//! | Key Binding | Action |
6
//! |:-------------------|:---------------------------------------|
7
//! | `Spacebar` | Toggle Atmospheric Fog |
8
//! | `S` | Toggle Directional Light Fog Influence |
9
10
use bevy::{
11
light::{CascadeShadowConfigBuilder, NotShadowCaster},
12
prelude::*,
13
};
14
15
fn main() {
16
App::new()
17
.add_plugins(DefaultPlugins)
18
.add_systems(
19
Startup,
20
(setup_camera_fog, setup_terrain_scene, setup_instructions),
21
)
22
.add_systems(Update, toggle_system)
23
.run();
24
}
25
26
fn setup_camera_fog(mut commands: Commands) {
27
commands.spawn((
28
Camera3d::default(),
29
Transform::from_xyz(-1.0, 0.1, 1.0).looking_at(Vec3::new(0.0, 0.0, 0.0), Vec3::Y),
30
DistanceFog {
31
color: Color::srgba(0.35, 0.48, 0.66, 1.0),
32
directional_light_color: Color::srgba(1.0, 0.95, 0.85, 0.5),
33
directional_light_exponent: 30.0,
34
falloff: FogFalloff::from_visibility_colors(
35
15.0, // distance in world units up to which objects retain visibility (>= 5% contrast)
36
Color::srgb(0.35, 0.5, 0.66), // atmospheric extinction color (after light is lost due to absorption by atmospheric particles)
37
Color::srgb(0.8, 0.844, 1.0), // atmospheric inscattering color (light gained due to scattering from the sun)
38
),
39
},
40
));
41
}
42
43
fn setup_terrain_scene(
44
mut commands: Commands,
45
mut meshes: ResMut<Assets<Mesh>>,
46
mut materials: ResMut<Assets<StandardMaterial>>,
47
asset_server: Res<AssetServer>,
48
) {
49
// Configure a properly scaled cascade shadow map for this scene (defaults are too large, mesh units are in km)
50
let cascade_shadow_config = CascadeShadowConfigBuilder {
51
first_cascade_far_bound: 0.3,
52
maximum_distance: 3.0,
53
..default()
54
}
55
.build();
56
57
// Sun
58
commands.spawn((
59
DirectionalLight {
60
color: Color::srgb(0.98, 0.95, 0.82),
61
shadows_enabled: true,
62
..default()
63
},
64
Transform::from_xyz(0.0, 0.0, 0.0).looking_at(Vec3::new(-0.15, -0.05, 0.25), Vec3::Y),
65
cascade_shadow_config,
66
));
67
68
// Terrain
69
commands.spawn(SceneRoot(asset_server.load(
70
GltfAssetLabel::Scene(0).from_asset("models/terrain/Mountains.gltf"),
71
)));
72
73
// Sky
74
commands.spawn((
75
Mesh3d(meshes.add(Cuboid::new(2.0, 1.0, 1.0))),
76
MeshMaterial3d(materials.add(StandardMaterial {
77
base_color: Srgba::hex("888888").unwrap().into(),
78
unlit: true,
79
cull_mode: None,
80
..default()
81
})),
82
Transform::from_scale(Vec3::splat(20.0)),
83
NotShadowCaster,
84
));
85
}
86
87
fn setup_instructions(mut commands: Commands) {
88
commands.spawn((Text::new("Press Spacebar to Toggle Atmospheric Fog.\nPress S to Toggle Directional Light Fog Influence."),
89
Node {
90
position_type: PositionType::Absolute,
91
bottom: px(12),
92
left: px(12),
93
..default()
94
})
95
);
96
}
97
98
fn toggle_system(keycode: Res<ButtonInput<KeyCode>>, mut fog: Single<&mut DistanceFog>) {
99
if keycode.just_pressed(KeyCode::Space) {
100
let a = fog.color.alpha();
101
fog.color.set_alpha(1.0 - a);
102
}
103
104
if keycode.just_pressed(KeyCode::KeyS) {
105
let a = fog.directional_light_color.alpha();
106
fog.directional_light_color.set_alpha(0.5 - a);
107
}
108
}
109
110