Repository navigation
Conversation
Instead of always blindly continuing along the 'cont' edge, we now can use the swap edge even if cont edge is valid; this is done when the number of neighboring triangles that we haven't emitted yet in the swap case is lower. This is actually part of the SGI algorithm that's also described in the Evans paper; during the original implementation I must have missed this fact. This seems suboptimal: cont edge results in zero new indices emitted. However, taking swaps more eagerly results in better stripification - a locally suboptimal choice is more optimal globally. This is because when the swap triangle has few remaining neighbors, it's expensive to re-stripify it later in the process, and may create many single-triangle strips. Number of neighboring triangles is an approximation through valence; the shared vertex between cont & swap must have valence >= 2, so countSharedVertices returns 1, 2 or 3 for each triangle, which corresponds to 0, 1 or 3 shared edges, assuming manifold topology. By itself, this results in significant ACMR improvement and a moderate overall improvement in the triangle strip size / reduction in indices; because this gives us ACMR budget, we use it to increase the buffer size to 11 which maintains ~neutral ACMR but significantly improves stripification quality (5.5% fewer indices, 41% more triangles per strip, small improvement in ACMR on a test set of 32 meshes).
The lowest-valence heuristic by itself is reasonable but if we run into a situation where we pick between cont & swap, then it is better to restart the strip from that skipped triangle instead. This is the same idea as the one Hoppe uses in his stripification paper; that paper maintains a full queue whereas we just record the last triangle for simplicity. By itself, this improves ACMR a bit, as it favors more recent triangles; we bump up buffer size a little to compensate for that and take the win in strip sizes instead. On a test mesh set, this results in ~7.8% more triangles/strip and ~1.6% fewer indices, at a small ACMR loss (0.4%); the previous change was a slightly more significant net improvement on ACMR so overall this is still a bit ahead of the original code (with buffer size 8).
Instead of checking individual edge endpoints, we now check the entire edge code with a single 64-bit comparison; this reduces branch mispredictions significantly. Also, when we try to continue the strip along one of the edges, we can check if the remaining valence of the vertex is already at 0; if it is, we don't need to scan as we have already run out of triangles. The second optimization makes stripify ~8% faster, and the first one gives ~16% extra performance on top. Between these two we're now fairly close to the original performance of the stripifier (with a smaller buffer and old heuristics).
With the updates to the stripification heuristics, we now have longer strips which makes restart indices a bit less profitable than before; on average they still save around 6% of indices. Also some comments about valence uses are now out of date, so this change fixes them too.
Owner
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Instead of always blindly continuing along the 'cont' edge, we now can
use the swap edge even if cont edge is valid; this is done when the
number of neighboring triangles that we haven't emitted yet in the swap
case is lower.
This is actually part of the SGI algorithm that's also described in the
Evans paper; during the original implementation I must have missed this
fact. This seems suboptimal: cont edge results in zero new indices
emitted. However, taking swaps more eagerly results in better
stripification - a locally suboptimal choice is more optimal globally.
For restarts, the lowest-valence heuristic by itself is reasonable but if we
run into a situation where we pick between cont & swap, then it is better
to restart the strip from that skipped triangle instead. This is the same
idea as the one Hoppe uses in his stripification paper; that paper
maintains a full queue whereas we just record the last triangle for
simplicity.
Together these result in significant ACMR improvement and a moderate
overall improvement in the triangle strip size / reduction in indices;
because this gives us ACMR budget, we use it to increase the buffer size
to 12 which maintains ~neutral ACMR but significantly improves
stripification quality, producing ~10% fewer indices and ~50% longer strips.
This contribution is sponsored by Valve.