DXR 1.1 Inline Raytracing and Ray Queries Explained
DirectX Raytracing (DXR) Tier 1.1 expands the capabilities of real-time raytracing in DirectX 12 by introducing inline raytracing via ray queries. This feature allows developers to execute ray traversal directly inside existing standard shader stages—such as compute, pixel, or vertex shaders—without relying on the heavy, state-driven raytracing pipeline introduced in DXR 1.0. This article explains how inline raytracing functions through ray queries, how it differs from traditional dynamic-dispatch raytracing, and where it provides the greatest performance and structural advantages.
The Shift from Dynamic Dispatch to Inline Raytracing
In DXR Tier 1.0, raytracing required a dedicated execution pipeline
initialized via DispatchRays. This pipeline relied on
distinct, specialized raytracing shader stages—Ray Generation, Any Hit,
Closest Hit, Miss, and Intersection shaders—coordinated through complex
Shader Binding Tables (SBTs). While ideal for scenarios with diverse
material types and multi-bounce global illumination, this dynamic
dispatch model introduced substantial runtime scheduling overhead,
pipeline state compilation costs, and state-management complexity for
simple visibility checks.
DXR Tier 1.1 addresses this by introducing inline raytracing. Rather than dispatching an entire dedicated raytracing pipeline, developers can invoke ray queries directly inside conventional HLSL shaders. Ray queries expose ray traversal as a set of intrinsic methods, giving the calling shader complete manual control over traversal, hit evaluation, and shading.
How Ray Queries Work in HLSL
Ray queries function through the templated HLSL object
RayQuery<RayFlags>. Traversal is driven synchronously
inside the shader execution flow through a controlled loop rather than
hardware-driven shader invocation.
Initialization: The shader instantiates a
RayQueryobject and configures it usingTraceRayInline(). This call takes the acceleration structure, ray flags, instance inclusion mask, and the ray description (origin, direction, and range limits).Traversal Loop: The shader advances traversal by repeatedly calling the
Proceed()method inside a loop:RayQuery<RAY_FLAG_NONE> q; q.TraceRayInline(TopLevelAS, RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH, 0xFF, ray); while (q.Proceed()) { // Handle custom intersection or any-hit logic manually }Candidate Processing: During
Proceed(), if the traversal hits non-opaque geometry or procedural primitives requiring shader intervention, the loop pauses and yields control back to the shader. The shader inspects the candidate hit usingq.CandidateType(), performs alpha testing or custom intersection tests, and either accepts the hit viaq.CommitNonOpaqueTriangleHit()or rejects it.Final Result: Once
Proceed()returnsfalse, traversal is complete. The shader queriesq.CommittedStatus()to check if a valid hit occurred and retrieves hit attributes (such as barycentrics, instance ID, and primitive ID) to perform custom lighting inline.
Key Architectural Advantages
- Any-Stage Availability: Ray queries can be executed in compute shaders, pixel shaders, or even amplification and mesh shaders, integrating directly into existing rasterization or G-buffer pipelines.
- Elimination of Shader Binding Tables: Because hit processing and shading occur inline within the caller shader, developers do not need to configure hit groups or complex Shader Binding Tables for straightforward ray tests.
- Reduced Register and Divergence Overhead: Standard raytracing pipelines often suffer from divergence when different hits invoke widely different hit shaders. Inline raytracing keeps the control flow localized, allowing the compiler to optimize register allocation and scheduling directly within the host shader.
- Deterministic Execution: The host shader retains full authority over whether to continue searching, abort early, or limit traversal depth, providing precise control over worst-case performance scenarios.
Practical Use Cases
Inline raytracing through ray queries is primarily designed for lightweight, coherent ray casting tasks. Common implementations include:
- Shadow Rays: Determining binary visibility between
a surface point and a light source using
RAY_FLAG_ACCEPT_FIRST_HIT_AND_END_SEARCH, bypassing any need for complex hit evaluation. - Ambient Occlusion: Sampling local hemisphere occlusion within a compute or pixel shader pass without context-switching to an asynchronous pipeline.
- Screen-Space Fallbacks: Tracing short-range reflection or contact-shadow rays in compute passes where screen-space data is missing.
While DXR 1.0 dynamic dispatch remains optimal for complex scenes with thousands of disparate materials requiring recursive shading, DXR Tier 1.1 ray queries make ray casting accessible as an on-demand primitive across the entire graphics pipeline.