Skip to content

Rendering many Boxes3D is very slow #10276

@emilk

Description

@emilk

This code is way too slow when visualizing hundreds of thousands of meshes:

let mut num_instances = 0;
for (
instance_index,
(half_size, world_from_instance, radius, &color, proc_mesh_key, fill_mode),
) in itertools::izip!(
half_sizes,
world_from_instances,
line_radii,
colors.iter(),
batch.meshes,
batch.fill_modes
)
.enumerate()
{
let instance = Instance::from(instance_index as u64);
num_instances = instance_index + 1;
let world_from_instance = world_from_instance
* glam::Affine3A::from_scale(glam::Vec3::from(*half_size))
* constant_instance_transform;
world_space_bounding_box = world_space_bounding_box.union(
proc_mesh_key
.simple_bounding_box()
.transform_affine3(&world_from_instance),
);
match fill_mode {
FillMode::MajorWireframe | FillMode::DenseWireframe => {
let Some(wireframe_mesh) = query_context.store_ctx().caches.entry(
|c: &mut proc_mesh::WireframeCache| c.entry(proc_mesh_key, self.render_ctx),
) else {
return Err(ViewSystemExecutionError::DrawDataCreationError(
"Failed to allocate wireframe mesh".into(),
));
};
for strip in &wireframe_mesh.line_strips {
let strip_builder = line_batch
.add_strip(
strip
.iter()
.map(|&point| world_from_instance.transform_point3(point)),
)
.color(color)
.radius(radius)
.picking_instance_id(PickingLayerInstanceId(instance_index as _))
// Looped lines should be connected with rounded corners.
.flags(LineStripFlags::FLAGS_OUTWARD_EXTENDING_ROUND_CAPS);
if let Some(outline_mask_ids) = ent_context
.highlight
.instances
.get(&Instance::from(instance_index as u64))
{
// Not using ent_context.highlight.index_outline_mask() because
// that's already handled when the builder was created.
strip_builder.outline_mask_ids(*outline_mask_ids);
}
}
}
FillMode::Solid => {
let store_ctx = query_context.store_ctx();
let Some(solid_mesh) =
store_ctx.caches.entry(|c: &mut proc_mesh::SolidCache| {
c.entry(proc_mesh_key, self.render_ctx)
})
else {
return Err(ViewSystemExecutionError::DrawDataCreationError(
"Failed to allocate solid mesh".into(),
));
};
self.solid_instances.push(GpuMeshInstance {
gpu_mesh: solid_mesh.gpu_mesh,
world_from_mesh: world_from_instance,
outline_mask_ids: ent_context.highlight.index_outline_mask(instance),
picking_layer_id: re_view::picking_layer_id_from_instance_path_hash(
InstancePathHash::instance(entity_path, instance),
),
additive_tint: color,
});
}
}
}

In constrast, spheres and points are ~100x faster in Rerun.

Optimizing boxes in particular would be nice because it is very useful for rendering voxel occupancy grids.

Approaches

Speed up instanced rendering

Provide a way of mapping transforms onto the GPU directly, speeding up rendering of all our primitives.

Write specific shaders for boxes

We could consider a fast-path for boxes, like we have for spheres, e.g. generating the vertex data in a shader.

Related

The way we solve this could maybe also speed up having millions of Ellipsoids3D, which would unblock:

Links

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions