Understanding GL_EXT_ray_query in GLSL Shaders
This article provides an overview of the
GL_EXT_ray_query extension in GLSL, focusing on how ray
query objects function within compute and fragment shaders. By
introducing inline ray tracing capabilities, this extension allows
developers to query acceleration structures directly within standard
shader stages without requiring a dedicated ray tracing pipeline. Below,
we examine the fundamental mechanics of ray query objects, their
integration into compute and fragment workloads, key use cases, and
performance considerations.
What is GL_EXT_ray_query?
The GL_EXT_ray_query extension introduces inline ray
tracing to traditional execution stages, such as compute, fragment, and
vertex shaders. Unlike the dedicated ray tracing pipeline
(GL_EXT_ray_tracing)—which relies on separate shader stages
like ray generation, closest-hit, any-hit, and miss shaders—ray queries
operate entirely within a single shader invocation.
The core mechanism is the rayQueryEXT object. This
opaque type manages the traversal state of a ray intersecting a
top-level acceleration structure (TLAS).
How Ray Query Objects Work
A ray query follows an explicit, step-by-step traversal loop managed directly in the shader code:
- Declaration: The shader declares an acceleration
structure uniform (
accelerationStructureEXT) and a localrayQueryEXTobject. - Initialization: The function
rayQueryInitializeEXT()initializes the query with parameters such as the target acceleration structure, ray flags (e.g., cull masks, terminate on first hit), ray origin, direction, and clipping distances (\(t_{min}\) and \(t_{max}\)). - Traversal: The shader advances through the
acceleration structure using
rayQueryProceedEXT(), typically within awhileloop. This function returnstruewhile traversal is ongoing andfalsewhen it finishes. - Hit Evaluation: For geometries with custom intersection or transparency needs (non-opaque geometry), the shader can process candidate hits during traversal.
- Result Extraction: Once traversal completes,
functions such as
rayQueryGetIntersectionTypeEXT()determine if a primitive was struck, alongside functions to retrieve intersection distances, hit instance IDs, and barycentric coordinates.
Role in Fragment Shaders
In fragment shaders, ray query objects bring hardware-accelerated ray tracing to standard rasterization pipelines:
- Hard and Soft Shadows: Instead of relying on shadow maps and dealing with cascading or biasing artifacts, a fragment shader can cast a single shadow ray directly toward a light source to determine visibility.
- Ambient Occlusion (RTAO): Fragment shaders can shoot a small set of randomized hemisphere rays around the surface normal to compute accurate local ambient occlusion.
- Simple Reflections: Fragment shaders can perform simple secondary ray casts to sample reflections directly from screen-space buffers or acceleration structures for glossy materials.
Role in Compute Shaders
Compute shaders gain fine-grained, parallel spatial querying capabilities with ray queries:
- Hybrid Post-Processing: Compute passes can gather lighting data, compute diffuse indirect illumination, or trace glossy reflections across full-screen tiles without leaving the compute workflow.
- Non-Graphics Computations: Compute shaders can use ray queries for game physics, light baking, sound propagation tracing, and line-of-sight/visibility testing for artificial intelligence.
Key Advantages and Trade-Offs
Advantages:
- Pipeline Simplicity: Ray queries avoid the overhead and complexity of configuring dedicated ray tracing pipelines, shader binding tables (SBTs), and pipeline compilation.
- Seamless Integration: They integrate directly into existing deferred or forward rendering architectures.
- Dynamic Control: Shaders retain complete control over ray flow, allowing for early exits or conditional tracing based on material properties or screen-space information.
Trade-offs:
- Divergence and Register Pressure: Manual traversal loops can lead to execution divergence across thread warps/wavefronts and require higher register usage, which may lower GPU occupancy compared to hardware-scheduled ray tracing pipelines.
- No Dynamic Shading: Because ray queries do not invoke separate hit shaders automatically, complex multi-material handling must be decoded and executed manually by the initiating shader.