Skip to content

Commit 9e380cd

Browse files
committed
Add many_meshlet_materials stress test example
1 parent 5330b01 commit 9e380cd

File tree

2 files changed

+133
-0
lines changed

2 files changed

+133
-0
lines changed

Cargo.toml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3544,6 +3544,19 @@ description = "Displays many Text2d! Used for performance testing."
35443544
category = "Stress Tests"
35453545
wasm = true
35463546

3547+
[[example]]
3548+
name = "many_meshlet_materials"
3549+
path = "examples/stress_tests/many_meshlet_materials.rs"
3550+
doc-scrape-examples = true
3551+
required-features = ["meshlet", "https"]
3552+
3553+
[package.metadata.example.many_meshlet_materials]
3554+
name = "Many Meshlet Materials"
3555+
description = "Benchmark to test rendering many meshlet materials (experimental)"
3556+
category = "Stress Tests"
3557+
# Requires compute shaders and WGPU extensions, not supported by WebGL nor WebGPU.
3558+
wasm = false
3559+
35473560
[[example]]
35483561
name = "many_materials"
35493562
path = "examples/stress_tests/many_materials.rs"
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
//! A stress test for the Meshlet pipeline specialization overhead.
2+
//!
3+
//! Run with `--unique-materials` to trigger the unconditional specialization bug.
4+
//! Run without it (shared material) to see the baseline performance.
5+
6+
use argh::FromArgs;
7+
use bevy::{
8+
pbr::experimental::meshlet::{MeshletMesh3d, MeshletPlugin},
9+
prelude::*,
10+
winit::WinitSettings,
11+
};
12+
13+
#[derive(FromArgs, Resource)]
14+
#[argh(description = "Meshlet Material Stress Test")]
15+
struct Args {
16+
/// the grid size (e.g., 50 means 50x50 = 2500 meshlets)
17+
#[argh(option, short = 'n', default = "50")]
18+
grid_size: usize,
19+
20+
/// if set, every meshlet gets a unique material asset.
21+
/// This triggers the unconditional pipeline specialization bug in `prepare_material_meshlet_meshes`.
22+
#[argh(switch)]
23+
unique_materials: bool,
24+
}
25+
26+
const ASSET_URL: &str =
27+
"https://github.com/bevyengine/bevy_asset_files/raw/6dccaef517bde74d1969734703709aead7211dbc/meshlet/bunny.meshlet_mesh";
28+
29+
fn main() {
30+
let args: Args = argh::from_env();
31+
32+
println!("Meshlet Stress Test");
33+
println!(
34+
"Grid size: {}x{} ({} instances)",
35+
args.grid_size,
36+
args.grid_size,
37+
args.grid_size * args.grid_size
38+
);
39+
println!(
40+
"Materials: {}",
41+
if args.unique_materials {
42+
"UNIQUE"
43+
} else {
44+
"SHARED"
45+
}
46+
);
47+
48+
App::new()
49+
.add_plugins((
50+
DefaultPlugins,
51+
MeshletPlugin {
52+
cluster_buffer_slots: 8192,
53+
},
54+
))
55+
.insert_resource(WinitSettings::continuous())
56+
.insert_resource(args)
57+
.add_systems(Startup, setup)
58+
.run();
59+
}
60+
61+
fn setup(
62+
mut commands: Commands,
63+
args: Res<Args>,
64+
asset_server: Res<AssetServer>,
65+
mut materials: ResMut<Assets<StandardMaterial>>,
66+
) {
67+
let meshlet_handle = asset_server.load(ASSET_URL);
68+
69+
let n = args.grid_size;
70+
let spacing = 2.0;
71+
let offset = (n as f32 * spacing) / 2.0;
72+
73+
commands.spawn((
74+
Camera3d::default(),
75+
Transform::from_xyz(0.0, offset, offset * 1.5).looking_at(Vec3::ZERO, Vec3::Y),
76+
Msaa::Off,
77+
));
78+
79+
commands.spawn((
80+
DirectionalLight {
81+
illuminance: 3000.0,
82+
shadow_maps_enabled: true,
83+
..default()
84+
},
85+
Transform::from_rotation(Quat::from_euler(
86+
EulerRot::ZYX,
87+
0.0,
88+
1.0,
89+
-std::f32::consts::FRAC_PI_4,
90+
)),
91+
));
92+
93+
let shared_material = materials.add(StandardMaterial {
94+
base_color: Color::WHITE,
95+
..default()
96+
});
97+
98+
for x in 0..n {
99+
for z in 0..n {
100+
let material = if args.unique_materials {
101+
materials.add(StandardMaterial {
102+
base_color: Color::srgb(x as f32 / n as f32, 0.5, z as f32 / n as f32),
103+
..default()
104+
})
105+
} else {
106+
shared_material.clone()
107+
};
108+
109+
commands.spawn((
110+
MeshletMesh3d(meshlet_handle.clone()),
111+
MeshMaterial3d(material),
112+
Transform::from_xyz(
113+
x as f32 * spacing - offset,
114+
0.0,
115+
z as f32 * spacing - offset,
116+
),
117+
));
118+
}
119+
}
120+
}

0 commit comments

Comments
 (0)