From c818c92143e56ef3b51836af423319a5a61b15ad Mon Sep 17 00:00:00 2001 From: Griffin <33357138+DGriffin91@users.noreply.github.com> Date: Tue, 18 Feb 2025 14:39:27 -0800 Subject: [PATCH] Add option to animate materials in many_cubes (#17927) This adds an option to animate the materials in the `many_cubes` stress test. Each material instance `base_color` is varied each frame. This has been tested in conjunction with the `--vary-material-data-per-instance` and `--material-texture-count` options. If `--vary-material-data-per-instance` is not used it will just update the single material, otherwise it will update all of them. If `--material-texture-count` is used the `base_color` is multiplied with the texture so the effect is still visible. Because this test is focused on the performance of updating material data and not the performance of bevy's color system it uses its own function (`fast_hue_to_rgb`) to quickly set the hue. This appeared to be around 8x faster than using `base_color.set_hue(hue)` in the tight loop. --- examples/stress_tests/many_cubes.rs | 62 +++++++++++++++++++---------- 1 file changed, 42 insertions(+), 20 deletions(-) diff --git a/examples/stress_tests/many_cubes.rs b/examples/stress_tests/many_cubes.rs index 2b199a4a4b..6cf7f40845 100644 --- a/examples/stress_tests/many_cubes.rs +++ b/examples/stress_tests/many_cubes.rs @@ -70,6 +70,10 @@ struct Args { /// whether to enable directional light cascaded shadow mapping. #[argh(switch)] shadows: bool, + + /// animate the cube materials by updating the material from the cpu each frame + #[argh(switch)] + animate_materials: bool, } #[derive(Default, Clone)] @@ -100,28 +104,31 @@ fn main() { #[cfg(target_arch = "wasm32")] let args = Args::from_args(&[], &[]).unwrap(); - App::new() - .add_plugins(( - DefaultPlugins.set(WindowPlugin { - primary_window: Some(Window { - present_mode: PresentMode::AutoNoVsync, - resolution: WindowResolution::new(1920.0, 1080.0) - .with_scale_factor_override(1.0), - ..default() - }), + let mut app = App::new(); + app.add_plugins(( + DefaultPlugins.set(WindowPlugin { + primary_window: Some(Window { + present_mode: PresentMode::AutoNoVsync, + resolution: WindowResolution::new(1920.0, 1080.0).with_scale_factor_override(1.0), ..default() }), - FrameTimeDiagnosticsPlugin::default(), - LogDiagnosticsPlugin::default(), - )) - .insert_resource(WinitSettings { - focused_mode: UpdateMode::Continuous, - unfocused_mode: UpdateMode::Continuous, - }) - .insert_resource(args) - .add_systems(Startup, setup) - .add_systems(Update, (move_camera, print_mesh_count)) - .run(); + ..default() + }), + FrameTimeDiagnosticsPlugin::default(), + LogDiagnosticsPlugin::default(), + )) + .insert_resource(WinitSettings { + focused_mode: UpdateMode::Continuous, + unfocused_mode: UpdateMode::Continuous, + }) + .add_systems(Startup, setup) + .add_systems(Update, (move_camera, print_mesh_count)); + + if args.animate_materials { + app.add_systems(Update, update_materials); + } + + app.insert_resource(args).run(); } const WIDTH: usize = 200; @@ -475,3 +482,18 @@ impl Default for PrintingTimer { Self(Timer::from_seconds(1.0, TimerMode::Repeating)) } } + +fn update_materials(mut materials: ResMut>, time: Res