forked from bevyengine/bevy
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add many_materials stress test (bevyengine#17346)
# Objective - This PR adds a new stress test called `many_materials` to benchmark the rendering performance of many animated materials. - Fixes bevyengine#11588 - This PR continues the work started in the previous PR bevyengine#11592, which was closed due to inactivity. ## Solution - Created a new example (`examples/stress_tests/many_materials.rs`) that renders a grid of cubes with animated materials. - The size of the grid can be configured using the `-n` command-line argument (or `--grid-size`). The default grid size is 10x10. - The materials animate by cycling through colors in the HSL color space. ## Testing - I have tested these changes locally on my Linux machine. - Reviewers can test the changes by running the example with different grid sizes and observing the performance (FPS, frame time). - I have not tested on other platforms (macOS, Windows, wasm), but I expect it to work as the code uses standard Bevy features. --- ## Showcase <details> <summary>Click to view showcase</summary>  </details>
- Loading branch information
Showing
3 changed files
with
115 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
//! Benchmark to test rendering many animated materials | ||
use argh::FromArgs; | ||
use bevy::{ | ||
diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, | ||
prelude::*, | ||
window::{PresentMode, WindowPlugin, WindowResolution}, | ||
}; | ||
use std::f32::consts::PI; | ||
|
||
#[derive(FromArgs, Resource)] | ||
/// Command-line arguments for the `many_materials` stress test. | ||
struct Args { | ||
/// the size of the grid of materials to render (n x n) | ||
#[argh(option, short = 'n', default = "10")] | ||
grid_size: usize, | ||
} | ||
|
||
fn main() { | ||
// `from_env` panics on the web | ||
#[cfg(not(target_arch = "wasm32"))] | ||
let args: Args = argh::from_env(); | ||
#[cfg(target_arch = "wasm32")] | ||
let args = Args::from_args(&[], &[]).unwrap(); | ||
|
||
App::new() | ||
.add_plugins(( | ||
DefaultPlugins.set(WindowPlugin { | ||
primary_window: Some(Window { | ||
resolution: WindowResolution::new(1920.0, 1080.0) | ||
.with_scale_factor_override(1.0), | ||
title: "many_materials".into(), | ||
present_mode: PresentMode::AutoNoVsync, | ||
..default() | ||
}), | ||
..default() | ||
}), | ||
FrameTimeDiagnosticsPlugin::default(), | ||
LogDiagnosticsPlugin::default(), | ||
)) | ||
.insert_resource(args) | ||
.add_systems(Startup, setup) | ||
.add_systems(Update, animate_materials) | ||
.run(); | ||
} | ||
|
||
fn setup( | ||
mut commands: Commands, | ||
args: Res<Args>, | ||
mesh_assets: ResMut<Assets<Mesh>>, | ||
material_assets: ResMut<Assets<StandardMaterial>>, | ||
) { | ||
let args = args.into_inner(); | ||
let material_assets = material_assets.into_inner(); | ||
let mesh_assets = mesh_assets.into_inner(); | ||
let n = args.grid_size; | ||
|
||
// Camera | ||
let w = n as f32; | ||
commands.spawn(( | ||
Camera3d::default(), | ||
Transform::from_xyz(w * 1.25, w + 1.0, w * 1.25) | ||
.looking_at(Vec3::new(0.0, (w * -1.1) + 1.0, 0.0), Vec3::Y), | ||
)); | ||
|
||
// Light | ||
commands.spawn(( | ||
Transform::from_rotation(Quat::from_euler(EulerRot::ZYX, 0.0, 1.0, -PI / 4.)), | ||
DirectionalLight { | ||
illuminance: 3000.0, | ||
shadows_enabled: true, | ||
..default() | ||
}, | ||
)); | ||
|
||
// Cubes | ||
let mesh_handle = mesh_assets.add(Cuboid::from_size(Vec3::ONE)); | ||
for x in 0..n { | ||
for z in 0..n { | ||
commands.spawn(( | ||
Mesh3d(mesh_handle.clone()), | ||
MeshMaterial3d(material_assets.add(Color::WHITE)), | ||
Transform::from_translation(Vec3::new(x as f32, 0.0, z as f32)), | ||
)); | ||
} | ||
} | ||
} | ||
|
||
fn animate_materials( | ||
material_handles: Query<&MeshMaterial3d<StandardMaterial>>, | ||
time: Res<Time>, | ||
mut materials: ResMut<Assets<StandardMaterial>>, | ||
) { | ||
for (i, material_handle) in material_handles.iter().enumerate() { | ||
if let Some(material) = materials.get_mut(material_handle) { | ||
let color = Color::hsl( | ||
((i as f32 * 2.345 + time.elapsed_secs()) * 100.0) % 360.0, | ||
1.0, | ||
0.5, | ||
); | ||
material.base_color = color; | ||
} | ||
} | ||
} |