Fix ray masking in hybrid occlusion traversal - #636
Open
BrianSharpe wants to merge 1 commit into
Open
BrianSharpe wants to merge 1 commit into
BrianSharpe wants to merge 1 commit into
Conversation
Restrict primitive tests and termination updates to active leaf rays in both packet paths, preventing duplicate filter callbacks.
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.
This fixes a bug where Embree executes the FilterFunction many times for a single hit during a call to rtcOccluded1M(), even on LOW and MEDIUM build quality. A workaround was to either avoid RTC_INTERSECT_CONTEXT_FLAG_COHERENT, or fall back to rtcOccluded1(), but this fixes the bug properly.
Disclaimer:
We encountered these bugs firsthand in our renderer. But have used ChatGPT to...
repro programs
embree-pr-repro.zip
Description:
Two packet occlusion paths call the primitive intersector with
!terminatedinstead of the rays active for the current leaf. This can repeat a filter callback for the same ray/primitive hit when the filter rejects the hit and continues traversal. Filters that accumulate contributions, such as additive emission or transparency, can therefore produce incorrect results.The affected paths are:
valid_leafmask is ignored, allowing rays to test temporal references outside their times.m_activemask is ignored, allowing rays from other direction octants to test the same primitive repeatedly.Both calls now pass the active leaf mask and restrict the returned termination mask to those same lanes. Masking the result is necessary because
ArrayIntersectorK_1::occluded()returns!valid0, which also includes lanes excluded from its input.Two standalone C reproducers are attached, with build instructions.
Compile against Embree 4 and run on an AVX2 CPU:
motion_occlusion isa=avx2
coherent_occlusion isa=avx2
The motion example uses rotating sphere instances and mixed ray times. Before the fix, packet traversal reports 128 entries instead of 64.
The coherent example uses one static triangle. Before the fix, two/four direction octants produce 128/256 hits instead of 64.
Both use MEDIUM build quality. Scalar traversal and control cases report 64 throughout. After the fix, all cases report 64. Each program checks every ray and returns 1 on failure or 0 on success.
Validated as C with MSVC 19.42 against master
3d9cb89band patched commitdf361682, using AVX and AVX2.