 af3a84fc0b
			
		
	
	
		af3a84fc0b
		
			
		
	
	
	
	
		
			
			# Objective - This PR adds a new stress test called `many_materials` to benchmark the rendering performance of many animated materials. - Fixes #11588 - This PR continues the work started in the previous PR #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>
		
			
				
	
	
		
			104 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			104 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| //! 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;
 | |
|         }
 | |
|     }
 | |
| }
 |