Path: blob/main/examples/stress_tests/many_meshlet_materials.rs
30632 views
//! A stress test for the Meshlet pipeline specialization overhead.1//!2//! Run with `--unique-materials` to trigger the unconditional specialization bug.3//! Run without it (shared material) to see the baseline performance.45use argh::FromArgs;6use bevy::{7diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin},8pbr::experimental::meshlet::{MeshletMesh3d, MeshletPlugin},9prelude::*,10window::{PresentMode, WindowResolution},11winit::WinitSettings,12};1314#[derive(FromArgs, Resource)]15#[argh(description = "Meshlet Material Stress Test")]16struct Args {17/// the grid size (e.g., 50 means 50x50 = 2500 meshlets)18#[argh(option, short = 'n', default = "50")]19grid_size: usize,2021/// if set, every meshlet gets a unique material asset.22/// This triggers the unconditional pipeline specialization bug in `prepare_material_meshlet_meshes`.23#[argh(switch)]24unique_materials: bool,25}2627const ASSET_URL: &str =28"https://github.com/bevyengine/bevy_asset_files/raw/6dccaef517bde74d1969734703709aead7211dbc/meshlet/bunny.meshlet_mesh";2930fn main() {31let args: Args = argh::from_env();3233warn!(include_str!("warning_string.txt"));34println!("Meshlet Stress Test");35println!(36"Grid size: {}x{} ({} instances)",37args.grid_size,38args.grid_size,39args.grid_size * args.grid_size40);41println!(42"Materials: {}",43if args.unique_materials {44"UNIQUE"45} else {46"SHARED"47}48);4950App::new()51.add_plugins((52DefaultPlugins.set(WindowPlugin {53primary_window: Some(Window {54present_mode: PresentMode::AutoNoVsync,55resolution: WindowResolution::new(1920, 1080).with_scale_factor_override(1.0),56..default()57}),58..default()59}),60FrameTimeDiagnosticsPlugin::default(),61LogDiagnosticsPlugin::default(),62MeshletPlugin {63cluster_buffer_slots: 8192,64},65))66.insert_resource(WinitSettings::continuous())67.insert_resource(args)68.add_systems(Startup, setup)69.run();70}7172fn setup(73mut commands: Commands,74args: Res<Args>,75asset_server: Res<AssetServer>,76mut materials: ResMut<Assets<StandardMaterial>>,77) {78let meshlet_handle = asset_server.load(ASSET_URL);7980let n = args.grid_size;81let spacing = 2.0;8283commands.spawn((84Camera3d::default(),85Transform::from_xyz(0.0, n as f32, n as f32 * 1.5).looking_at(Vec3::ZERO, Vec3::Y),86Msaa::Off,87));8889commands.spawn((90DirectionalLight {91illuminance: 3000.0,92shadow_maps_enabled: true,93..default()94},95Transform::from_rotation(Quat::from_euler(96EulerRot::ZYX,970.0,981.0,99-std::f32::consts::FRAC_PI_4,100)),101));102103let shared_material = materials.add(StandardMaterial {104base_color: Color::WHITE,105..default()106});107108for x in 0..n {109for z in 0..n {110let material = if args.unique_materials {111materials.add(StandardMaterial {112base_color: Color::srgb(x as f32 / n as f32, 0.5, z as f32 / n as f32),113..default()114})115} else {116shared_material.clone()117};118119commands.spawn((120MeshletMesh3d(meshlet_handle.clone()),121MeshMaterial3d(material),122Transform::from_xyz(123x as f32 * spacing - n as f32,1240.0,125z as f32 * spacing - n as f32,126),127));128}129}130}131132133