Closed zeux closed 2 months ago
I've tested this in Bevy using https://github.com/bevyengine/bevy/pull/13431 and the following diff (probably could have left 0.5 factor in but I am not sure it's correct to apply it!), and after that change simplification is barely visible in the profile - the overall process of data preparation is still not very fast because Bevy's meshlet connectivity analysis (find_connected_meshlets
) is slow, but I'm sure that can be made faster separately.
For the above to work, meshopt-rs needs to get two extra enum entries and that's it.
Going to mark this as ready to merge although I want to look into using a hash map for second part of buildSparseRemap as on Windows the large allocation is not as fast as I'd like it to be (buildSparseRemap accounts for ~30% of cluster simplification there compared to ~2% on Linux).
When simplifying a small subset of the larger mesh, all computations that go over the entire vertex buffer become expensive; this adds up even when done once, and especially when done for every pass. This is a critical part of some workflows that combine clusterization and simplification, notably Nanite-style virtual geometry renderers.
This change introduces a sparse simplification mode that instructs the simplifier to optimize based on the assumption that the subset of the mesh that is being simplified is small. In that case it's worth spending extra time to convert indices into a small 0..U subrange, do all internal processing assuming we are working with a small vertex/index buffer, and remap the indices at the end. While this processing could be done externally, that is less efficient as it requires constant copying of position/attribute data; in constrast, we can do it fairly cheaply.
When using sparse simplification, the error is treated as relative to the mesh subset. This is a performance requirement as computing the full mesh extents is too expensive when the subset is small relative to the mesh, but it means that it can be difficult to rely on exact error metrics.
There are also cases in general, when not using sparse simplification, when an absolute error is more convenient. These can be achieved right now via
meshopt_simplifyScale
but that is an extra step that is not always necessary.The new features can be accessed by adding
meshopt_SimplifySparse
andmeshopt_SimplifyErrorAbsolute
bit flags to simplification options.As an example of a performance delta, the newly added
simplifyClusters
demo call takes 17.7 seconds to simplify a 870K triangle mesh one cluster at a time, with the new sparse mode it takes ~150 msec (100x faster).