1use bevy::camera_controller::free_camera::{FreeCamera, FreeCameraPlugin};
4use bevy::prelude::*;
5
6fn main() {
7 App::new()
8 .add_plugins((
9 DefaultPlugins.set(WindowPlugin {
10 primary_window: Some(Window {
11 present_mode: bevy::window::PresentMode::Mailbox,
12 ..default()
13 }),
14 ..default()
15 }),
16 FreeCameraPlugin,
17 ))
18 .add_systems(Startup, setup)
19 .add_systems(Update, (toggle_gizmos, adjust_roughness))
20 .run();
21}
22
23#[derive(Resource)]
24struct FloorMaterial(Handle<StandardMaterial>);
25
26#[derive(Component)]
27struct RoughnessDisplay;
28
29fn setup(
31 mut commands: Commands,
32 mut meshes: ResMut<Assets<Mesh>>,
33 mut materials: ResMut<Assets<StandardMaterial>>,
34) {
35 let floor_material = materials.add(StandardMaterial {
36 base_color: Color::WHITE,
37 metallic: 1.0,
38 perceptual_roughness: 0.6,
39 ..default()
40 });
41 commands.insert_resource(FloorMaterial(floor_material.clone()));
42 commands.spawn((
43 Mesh3d(meshes.add(Plane3d::default().mesh().size(20.0, 20.0))),
44 MeshMaterial3d(floor_material),
45 ));
46
47 commands.spawn((
48 Mesh3d(meshes.add(Sphere::new(1.0))),
49 MeshMaterial3d(materials.add(Color::WHITE)),
50 Transform::from_xyz(0.0, 1.0, 0.0),
51 ));
52
53 commands.spawn((
55 RectLight {
56 color: Color::srgb(1.0, 0.3, 0.2),
57 intensity: 100_000.0,
58 width: 2.0,
59 height: 1.0,
60 range: 20.0,
61 },
62 ShowLightGizmo::default(),
63 Transform::from_xyz(1.0, 3.0, 1.0).looking_at(Vec3::Y, Vec3::Y),
64 ));
65
66 commands.spawn((
67 RectLight {
68 color: Color::srgb(0.5, 0.7, 1.0),
69 intensity: 800_000.0,
70 width: 1.5,
71 height: 4.0,
72 range: 20.0,
73 },
74 ShowLightGizmo::default(),
75 Transform::from_xyz(-2.0, 1.5, -3.0)
76 .with_rotation(Quat::from_rotation_y(std::f32::consts::PI)),
77 ));
78
79 commands.spawn((
80 Camera3d::default(),
81 Transform::from_xyz(-8.0, 5.0, 8.0).looking_at(Vec3::Y, Vec3::Y),
82 FreeCamera::default(),
83 ));
84
85 commands.spawn((
86 Text::new("Controls\nArrow Up/Down: Adjust floor roughness\nG: Toggle light gizmos\n\nRoughness: 0.60"),
87 TextFont {
88 font_size: FontSize::Px(18.0),
89 ..default()
90 },
91 TextColor(Color::srgb(0.9, 0.9, 0.9)),
92 Node {
93 position_type: PositionType::Absolute,
94 top: px(12),
95 left: px(12),
96 ..default()
97 },
98 RoughnessDisplay,
99 ));
100}
101
102fn adjust_roughness(
104 keys: Res<ButtonInput<KeyCode>>,
105 floor_material: Res<FloorMaterial>,
106 mut materials: ResMut<Assets<StandardMaterial>>,
107 mut text_query: Query<&mut Text, With<RoughnessDisplay>>,
108) {
109 let delta = if keys.pressed(KeyCode::ArrowUp) {
110 0.005
111 } else if keys.pressed(KeyCode::ArrowDown) {
112 -0.005
113 } else {
114 return;
115 };
116
117 if let Some(mut material) = materials.get_mut(&floor_material.0) {
118 material.perceptual_roughness = (material.perceptual_roughness + delta).clamp(0.0, 1.0);
119
120 if let Ok(mut text) = text_query.single_mut() {
121 **text = format!(
122 "Controls\nArrow Up/Down: Adjust floor roughness\nG: Toggle light gizmos\n\nRoughness: {:.2}",
123 material.perceptual_roughness
124 );
125 }
126 }
127}
128
129fn toggle_gizmos(keys: Res<ButtonInput<KeyCode>>, mut config_store: ResMut<GizmoConfigStore>) {
130 if keys.just_pressed(KeyCode::KeyG) {
131 let (config, light_config) = config_store.config_mut::<LightGizmoConfigGroup>();
132 light_config.draw_all = false;
133 config.enabled = !config.enabled;
134 }
135}