1use std::f32::consts::PI;
4
5use bevy::{
6 camera::Exposure,
7 core_pipeline::tonemapping::Tonemapping,
8 light::{light_consts::lux, AtmosphereEnvironmentMapLight, CascadeShadowConfigBuilder},
9 pbr::{Atmosphere, AtmosphereSettings},
10 post_process::bloom::Bloom,
11 prelude::*,
12};
13
14fn main() {
15 App::new()
16 .add_plugins(DefaultPlugins)
17 .add_systems(Startup, (setup_camera_fog, setup_terrain_scene))
18 .add_systems(Update, dynamic_scene)
19 .run();
20}
21
22fn setup_camera_fog(mut commands: Commands) {
23 commands.spawn((
24 Camera3d::default(),
25 Transform::from_xyz(-1.2, 0.15, 0.0).looking_at(Vec3::Y * 0.1, Vec3::Y),
26 Atmosphere::EARTH,
28 AtmosphereSettings {
32 aerial_view_lut_max_distance: 3.2e5,
33 scene_units_to_m: 1e+4,
34 ..Default::default()
35 },
36 Exposure::SUNLIGHT,
41 Tonemapping::AcesFitted,
44 Bloom::NATURAL,
46 AtmosphereEnvironmentMapLight::default(),
48 ));
49}
50
51#[derive(Component)]
52struct Terrain;
53
54fn setup_terrain_scene(
55 mut commands: Commands,
56 mut meshes: ResMut<Assets<Mesh>>,
57 mut materials: ResMut<Assets<StandardMaterial>>,
58 asset_server: Res<AssetServer>,
59) {
60 let cascade_shadow_config = CascadeShadowConfigBuilder {
62 first_cascade_far_bound: 0.3,
63 maximum_distance: 3.0,
64 ..default()
65 }
66 .build();
67
68 commands.spawn((
70 DirectionalLight {
71 shadows_enabled: true,
72 illuminance: lux::RAW_SUNLIGHT,
78 ..default()
79 },
80 Transform::from_xyz(1.0, -0.4, 0.0).looking_at(Vec3::ZERO, Vec3::Y),
81 cascade_shadow_config,
82 ));
83
84 let sphere_mesh = meshes.add(Mesh::from(Sphere { radius: 1.0 }));
85
86 commands.spawn((
88 Mesh3d(sphere_mesh.clone()),
89 MeshMaterial3d(materials.add(StandardMaterial {
90 base_color: Color::WHITE,
91 metallic: 1.0,
92 perceptual_roughness: 0.0,
93 ..default()
94 })),
95 Transform::from_xyz(-0.3, 0.1, -0.1).with_scale(Vec3::splat(0.05)),
96 ));
97
98 commands.spawn((
99 Mesh3d(sphere_mesh.clone()),
100 MeshMaterial3d(materials.add(StandardMaterial {
101 base_color: Color::WHITE,
102 metallic: 0.0,
103 perceptual_roughness: 1.0,
104 ..default()
105 })),
106 Transform::from_xyz(-0.3, 0.1, 0.1).with_scale(Vec3::splat(0.05)),
107 ));
108
109 commands.spawn((
111 Terrain,
112 SceneRoot(
113 asset_server.load(GltfAssetLabel::Scene(0).from_asset("models/terrain/terrain.glb")),
114 ),
115 Transform::from_xyz(-1.0, 0.0, -0.5)
116 .with_scale(Vec3::splat(0.5))
117 .with_rotation(Quat::from_rotation_y(PI / 2.0)),
118 ));
119}
120
121fn dynamic_scene(mut suns: Query<&mut Transform, With<DirectionalLight>>, time: Res<Time>) {
122 suns.iter_mut()
123 .for_each(|mut tf| tf.rotate_x(-time.delta_secs() * PI / 10.0));
124}