From 25d17a3d92c1931a9b7dd36646f0729a189f7365 Mon Sep 17 00:00:00 2001 From: Arseny Kapoulkine Date: Wed, 4 Sep 2024 19:23:12 -0700 Subject: [PATCH] demo: Reinsert stuck clusters into the queue This means that small clusters that end up being too small to merge or edge-locked enough so that simplification is not effective may get another chance further into the process to get merged with other clusters. This is generally beneficial for quality although sometimes results in worse results and definitely results in slower processing as the stuck triangles keep being reevaluated on every pass. --- demo/nanite.cpp | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/demo/nanite.cpp b/demo/nanite.cpp index 482f7129..2349f757 100644 --- a/demo/nanite.cpp +++ b/demo/nanite.cpp @@ -226,7 +226,6 @@ static std::vector clusterize(const std::vector& vertices, cons return clusterizeMetis(vertices, indices); #endif - const size_t max_vertices = 192; // TODO: depends on kClusterSize, also may want to dial down for mesh shaders const size_t max_triangles = kClusterSize; @@ -427,6 +426,8 @@ void nanite(const std::vector& vertices, const std::vector std::vector > groups = partition(clusters, pending); pending.clear(); + std::vector retry; + size_t triangles = 0; size_t stuck_triangles = 0; int stuck_clusters = 0; @@ -456,19 +457,23 @@ void nanite(const std::vector& vertices, const std::vector stuck_clusters++; stuck_triangles += merged.size() / 3; + for (size_t j = 0; j < groups[i].size(); ++j) + retry.push_back(groups[i][j]); continue; // didn't merge enough // TODO: this is very suboptimal as it leaves some edges of other clusters permanently locked. } float error = 0.f; std::vector simplified = simplify(vertices, merged, kClusterSize * 2 * 3, &error); - if (simplified.size() >= kClusterSize * 3 * 3) + if (simplified.size() > kClusterSize * 3 * 3) { #if TRACE printf("stuck cluster: simplified triangles %d over threshold\n", int(simplified.size() / 3)); #endif stuck_clusters++; stuck_triangles += merged.size() / 3; + for (size_t j = 0; j < groups[i].size(); ++j) + retry.push_back(groups[i][j]); continue; // simplification is stuck; abandon the merge } @@ -507,8 +512,13 @@ void nanite(const std::vector& vertices, const std::vector } depth++; - printf("lod %d: %d clusters (%d full), %d triangles (%d triangles stuck in %d clusters)\n", depth, - int(pending.size()), full_clusters, int(triangles), int(stuck_triangles), stuck_clusters); + printf("lod %d: simplified %d clusters (%d full), %d triangles; stuck %d clusters, %d triangles\n", depth, + int(pending.size()), full_clusters, int(triangles), stuck_clusters, int(stuck_triangles)); + + if (triangles < stuck_triangles / 3) + break; + + pending.insert(pending.end(), retry.begin(), retry.end()); } size_t lowest_triangles = 0;