many_meshlet_materials/
many_meshlet_materials.rs1use argh::FromArgs;
7use bevy::{
8 diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},
9 pbr::experimental::meshlet::{MeshletMesh3d, MeshletPlugin},
10 prelude::*,
11 window::{PresentMode, WindowResolution},
12 winit::WinitSettings,
13};
14
15#[derive(FromArgs, Resource)]
16#[argh(description = "Meshlet Material Stress Test")]
17struct Args {
18 #[argh(option, short = 'n', default = "50")]
20 grid_size: usize,
21
22 #[argh(switch)]
25 unique_materials: bool,
26}
27
28const ASSET_URL: &str =
29 "https://github.com/bevyengine/bevy_asset_files/raw/6dccaef517bde74d1969734703709aead7211dbc/meshlet/bunny.meshlet_mesh";
30
31fn main() {
32 let args: Args = argh::from_env();
33
34 println!("Meshlet Stress Test");
35 println!(
36 "Grid size: {}x{} ({} instances)",
37 args.grid_size,
38 args.grid_size,
39 args.grid_size * args.grid_size
40 );
41 println!(
42 "Materials: {}",
43 if args.unique_materials {
44 "UNIQUE"
45 } else {
46 "SHARED"
47 }
48 );
49
50 App::new()
51 .add_plugins((
52 DefaultPlugins.set(WindowPlugin {
53 primary_window: Some(Window {
54 present_mode: PresentMode::AutoNoVsync,
55 resolution: WindowResolution::new(1920, 1080).with_scale_factor_override(1.0),
56 ..default()
57 }),
58 ..default()
59 }),
60 FrameTimeDiagnosticsPlugin::default(),
61 LogDiagnosticsPlugin::default(),
62 MeshletPlugin {
63 cluster_buffer_slots: 8192,
64 },
65 ))
66 .insert_resource(WinitSettings::continuous())
67 .insert_resource(args)
68 .add_systems(Startup, setup)
69 .run();
70}
71
72fn setup(
73 mut commands: Commands,
74 args: Res<Args>,
75 asset_server: Res<AssetServer>,
76 mut materials: ResMut<Assets<StandardMaterial>>,
77) {
78 warn!(include_str!("warning_string.txt"));
79
80 let meshlet_handle = asset_server.load(ASSET_URL);
81
82 let n = args.grid_size;
83 let spacing = 2.0;
84
85 commands.spawn((
86 Camera3d::default(),
87 Transform::from_xyz(0.0, n as f32, n as f32 * 1.5).looking_at(Vec3::ZERO, Vec3::Y),
88 Msaa::Off,
89 ));
90
91 commands.spawn((
92 DirectionalLight {
93 illuminance: 3000.0,
94 shadow_maps_enabled: true,
95 ..default()
96 },
97 Transform::from_rotation(Quat::from_euler(
98 EulerRot::ZYX,
99 0.0,
100 1.0,
101 -std::f32::consts::FRAC_PI_4,
102 )),
103 ));
104
105 let shared_material = materials.add(StandardMaterial {
106 base_color: Color::WHITE,
107 ..default()
108 });
109
110 for x in 0..n {
111 for z in 0..n {
112 let material = if args.unique_materials {
113 materials.add(StandardMaterial {
114 base_color: Color::srgb(x as f32 / n as f32, 0.5, z as f32 / n as f32),
115 ..default()
116 })
117 } else {
118 shared_material.clone()
119 };
120
121 commands.spawn((
122 MeshletMesh3d(meshlet_handle.clone()),
123 MeshMaterial3d(material),
124 Transform::from_xyz(
125 x as f32 * spacing - n as f32,
126 0.0,
127 z as f32 * spacing - n as f32,
128 ),
129 ));
130 }
131 }
132}