Skip to content

Commit e389fe0

Browse files
Virtual geometry: Upgrade deps, allow 256 vertices (#21301)
Some small work on virtual geometry. Some other improvements we should do in the future for the builder code: * meshopt_computeSphereBounds instead of merge_spheres * Permissive simplification * Faster vertex locking, copying zeux/meshoptimizer#961 * Try out meshopt's clusterizer/partitioner instead of using metis --------- Co-authored-by: Jasmine Schweitzer <[email protected]>
1 parent 40767f4 commit e389fe0

File tree

5 files changed

+19
-37
lines changed

5 files changed

+19
-37
lines changed

crates/bevy_pbr/Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ derive_more = { version = "2", default-features = false, features = ["from"] }
7070
lz4_flex = { version = "0.11", default-features = false, features = [
7171
"frame",
7272
], optional = true }
73-
range-alloc = { version = "0.1.3", optional = true }
74-
meshopt = { version = "0.4.1", optional = true }
75-
metis = { version = "0.2", optional = true }
73+
range-alloc = { version = "0.1", optional = true }
74+
meshopt = { version = "0.6.2", optional = true }
75+
metis = { version = "0.2.2", optional = true }
7676
itertools = { version = "0.14", optional = true }
7777
bitvec = { version = "1", optional = true }
7878
# direct dependency required for derive macro

crates/bevy_pbr/src/meshlet/asset.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use thiserror::Error;
1717
const MESHLET_MESH_ASSET_MAGIC: u64 = 1717551717668;
1818

1919
/// The current version of the [`MeshletMesh`] asset format.
20-
pub const MESHLET_MESH_ASSET_VERSION: u64 = 2;
20+
pub const MESHLET_MESH_ASSET_VERSION: u64 = 3;
2121

2222
/// A mesh that has been pre-processed into multiple small clusters of triangles called meshlets.
2323
///
@@ -86,8 +86,8 @@ pub struct Meshlet {
8686
pub start_vertex_attribute_id: u32,
8787
/// The offset within the parent mesh's [`MeshletMesh::indices`] buffer where the indices for this meshlet begin.
8888
pub start_index_id: u32,
89-
/// The amount of vertices in this meshlet.
90-
pub vertex_count: u8,
89+
/// The amount of vertices in this meshlet (minus one to fit 256 in a u8).
90+
pub vertex_count_minus_one: u8,
9191
/// The amount of triangles in this meshlet.
9292
pub triangle_count: u8,
9393
/// Unused.

crates/bevy_pbr/src/meshlet/from_mesh.rs

Lines changed: 11 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ use bitvec::{order::Lsb0, vec::BitVec, view::BitView};
1515
use core::{f32, ops::Range};
1616
use itertools::Itertools;
1717
use meshopt::{
18-
build_meshlets, ffi::meshopt_Meshlet, generate_vertex_remap_multi,
19-
simplify_with_attributes_and_locks, Meshlets, SimplifyOptions, VertexDataAdapter, VertexStream,
18+
build_meshlets, ffi::meshopt_Meshlet, generate_position_remap,
19+
simplify_with_attributes_and_locks, Meshlets, SimplifyOptions, VertexDataAdapter,
2020
};
2121
use metis::{option::Opt, Graph};
2222
use smallvec::SmallVec;
@@ -81,23 +81,11 @@ impl MeshletMesh {
8181
let vertex_normals = bytemuck::cast_slice(&vertex_buffer[12..16]);
8282

8383
// Generate a position-only vertex buffer for determining triangle/meshlet connectivity
84-
let (position_only_vertex_count, position_only_vertex_remap) = generate_vertex_remap_multi(
85-
vertices.vertex_count,
86-
&[VertexStream::new_with_stride::<Vec3, _>(
87-
vertex_buffer.as_ptr(),
88-
vertex_stride,
89-
)],
90-
Some(&indices),
91-
);
84+
let position_only_vertex_remap = generate_position_remap(&vertices);
9285

9386
// Split the mesh into an initial list of meshlets (LOD 0)
94-
let (mut meshlets, mut cull_data) = compute_meshlets(
95-
&indices,
96-
&vertices,
97-
&position_only_vertex_remap,
98-
position_only_vertex_count,
99-
None,
100-
);
87+
let (mut meshlets, mut cull_data) =
88+
compute_meshlets(&indices, &vertices, &position_only_vertex_remap, None);
10189

10290
let mut vertex_locks = vec![false; vertices.vertex_count];
10391

@@ -115,7 +103,6 @@ impl MeshletMesh {
115103
&simplification_queue,
116104
&meshlets,
117105
&position_only_vertex_remap,
118-
position_only_vertex_count,
119106
);
120107

121108
// Group meshlets into roughly groups of size TARGET_MESHLETS_PER_GROUP,
@@ -133,7 +120,6 @@ impl MeshletMesh {
133120
&groups,
134121
&meshlets,
135122
&position_only_vertex_remap,
136-
position_only_vertex_count,
137123
);
138124

139125
let simplified = groups.par_chunk_map(AsyncComputeTaskPool::get(), 1, |_, groups| {
@@ -172,7 +158,6 @@ impl MeshletMesh {
172158
&simplified_group_indices,
173159
&vertices,
174160
&position_only_vertex_remap,
175-
position_only_vertex_count,
176161
Some((group.lod_bounds, group.parent_error)),
177162
);
178163

@@ -295,11 +280,10 @@ fn compute_meshlets(
295280
indices: &[u32],
296281
vertices: &VertexDataAdapter,
297282
position_only_vertex_remap: &[u32],
298-
position_only_vertex_count: usize,
299283
prev_lod_data: Option<(BoundingSphere, f32)>,
300284
) -> (Meshlets, Vec<TempMeshletCullData>) {
301285
// For each vertex, build a list of all triangles that use it
302-
let mut vertices_to_triangles = vec![Vec::new(); position_only_vertex_count];
286+
let mut vertices_to_triangles = vec![Vec::new(); position_only_vertex_remap.len()];
303287
for (i, index) in indices.iter().enumerate() {
304288
let vertex_id = position_only_vertex_remap[*index as usize];
305289
let vertex_to_triangles = &mut vertices_to_triangles[vertex_id as usize];
@@ -383,7 +367,7 @@ fn compute_meshlets(
383367
)
384368
};
385369
for meshlet_indices in &indices_per_meshlet {
386-
let meshlet = build_meshlets(meshlet_indices, vertices, 255, 128, 0.0);
370+
let meshlet = build_meshlets(meshlet_indices, vertices, 256, 128, 0.0);
387371
for meshlet in meshlet.iter() {
388372
let (lod_group_sphere, error) = prev_lod_data.unwrap_or_else(|| {
389373
let bounds = meshopt::compute_meshlet_bounds(meshlet, vertices);
@@ -408,10 +392,9 @@ fn find_connected_meshlets(
408392
simplification_queue: &[u32],
409393
meshlets: &Meshlets,
410394
position_only_vertex_remap: &[u32],
411-
position_only_vertex_count: usize,
412395
) -> Vec<Vec<(usize, usize)>> {
413396
// For each vertex, build a list of all meshlets that use it
414-
let mut vertices_to_meshlets = vec![Vec::new(); position_only_vertex_count];
397+
let mut vertices_to_meshlets = vec![Vec::new(); position_only_vertex_remap.len()];
415398
for (id_index, &meshlet_id) in simplification_queue.iter().enumerate() {
416399
let meshlet = meshlets.get(meshlet_id as _);
417400
for index in meshlet.triangles {
@@ -505,9 +488,8 @@ fn lock_group_borders(
505488
groups: &[TempMeshletGroup],
506489
meshlets: &Meshlets,
507490
position_only_vertex_remap: &[u32],
508-
position_only_vertex_count: usize,
509491
) {
510-
let mut position_only_locks = vec![-1; position_only_vertex_count];
492+
let mut position_only_locks = vec![-1; position_only_vertex_remap.len()];
511493

512494
// Iterate over position-only based vertices of all meshlets in all groups
513495
for (group_id, group) in groups.iter().enumerate() {
@@ -617,7 +599,7 @@ fn build_and_compress_per_meshlet_vertex_data(
617599
let mut max_quantized_position_channels = IVec3::MIN;
618600

619601
// Lossy vertex compression
620-
let mut quantized_positions = [IVec3::ZERO; 255];
602+
let mut quantized_positions = [IVec3::ZERO; 256];
621603
for (i, vertex_id) in meshlet_vertex_ids.iter().enumerate() {
622604
// Load source vertex attributes
623605
let vertex_id_byte = *vertex_id as usize * vertex_stride;
@@ -668,7 +650,7 @@ fn build_and_compress_per_meshlet_vertex_data(
668650
start_vertex_position_bit,
669651
start_vertex_attribute_id,
670652
start_index_id: meshlet.triangle_offset,
671-
vertex_count: meshlet.vertex_count as u8,
653+
vertex_count_minus_one: (meshlet.vertex_count - 1) as u8,
672654
triangle_count: meshlet.triangle_count as u8,
673655
padding: 0,
674656
bits_per_vertex_position_channel_x,

crates/bevy_pbr/src/meshlet/meshlet_bindings.wgsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ struct Meshlet {
2424
}
2525

2626
fn get_meshlet_vertex_count(meshlet: ptr<function, Meshlet>) -> u32 {
27-
return extractBits((*meshlet).packed_a, 0u, 8u);
27+
return extractBits((*meshlet).packed_a, 0u, 8u) + 1u;
2828
}
2929

3030
fn get_meshlet_triangle_count(meshlet: ptr<function, Meshlet>) -> u32 {

crates/bevy_pbr/src/meshlet/visibility_buffer_software_raster.wgsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
// TODO: Fixed-point math and top-left rule
2525

26-
var<workgroup> viewport_vertices: array<vec3f, 255>;
26+
var<workgroup> viewport_vertices: array<vec3f, 256>;
2727

2828
@compute
2929
@workgroup_size(128, 1, 1) // 128 threads per workgroup, 1-2 vertices per thread, 1 triangle per thread, 1 cluster per workgroup

0 commit comments

Comments
 (0)