gl_RayFlagsSkipClosestHitShaderEXT for Occlusion Rays

In hardware-accelerated ray tracing pipelines using GLSL, evaluating pure occlusion—such as shadow or ambient occlusion testing—requires determining only whether an intersection exists along a ray rather than computing detailed surface attributes. The gl_RayFlagsSkipClosestHitShaderEXT flag streamlines this process by instructing the ray tracing hardware to bypass the execution of the Closest Hit Shader (CHS) entirely when an intersection is confirmed. This article examines how this flag operates at the pipeline level, how it interacts with ray payloads, and how combining it with complementary traversal flags optimizes occlusion queries into fast, fixed-function visibility checks.

The Inefficiency of the Closest Hit Shader in Occlusion Queries

In a standard ray tracing pipeline, rays identify the nearest surface interaction, after which the pipeline invokes the Closest Hit Shader associated with the hit geometry. The CHS typically evaluates lighting, materials, and secondary rays, writing the results into the ray payload.

For pure occlusion rays, however, the exact surface properties, texture coordinates, and lighting data of the occluder are irrelevant. The query only needs to yield a binary result: whether the ray path between the origin and the target is clear or blocked. Invoking a CHS for an occlusion ray introduces substantial latency by scheduling, launching, and executing unnecessary programmable shader stages and memory writes.

How gl_RayFlagsSkipClosestHitShaderEXT Bypasses Execution

When gl_RayFlagsSkipClosestHitShaderEXT is passed to the traceRayEXT() call in GLSL, it sets a hardware traversal state that modifies how the pipeline handles ray termination:

  1. State Evaluation: During acceleration structure traversal, the hardware tests for ray-primitive intersections.
  2. Hit Confirmation: If the ray determines an intersection with an opaque surface (or passes the Any-Hit Shader test), the ray state is marked as having hit geometry.
  3. Execution Suppression: Under normal execution, concluding traversal with an active hit triggers the binding and execution of the corresponding hit group's CHS. Setting gl_RayFlagsSkipClosestHitShaderEXT tells the pipeline to drop the CHS stage completely.
  4. Control Return: Traversal halts without invoking any shader code from the hit group, returning execution directly to the calling shader (typically the Ray Generation Shader) or transferring state back to the caller.

Payload Management for Binary Visibility

Because the Closest Hit Shader does not run, it cannot be relied upon to write data to the ray payload indicating an occlusion event. Instead, the application determines visibility using initialization patterns or the Miss Shader:

  • Miss-Shader Strategy: The Ray Generation Shader initializes the ray payload to represent an occluded state (e.g., visibility = 0.0). If the ray encounters geometry, the CHS is skipped, leaving the payload as 0.0. If the ray encounters no geometry along its path, the Miss Shader executes and updates the payload to represent an unoccluded state (e.g., visibility = 1.0).
  • Direct Ray Queries: When using inline ray queries (rayQueryEXT), skipping hit shaders avoids pipeline state transitions entirely, letting fixed-function hardware handle the query while the calling shader checks rayQueryGetIntersectionTypeEXT().

Pairing Flags for Maximum Traversal Throughput

To achieve zero programmable shader overhead for pure occlusion, gl_RayFlagsSkipClosestHitShaderEXT is combined with other ray flags:

  • gl_RayFlagsTerminateOnFirstHitEXT: Forces the traversal unit to stop immediately upon encountering the first valid intersection rather than searching for the true closest hit along the ray interval.
  • gl_RayFlagsOpaqueEXT: Treats all geometry as fully opaque, bypassing Any-Hit Shader invocations.

When gl_RayFlagsSkipClosestHitShaderEXT, gl_RayFlagsTerminateOnFirstHitEXT, and gl_RayFlagsOpaqueEXT are used together, the ray traversal operates entirely within fixed-function hardware. Any-Hit shaders are skipped, traversal aborts on the first primitive encountered, and the Closest Hit Shader never launches. This turns occlusion testing into a highly optimized, hardware-accelerated boolean operation.