Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

gltfpack: Accelerate deduplication pass for scenes with a lot of primitives #790

Merged
merged 4 commits into from
Oct 16, 2024

Conversation

zeux
Copy link
Owner

@zeux zeux commented Oct 16, 2024

While on most scenes our strategy performs reasonably well, and we
already have some potential N^2 processing elsewhere, there are cases
where the existing N^2 algorithms in the pipeline are actually
semi-linear, because mesh merging lazily and effectively aggregates most
meshes; since deduplication is the first pass, it may actually be
quadratic in the face of a scene with a lot of meshes.

A simple fix is to track the number of occurences of each hash and only
search for duplicates for meshes where this value is >1. We could of
course implement more involved tracking but for now this works just
fine.

We also now prune the node list to avoid accidental duplicate attachments,
as it confuses the logic downstream in the pipeline.

While on most scenes our strategy performs reasonably well, and we
already have some potential N^2 processing elsewhere, there are cases
where the existing N^2 algorithms in the pipeline are actually
semi-linear, because mesh merging lazily and effectively aggregates most
meshes; since deduplication is the first pass, it may actually be
quadratic in the face of a scene with a lot of meshes.

A simple fix is to track the number of occurences of each hash and only
search for duplicates for meshes where this value is >1. We could of
course implement more involved tracking but for now this works just
fine.
Neither std::map nor std::unordered_map are particularly good
containers, but since we're now using unordered_map for deduplication
filtering we might as well use it for the primitive cache. This requires
a custom hash function for pair<uint64, uint64>, but our hash halves are
sufficiently decorellated that a xor suffices.
This almost never comes up in practice, but occasionally scenes might
have the same geometry attached to the same nodes. This results in
counterintuitive results because we create node lists with duplicate
nodes for this, which never happened before, and end up producing more
quantization sub-nodes than necessary.

For now we can just filter these attachments out to avoid redundancy.
clang-tidy complains that we're dividing an integer by 3 before a float
cast; this is correct as the division is exact, and a cast silences it.
@zeux zeux merged commit 8c86684 into master Oct 16, 2024
12 checks passed
@zeux zeux deleted the gltf-ddperf branch October 16, 2024 20:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant