mirror of
https://github.com/bevyengine/bevy
synced 2025-02-16 14:08:32 +00:00
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.
This commit is contained in:
parent
3a04d38832
commit
4cd188568a
2 changed files with 9 additions and 24 deletions
|
@ -56,7 +56,7 @@ serde = { version = "1", features = ["derive", "rc"], optional = true }
|
|||
bincode = { version = "1", optional = true }
|
||||
thiserror = { version = "1", optional = true }
|
||||
range-alloc = { version = "0.1", optional = true }
|
||||
meshopt = { version = "0.2.1", optional = true }
|
||||
meshopt = { version = "0.3.0", optional = true }
|
||||
metis = { version = "0.2", optional = true }
|
||||
itertools = { version = "0.13", optional = true }
|
||||
# direct dependency required for derive macro
|
||||
|
|
|
@ -6,9 +6,8 @@ use bevy_render::{
|
|||
use bevy_utils::HashMap;
|
||||
use itertools::Itertools;
|
||||
use meshopt::{
|
||||
build_meshlets, compute_cluster_bounds, compute_meshlet_bounds,
|
||||
ffi::{meshopt_Bounds, meshopt_optimizeMeshlet},
|
||||
simplify, simplify_scale, Meshlets, SimplifyOptions, VertexDataAdapter,
|
||||
build_meshlets, compute_cluster_bounds, compute_meshlet_bounds, ffi::meshopt_Bounds, simplify,
|
||||
simplify_scale, Meshlets, SimplifyOptions, VertexDataAdapter,
|
||||
};
|
||||
use metis::Graph;
|
||||
use smallvec::SmallVec;
|
||||
|
@ -178,22 +177,7 @@ fn validate_input_mesh(mesh: &Mesh) -> Result<Cow<'_, [u32]>, MeshToMeshletMeshC
|
|||
}
|
||||
|
||||
fn compute_meshlets(indices: &[u32], vertices: &VertexDataAdapter) -> Meshlets {
|
||||
let mut meshlets = build_meshlets(indices, vertices, 64, 64, 0.0);
|
||||
|
||||
for meshlet in &mut meshlets.meshlets {
|
||||
#[allow(unsafe_code)]
|
||||
#[allow(clippy::undocumented_unsafe_blocks)]
|
||||
unsafe {
|
||||
meshopt_optimizeMeshlet(
|
||||
&mut meshlets.vertices[meshlet.vertex_offset as usize],
|
||||
&mut meshlets.triangles[meshlet.triangle_offset as usize],
|
||||
meshlet.triangle_count as usize,
|
||||
meshlet.vertex_count as usize,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
meshlets
|
||||
build_meshlets(indices, vertices, 64, 64, 0.0)
|
||||
}
|
||||
|
||||
fn find_connected_meshlets(
|
||||
|
@ -306,7 +290,8 @@ fn simplify_meshlet_groups(
|
|||
|
||||
// Allow more deformation for high LOD levels (1% at LOD 1, 10% at LOD 20+)
|
||||
let t = (lod_level - 1) as f32 / 19.0;
|
||||
let target_error = 0.1 * t + 0.01 * (1.0 - t);
|
||||
let target_error_relative = 0.1 * t + 0.01 * (1.0 - t);
|
||||
let target_error = target_error_relative * mesh_scale;
|
||||
|
||||
// Simplify the group to ~50% triangle count
|
||||
// TODO: Use simplify_with_locks()
|
||||
|
@ -316,7 +301,7 @@ fn simplify_meshlet_groups(
|
|||
vertices,
|
||||
group_indices.len() / 2,
|
||||
target_error,
|
||||
SimplifyOptions::LockBorder,
|
||||
SimplifyOptions::LockBorder | SimplifyOptions::Sparse | SimplifyOptions::ErrorAbsolute,
|
||||
Some(&mut error),
|
||||
);
|
||||
|
||||
|
@ -325,8 +310,8 @@ fn simplify_meshlet_groups(
|
|||
return None;
|
||||
}
|
||||
|
||||
// Convert error to object-space and convert from diameter to radius
|
||||
error *= mesh_scale * 0.5;
|
||||
// Convert error from diameter to radius
|
||||
error *= 0.5;
|
||||
|
||||
Some((simplified_group_indices, error))
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue