Skip to content

Commit 5d7da82

Browse files
zeuxmockersf
authored andcommitted
Improve MeshletMesh::from_mesh performance further (#14038)
This change updates meshopt-rs to 0.3 to take advantage of the newly added sparse simplification mode: by default, simplifier assumes that the entire mesh is simplified and runs a set of calculations that are O(vertex count), but in our case we simplify many small mesh subsets which is inefficient. Sparse mode instead assumes that the simplified subset is only using a portion of the vertex buffer, and optimizes accordingly. This changes the meaning of the error (as it becomes relative to the subset, in our case a meshlet group); to ensure consistent error selection, we also use the ErrorAbsolute mode which allows us to operate in mesh coordinate space. Additionally, meshopt 0.3 runs optimizeMeshlet automatically as part of `build_meshlets` so we no longer need to call it ourselves. This reduces the time to build meshlet representation for Stanford Bunny mesh from ~1.65s to ~0.45s (3.7x) in optimized builds.
1 parent 4f0b0e0 commit 5d7da82

File tree

2 files changed

+9
-24
lines changed

2 files changed

+9
-24
lines changed

crates/bevy_pbr/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ serde = { version = "1", features = ["derive", "rc"], optional = true }
5656
bincode = { version = "1", optional = true }
5757
thiserror = { version = "1", optional = true }
5858
range-alloc = { version = "0.1", optional = true }
59-
meshopt = { version = "0.2.1", optional = true }
59+
meshopt = { version = "0.3.0", optional = true }
6060
metis = { version = "0.2", optional = true }
6161
itertools = { version = "0.13", optional = true }
6262
# direct dependency required for derive macro

crates/bevy_pbr/src/meshlet/from_mesh.rs

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@ use bevy_render::{
66
use bevy_utils::HashMap;
77
use itertools::Itertools;
88
use meshopt::{
9-
build_meshlets, compute_cluster_bounds, compute_meshlet_bounds,
10-
ffi::{meshopt_Bounds, meshopt_optimizeMeshlet},
11-
simplify, simplify_scale, Meshlets, SimplifyOptions, VertexDataAdapter,
9+
build_meshlets, compute_cluster_bounds, compute_meshlet_bounds, ffi::meshopt_Bounds, simplify,
10+
simplify_scale, Meshlets, SimplifyOptions, VertexDataAdapter,
1211
};
1312
use metis::Graph;
1413
use smallvec::SmallVec;
@@ -178,22 +177,7 @@ fn validate_input_mesh(mesh: &Mesh) -> Result<Cow<'_, [u32]>, MeshToMeshletMeshC
178177
}
179178

180179
fn compute_meshlets(indices: &[u32], vertices: &VertexDataAdapter) -> Meshlets {
181-
let mut meshlets = build_meshlets(indices, vertices, 64, 64, 0.0);
182-
183-
for meshlet in &mut meshlets.meshlets {
184-
#[allow(unsafe_code)]
185-
#[allow(clippy::undocumented_unsafe_blocks)]
186-
unsafe {
187-
meshopt_optimizeMeshlet(
188-
&mut meshlets.vertices[meshlet.vertex_offset as usize],
189-
&mut meshlets.triangles[meshlet.triangle_offset as usize],
190-
meshlet.triangle_count as usize,
191-
meshlet.vertex_count as usize,
192-
);
193-
}
194-
}
195-
196-
meshlets
180+
build_meshlets(indices, vertices, 64, 64, 0.0)
197181
}
198182

199183
fn find_connected_meshlets(
@@ -306,7 +290,8 @@ fn simplify_meshlet_groups(
306290

307291
// Allow more deformation for high LOD levels (1% at LOD 1, 10% at LOD 20+)
308292
let t = (lod_level - 1) as f32 / 19.0;
309-
let target_error = 0.1 * t + 0.01 * (1.0 - t);
293+
let target_error_relative = 0.1 * t + 0.01 * (1.0 - t);
294+
let target_error = target_error_relative * mesh_scale;
310295

311296
// Simplify the group to ~50% triangle count
312297
// TODO: Use simplify_with_locks()
@@ -316,7 +301,7 @@ fn simplify_meshlet_groups(
316301
vertices,
317302
group_indices.len() / 2,
318303
target_error,
319-
SimplifyOptions::LockBorder,
304+
SimplifyOptions::LockBorder | SimplifyOptions::Sparse | SimplifyOptions::ErrorAbsolute,
320305
Some(&mut error),
321306
);
322307

@@ -325,8 +310,8 @@ fn simplify_meshlet_groups(
325310
return None;
326311
}
327312

328-
// Convert error to object-space and convert from diameter to radius
329-
error *= mesh_scale * 0.5;
313+
// Convert error from diameter to radius
314+
error *= 0.5;
330315

331316
Some((simplified_group_indices, error))
332317
}

0 commit comments

Comments
 (0)