From b7212656934e04a923cee4beea1ecfa714b94250 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Tue, 1 Oct 2024 19:45:31 -0700 Subject: [PATCH] demo: Use a flexible (and larger) cluster group size Using 4 clusters is fairly limiting wrt partition quality, as it demands very careful grouping that METIS is not willing to provide. Instead use a larger group size (8 atm), and adjust the simplification condition to be adaptive to the group size so that partitioning is free to produce groups of varying sizes. --- demo/nanite.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/demo/nanite.cpp b/demo/nanite.cpp index 13f7c216..868bc1c2 100644 --- a/demo/nanite.cpp +++ b/demo/nanite.cpp @@ -51,6 +51,7 @@ struct Cluster }; const size_t kClusterSize = 128; +const size_t kGroupSize = 8; const bool kUseLocks = true; static LODBounds bounds(const std::vector& vertices, const std::vector& indices, float error) @@ -335,7 +336,7 @@ static std::vector > partitionMetis(const std::vector& int nvtxs = int(pending.size()); int ncon = 1; - int nparts = int(pending.size() + 3) / 4; + int nparts = int(pending.size() + kGroupSize - 1) / kGroupSize; int edgecut = 0; if (nparts <= 1) @@ -375,7 +376,7 @@ static std::vector > partition(const std::vector& clus // rough merge; while clusters are approximately spatially ordered, this should use a proper partitioning algorithm for (size_t i = 0; i < pending.size(); ++i) { - if (result.empty() || last_indices + clusters[pending[i]].indices.size() > kClusterSize * 4 * 3) + if (result.empty() || last_indices + clusters[pending[i]].indices.size() > kClusterSize * kGroupSize * 3) { result.push_back(std::vector()); last_indices = 0; @@ -527,9 +528,10 @@ void nanite(const std::vector& vertices, const std::vector dumpObj("group", merged); } + size_t target_size = ((groups[i].size() + 1) / 2) * kClusterSize * 3; float error = 0.f; - std::vector simplified = simplify(vertices, merged, kUseLocks ? &locks : NULL, kClusterSize * 2 * 3, &error); - if (simplified.size() > merged.size() * 0.85f || simplified.size() > kClusterSize * 3 * 3) + std::vector simplified = simplify(vertices, merged, kUseLocks ? &locks : NULL, target_size, &error); + if (simplified.size() > merged.size() * 0.85f || simplified.size() / (kClusterSize * 3) >= merged.size() / (kClusterSize * 3)) { #if TRACE printf("stuck cluster: simplified %d => %d over threshold\n", int(merged.size() / 3), int(simplified.size() / 3));