Skip to main content

many_cameras_lights/
many_cameras_lights.rs

1//! Test rendering of many cameras and lights
2
3use std::f32::consts::PI;
4
5use bevy::{
6    camera::Viewport,
7    math::ops::{cos, sin},
8    prelude::*,
9    window::{PresentMode, WindowResolution},
10    winit::WinitSettings,
11};
12
13fn main() {
14    App::new()
15        .add_plugins(DefaultPlugins.set(WindowPlugin {
16            primary_window: Some(Window {
17                present_mode: PresentMode::AutoNoVsync,
18                resolution: WindowResolution::new(1920, 1080).with_scale_factor_override(1.0),
19                ..default()
20            }),
21            ..default()
22        }))
23        .insert_resource(WinitSettings::continuous())
24        .add_systems(Startup, setup)
25        .add_systems(Update, rotate_cameras)
26        .run();
27}
28
29const CAMERA_ROWS: usize = 4;
30const CAMERA_COLS: usize = 4;
31const NUM_LIGHTS: usize = 5;
32
33/// set up a simple 3D scene
34fn setup(
35    mut commands: Commands,
36    mut meshes: ResMut<Assets<Mesh>>,
37    mut materials: ResMut<Assets<StandardMaterial>>,
38    window: Query<&Window>,
39) -> Result {
40    // circular base
41    commands.spawn((
42        Mesh3d(meshes.add(Circle::new(4.0))),
43        MeshMaterial3d(materials.add(Color::WHITE)),
44        Transform::from_rotation(Quat::from_rotation_x(-std::f32::consts::FRAC_PI_2)),
45    ));
46
47    // cube
48    commands.spawn((
49        Mesh3d(meshes.add(Cuboid::new(1.0, 1.0, 1.0))),
50        MeshMaterial3d(materials.add(Color::WHITE)),
51        Transform::from_xyz(0.0, 0.5, 0.0),
52    ));
53
54    // lights
55    for i in 0..NUM_LIGHTS {
56        let angle = (i as f32) / (NUM_LIGHTS as f32) * PI * 2.0;
57        commands.spawn((
58            PointLight {
59                color: Color::hsv(angle.to_degrees(), 1.0, 1.0),
60                intensity: 2_000_000.0 / NUM_LIGHTS as f32,
61                shadow_maps_enabled: true,
62                ..default()
63            },
64            Transform::from_xyz(sin(angle) * 4.0, 2.0, cos(angle) * 4.0),
65        ));
66    }
67
68    // cameras
69    let window = window.single()?;
70    let width = window.resolution.width() / CAMERA_COLS as f32 * window.resolution.scale_factor();
71    let height = window.resolution.height() / CAMERA_ROWS as f32 * window.resolution.scale_factor();
72    let mut i = 0;
73    for y in 0..CAMERA_COLS {
74        for x in 0..CAMERA_ROWS {
75            let angle = i as f32 / (CAMERA_ROWS * CAMERA_COLS) as f32 * PI * 2.0;
76            commands.spawn((
77                Camera3d::default(),
78                Camera {
79                    viewport: Some(Viewport {
80                        physical_position: UVec2::new(
81                            (x as f32 * width) as u32,
82                            (y as f32 * height) as u32,
83                        ),
84                        physical_size: UVec2::new(width as u32, height as u32),
85                        ..default()
86                    }),
87                    order: i,
88                    ..default()
89                },
90                Transform::from_xyz(sin(angle) * 4.0, 2.5, cos(angle) * 4.0)
91                    .looking_at(Vec3::ZERO, Vec3::Y),
92            ));
93            i += 1;
94        }
95    }
96    Ok(())
97}
98
99fn rotate_cameras(time: Res<Time>, mut query: Query<&mut Transform, With<Camera>>) {
100    for mut transform in query.iter_mut() {
101        transform.rotate_around(Vec3::ZERO, Quat::from_rotation_y(time.delta_secs()));
102    }
103}