rayQueryGetIntersectionTypeEXT Candidate vs Committed Hits
In Vulkan ray tracing using GLSL,
rayQueryGetIntersectionTypeEXT determines whether a ray has
intersected geometry and identifies the kind of geometry encountered.
Rather than using separate functions to distinguish between temporary
candidate hits and final committed hits, the function relies on a
explicit boolean parameter passed by the developer. This article
explains how this boolean parameter operates within the ray query
lifecycle, how candidate and committed states differ, and the return
values associated with each state.
The Function Signature and Parameter
The GLSL function signature defined by the
GL_EXT_ray_query extension is:
uint rayQueryGetIntersectionTypeEXT(rayQueryEXT rayQuery, bool committed);The function differentiates candidate hits from committed hits solely
through the second parameter, committed:
committed = false: Evaluates the current candidate intersection.committed = true: Evaluates the currently committed (confirmed) intersection.
Understanding
Candidate Hits (committed = false)
A candidate hit represents an unconfirmed intersection encountered while traversing the acceleration structure. Traversal pauses at a candidate hit whenever the ray query encounters geometry that requires shader intervention, such as non-opaque geometry or procedural AABBs.
When rayQueryProceedEXT(rayQuery) returns
true, traversal has temporarily yielded control back to the
shader. At this stage, querying with committed = false
returns the geometry type of the hit under evaluation:
rayQueryIntersectionTriangleEXT: A candidate triangle has been hit. For non-opaque triangles, the shader can inspect properties (like alpha testing) and choose whether to callrayQueryConfirmIntersectionEXT()to commit the hit.rayQueryIntersectionGeneratedEXT: An axis-aligned bounding box (AABB) for a procedural primitive has been reached. The shader must perform custom intersection logic and potentially commit a hit usingrayQueryGenerateIntersectionEXT().
If committed = false is passed when no candidate is
currently active, the function returns
rayQueryIntersectionNoneEXT.
Understanding
Committed Hits (committed = true)
A committed hit represents an intersection that has been accepted as valid. For opaque geometry, the hardware traversal engine automatically commits the intersection. For non-opaque or procedural geometry, it represents a candidate that the shader explicitly confirmed.
Querying with committed = true inspects the best valid
hit found so far:
- Inside the traversal loop: It returns the state of the closest confirmed hit up to the current point of execution.
- After the traversal loop terminates: When
rayQueryProceedEXT()returnsfalse, traversal is complete. CallingrayQueryGetIntersectionTypeEXT(rayQuery, true)reveals the final result of the entire ray query.
The return values for committed queries are:
rayQueryIntersectionNoneEXT: No valid intersection was committed (a miss).rayQueryIntersectionTriangleEXT: The final committed hit is a triangle.rayQueryIntersectionGeneratedEXT: The final committed hit is a procedural primitive.
Typical Execution Pattern
In practice, the distinction controls the flow within a ray query:
rayQueryEXT rq;
rayQueryInitializeEXT(rq, topLevelAS, rayFlags, cullMask, origin, tMin, direction, tMax);
while (rayQueryProceedEXT(rq)) {
// Inspect candidate hit to make confirmation decisions
if (rayQueryGetIntersectionTypeEXT(rq, false) == rayQueryIntersectionTriangleEXT) {
// Perform alpha testing or custom opacity logic
if (shouldAcceptHit()) {
rayQueryConfirmIntersectionEXT(rq);
}
}
}
// Inspect the final committed hit after traversal finishes
if (rayQueryGetIntersectionTypeEXT(rq, true) != rayQueryIntersectionNoneEXT) {
// Shade the confirmed hit
}By toggling the boolean flag,
rayQueryGetIntersectionTypeEXT cleanly separates the
transient evaluation state during traversal from the persistent,
confirmed hit record.