• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2018-2021 The Khronos Group Inc.
2//
3// SPDX-License-Identifier: CC-BY-4.0
4
5[[ray-traversal]]
6= Ray Traversal
7
8The ray traversal process identifies and handles intersections between a ray
9and geometries in an acceleration structure.
10
11Ray traversal cannot be started by a Vulkan API command directly - a shader
12must execute
13ifdef::VK_KHR_ray_query[code:OpRayQueryProceedKHR]
14ifdef::VK_KHR_ray_query+VK_KHR_ray_tracing_pipeline[or]
15ifdef::VK_KHR_ray_tracing_pipeline[code:OpTraceRayKHR]
16.
17ifdef::VK_KHR_ray_tracing_pipeline[]
18When the <<features-rayTracingPipeline,pname:rayTracingPipeline>> feature is
19enabled, code:OpTraceRayKHR can: be used for <<ray-tracing, ray tracing>> in
20a <<pipelines-ray-tracing, ray tracing pipeline>>.
21endif::VK_KHR_ray_tracing_pipeline[]
22ifdef::VK_KHR_ray_query[]
23When the <<features-rayQuery,pname:rayQuery>> feature is enabled,
24code:OpRayQueryProceedKHR can: be used in any shader stage.
25endif::VK_KHR_ray_query[]
26
27[[ray-intersection-candidate-determination]]
28== Ray Intersection Candidate Determination
29
30Once tracing begins, rays are first tested against instances in a top-level
31acceleration structure.
32A ray that intersects an instance will be transformed into the space of the
33instance to continue traversal within that instance; therefore the transform
34matrix stored in the instance must be invertible.
35
36Next, rays are tested against geometries in an bottom-level acceleration
37structure to determine if a hit occurred between them, initially based only
38on their geometric properties (i.e. their vertices).
39The implementation performs similar operations to that of rasterization, but
40with the effective viewport determined by the parameters of the ray, and the
41geometry transformed into a space determined by that viewport.
42
43The vertices of each primitive are transformed from acceleration structure
44space #~as~# to ray space #~r~# according to the ray origin and direction as
45follows:
46
47[latexmath]
48++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
49\left(
50    \begin{array}{c}
51        x_{r} \\
52        y_{r}\\
53        z_{r}
54    \end{array}
55\right) =
56\left(
57    \begin{matrix}
58        a_x^2(1-c)  + c    & a_xa_y(1-c) - sa_z & a_xa_z(1-c) + sa_y \\
59        a_xa_y(1-c) + sa_z & a_y^2(1-c)  + c    & a_ya_z(1-c) - sa_x \\
60        a_xa_z(1-c) - sa_y & a_ya_z(1-c) + sa_x & a_z^2(1-c)  + c
61    \end{matrix}
62\right)
63\left(
64    \begin{array}{c}
65        x_{as} - o_x \\
66        y_{as} - o_y \\
67        z_{as} - o_z
68    \end{array}
69\right)
70++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
71
72latexmath:[\mathbf{a}] is the axis of rotation from the unnormalized ray
73direction vector latexmath:[\mathbf{d}] to the axis vector
74latexmath:[\mathbf{k}]:
75
76[latexmath]
77++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
78\mathbf{a} = \begin{cases}
79    \frac{\mathbf{d} \times \mathbf{k}}{|| \mathbf{d} \times \mathbf{k} ||} & \mathrm{if}\; || \mathbf{d} \times \mathbf{k} || \ne 0 \\
80    \left(\begin{array}{c}
81    0 \\
82    1 \\
83    0
84    \end{array}
85    \right) & \mathrm{if}\; || \mathbf{d} \times \mathbf{k} || = 0 \\
86  \end{cases}
87++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
88
89latexmath:[\mathit{s}] and latexmath:[\mathit{c}] are the sine and cosine of
90the angle of rotation about latexmath:[\mathbf{a}] from
91latexmath:[\mathbf{d}] to latexmath:[\mathbf{k}]:
92
93[latexmath]
94++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
95\begin{aligned}
96c      &= {{\mathbf{d} \cdot \mathbf{k}}\over{||\mathbf{d}||}} \\
97s      &= \sqrt{1 - c^2}
98\end{aligned}
99++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
100
101latexmath:[\mathbf{k}] is the unit vector:
102
103[latexmath]
104++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
105\mathbf{k} = \left(
106    \begin{array}{c}
107        0 \\
108        0 \\
109        -1
110    \end{array}
111\right)
112++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
113
114latexmath:[\mathbf{o}] and latexmath:[\mathbf{d}] are the ray origin and
115unnormalized direction, respectively; the vector described by [eq]#x~as~#,
116[eq]#y~as~#, and [eq]#z~as~# is any position in acceleration structure
117space; and the vector described by [eq]#x~r~#, [eq]#y~r~#, and [eq]#z~r~# is
118the same position in ray space.
119
120An _intersection candidate_ is a unique point of intersection between a ray
121and a geometric primitive.
122For any primitive that has within its bounds a position
123latexmath:[\mathbf{xyz_{as}}] such that
124
125[latexmath]
126++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
127\begin{aligned}
128             x_r &= 0 \\
129             y_r &= 0 \\
130t_\mathit{min} \lt {-{z_r}\over{||\mathbf{d}||}}  &\lt t_\mathit{max}  & \text{if the primitive is a triangle,} \\
131t_\mathit{min} \leq {-{z_r}\over{||\mathbf{d}||}} &\leq t_\mathit{max} & \text{otherwise} \\
132\end{aligned}
133++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
134
135(where latexmath:[t = {-{z_r}\over{||\mathbf{d}||}}]), an intersection
136candidate exists.
137
138Triangle primitive bounds consist of all points on the plane formed by the
139three vertices and within the bounds of the edges between the vertices,
140subject to the watertightness constraints below.
141AABB primitive bounds consist of all points within an implementation-defined
142bound which includes the specified box.
143
144[NOTE]
145.Note
146====
147The bounds of the AABB including all points internal to the bound implies
148that a ray started within the AABB will hit that AABB.
149====
150
151[[raytraversal-ray-intersection-candidate-diagram]]
152image::{images}/ray_intersection_candidate.svg[align="center",title="Ray intersection candidate",opts="{imageopts}"]
153
154The determination of this condition is performed in an implementation
155specific manner, and may: be performed with floating point operations.
156Due to the complexity and number of operations involved, inaccuracies are
157expected, particularly as the scale of values involved begins to diverge.
158Implementations should: take efforts to maintain as much precision as
159possible.
160
161[NOTE]
162.Note
163====
164One very common case is when geometries are close to each other at some
165distance from the origin in acceleration structure space, where an effect
166similar to "`z-fighting`" is likely to be observed.
167Applications can mitigate this by ensuring their detailed geometries remain
168close to the origin.
169
170Another likely case is when the origin of a ray is set to a position on a
171previously intersected surface, and its [eq]#t~min~# is zero or near zero;
172an intersection may be detected on the emitting surface.
173This case can usually be mitigated by offsetting [eq]#t~min~# slightly.
174====
175
176ifdef::VK_NV_ray_tracing_motion_blur[]
177For a motion primitive or a motion instance, the positions for intersection
178are evaluated at the time specified in the code:time parameter to
179code:OpTraceRayMotionNV by interpolating between the two endpoints as
180specified for the given motion type.
181If a motion acceleration structure is traced with code:OpTraceRayKHR, it
182behaves as a code:OpTraceRayMotionNV with code:time of 0.0.
183endif::VK_NV_ray_tracing_motion_blur[]
184
185In the case of AABB geometries, implementations may: increase their size in
186an acceleration structure in order to mitigate precision issues.
187This may: result in false positive intersections being reported to the
188application.
189
190For triangle intersection candidates, the [eq]#b# and [eq]#c#
191<<primsrast-polygon-barycentrics,barycentric coordinates>> on the triangle
192where the above condition is met are made available to future shading.
193ifdef::VK_KHR_ray_tracing_pipeline[]
194If the ray was traced with code:OpTraceRayKHR, these values are available as
195a vector of 2 32-bit floating point values in the code:HitAttributeKHR
196storage class.
197endif::VK_KHR_ray_tracing_pipeline[]
198
199Once an intersection candidate is determined, it proceeds through the
200following operations, in order:
201
202    . <<ray-intersection-culling>>
203    . <<ray-intersection-confirmation>>
204    . <<ray-closest-hit-determination>>
205    . <<ray-result-determination>>
206
207The sections below describe the exact details of these tests.
208There is no ordering guarantee between operations performed on different
209intersection candidates.
210
211
212[[ray-traversal-watertight]]
213=== Watertightness
214
215For a set of triangles with identical transforms, within a single instance:
216
217  * Any set of two or more triangles where all triangles have one vertex
218    with an identical position value, that vertex is a _shared vertex_.
219  * Any set of two triangles with two shared vertices that were specified in
220    the same <<drawing-triangle-lists, winding order>> in each triangle have
221    a _shared edge_ defined by those vertices.
222
223A _closed fan_ is a set of three or more triangles where:
224
225 * All triangles in the set have the same shared vertex as one of their
226   vertices.
227 * All edges that include the above vertex are shared edges.
228 * All above shared edges are shared by exactly two triangles from the set.
229 * No two triangles in the set intersect, except at shared edges.
230 * Every triangle in the set is joined to every other triangle in the set by
231   a series of the above shared edges.
232
233Implementations should: not double-hit or miss when a ray intersects a
234shared edge, or a shared vertex of a closed fan.
235
236
237[[ray-intersection-culling]]
238== Ray Intersection Culling
239
240Candidate intersections go through several phases of culling before
241confirmation as an actual hit.
242There is no particular ordering dependency between the different culling
243operations.
244
245
246[[ray-traversal-culling-primitive]]
247=== Ray Primitive Culling
248
249If the <<features-rayTraversalPrimitiveCulling,
250pname:rayTraversalPrimitiveCulling>> or <<features-rayQuery,
251pname:rayQuery>> features are enabled, the code:SkipTrianglesKHR and
252code:SkipAABBsKHR ray flags can: be specified when tracing a ray.
253
254If code:SkipTrianglesKHR was included in the `Ray Flags` operand of the ray
255trace instruction, and the intersection is with a triangle primitive, the
256intersection is dropped, and no further processing of this intersection
257occurs.
258If ename:VK_PIPELINE_CREATE_RAY_TRACING_SKIP_TRIANGLES_BIT_KHR was included
259in the pipeline, traversal with code:OpTraceRayKHR calls will all behave as
260if code:SkipTrianglesKHR was included in its `Ray Flags` operand.
261
262If code:SkipAABBsKHR was included in the `Ray Flags` operand of the ray
263trace instruction, and the intersection is with an AABB primitive, the
264intersection is dropped, and no further processing of this intersection
265occurs.
266If ename:VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR was included in
267the pipeline, traversal with code:OpTraceRayKHR calls will all behave as if
268code:SkipAABBsKHR was included in its `Ray Flags` operand.
269
270
271=== Ray Mask Culling
272
273Instances can: be made invisible to particular rays based on the value of
274slink:VkAccelerationStructureInstanceKHR::pname:mask used to add that
275instance to a top-level acceleration structure, and the `Cull Mask`
276parameter used to trace the ray.
277
278For the instance which is intersected, if [eq]#pname:mask & `Cull Mask` ==
2790#, the intersection is dropped, and no further processing occurs.
280
281
282[[ray-traversal-culling-face]]
283=== Ray Face Culling
284
285As in <<primsrast-polygons-basic,polygon rasterization>>, one of the stages
286of ray traversal is to determine if a triangle primitive is back- or
287front-facing, and primitives can: be culled based on that facing.
288
289If the intersection candidate is with an AABB primitive, this operation is
290skipped.
291
292.Determination
293
294When a ray intersects a triangle primitive, the order that vertices are
295specified for the polygon affects whether the ray intersects the front or
296back face.
297Front or back facing is determined in the same way as they are for
298<<primsrast-polygons-basic,rasterization>>, based on the sign of the
299polygon's area but using the ray space coordinates instead of framebuffer
300coordinates.
301One way to compute this area is:
302
303[latexmath]
304++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
305a = -{1 \over 2}\sum_{i=0}^{n-1}
306      x_r^i y_r^{i \oplus 1} -
307      x_r^{i \oplus 1} y_r^i
308++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
309
310where latexmath:[x_r^i] and latexmath:[y_r^i] are the [eq]#x# and [eq]#y#
311<<ray-intersection-candidate-determination,ray space coordinates>> of the
312[eq]##i##th vertex of the [eq]#n#-vertex polygon (vertices are numbered
313starting at zero for the purposes of this computation) and [eq]#i {oplus} 1#
314is [eq]#(i {plus} 1) mod n#.
315
316By default, if [eq]#a# is negative then the intersection is with the front
317face of the triangle, otherwise it is with the back face.
318If ename:VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR is included in
319slink:VkAccelerationStructureInstanceKHR::pname:flags for the instance
320containing the intersected triangle, this determination is reversed.
321Additionally, if [eq]#a# is 0, the intersection candidate is treated as not
322intersecting with any face, irrespective of the sign.
323
324[NOTE]
325.Note
326====
327In a left-handed coordinate system, an intersection will be with the front
328face of a triangle if the vertices of the triangle, as defined in index
329order, appear from the ray's perspective in a clockwise rotation order.
330ename:VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR was previously
331annotated as
332ename:VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR because
333of this.
334====
335
336ifdef::VK_KHR_ray_tracing_pipeline[]
337If the ray was traced with code:OpTraceRayKHR, the code:HitKindKHR built-in
338is set to code:HitKindFrontFacingTriangleKHR if the intersection is with
339front-facing geometry, and code:HitKindBackFacingTriangleKHR if the
340intersection is with back-facing geometry, for shader stages considering
341this intersection.
342endif::VK_KHR_ray_tracing_pipeline[]
343
344ifdef::VK_KHR_ray_query[]
345If the ray was traced with code:OpRayQueryProceedKHR,
346code:OpRayQueryGetIntersectionFrontFaceKHR will return true for intersection
347candidates with front faces, or false for back faces.
348endif::VK_KHR_ray_query[]
349
350.Culling
351
352If code:CullBackFacingTrianglesKHR was included in the `Ray Flags` parameter
353of the ray trace instruction, and the intersection is determined as with the
354back face of a triangle primitive, the intersection is dropped, and no
355further processing of this intersection occurs.
356
357If code:CullFrontFacingTrianglesKHR was included in the `Ray Flags`
358parameter of the ray trace instruction, and the intersection is determined
359as with the front face of a triangle primitive, the intersection is dropped,
360and no further processing of this intersection occurs.
361
362This culling is disabled if
363ename:VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR was included
364in slink:VkAccelerationStructureInstanceKHR::pname:flags for the instance
365which the intersected geometry belongs to.
366
367Intersection candidates that have not intersected with any face ([eq]#a ==
3680#) are unconditionally culled, irrespective of ray flags and geometry
369instance flags.
370
371
372=== Ray Opacity Culling
373
374Each geometry in the acceleration structure may: be considered either opaque
375or not.
376Opaque geometries continue through traversal as normal, whereas non-opaque
377geometries need to be either confirmed or discarded by shader code.
378Intersection candidates can: also be culled based on their opacity.
379
380.Determination
381
382Each individual intersection candidate is initally determined as opaque if
383ename:VK_GEOMETRY_OPAQUE_BIT_KHR was included in the
384slink:VkAccelerationStructureGeometryKHR::pname:flags when the geometry it
385intersected with was built, otherwise it is considered non-opaque.
386
387ifdef::VK_KHR_ray_tracing_pipeline[]
388If the intersection candidate was generated by an <<shaders-intersection,
389intersection shader>>, the intersection is initially considered to have
390opacity matching the AABB candidate that it was generated from.
391endif::VK_KHR_ray_tracing_pipeline[]
392
393However, this opacity can be overridden when it is built into an instance.
394Setting ename:VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR in
395slink:VkAccelerationStructureInstanceKHR::pname:flags will force all
396geometries in the instance to be considered opaque.
397Similarly, setting ename:VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR will
398force all geometries in the instance to be considered non-opaque.
399
400This can again be overridden by including code:OpaqueKHR or code:NoOpaqueKHR
401in the `Ray Flags` parameter when tracing a ray.
402code:OpaqueKHR forces all geometries to behave as if they are opaque,
403regardless of their build parameters.
404Similarly, code:NoOpaqueKHR forces all geometries to behave as if they are
405non-opaque.
406
407ifdef::VK_KHR_ray_query[]
408If the ray was traced with code:OpRayQueryProceedKHR, to determine the
409opacity of AABB intersection candidates,
410code:OpRayQueryGetIntersectionCandidateAABBOpaqueKHR can: be used.
411This instruction will return code:true for opaque intersection candidates,
412and code:false for non-opaque intersection candidates.
413endif::VK_KHR_ray_query[]
414
415.Culling
416
417If code:CullOpaqueKHR is included in the `Ray Flags` parameter when tracing
418a ray, an intersection with a geometry that is considered opaque is dropped,
419and no further processing occurs.
420
421If code:CullNoOpaqueKHR is included in the `Ray Flags` parameter when
422tracing a ray, an intersection with a geometry that is considered non-opaque
423is dropped, and no further processing occurs.
424
425
426[[ray-intersection-confirmation]]
427== Ray Intersection Confirmation
428
429Depending on the opacity of intersected geometry and whether it is a
430triangle or an AABB, candidate intersections are further processed to
431determine the eventual hit result.
432Candidates generated from AABB intersections run through the same
433confirmation process as triangle hits.
434
435
436=== AABB Intersection Candidates
437
438For an intersection candidate with an AABB geometry generated by
439<<ray-intersection-candidate-determination>>, shader code is executed to
440determine whether any hits should be reported to the traversal
441infrastructure; no further processing of this intersection candidate occurs.
442The occurrence of an AABB intersection candidate does not guarantee the ray
443intersects the primitive bounds.
444To avoid propagating false intersections the application should: verify the
445intersection candidate before reporting any hits.
446
447ifdef::VK_KHR_ray_tracing_pipeline[]
448If the ray was traced with code:OpTraceRayKHR, an <<shaders-intersection,
449intersection shader>> is invoked from the <<shader-binding-table>> according
450to the <<shader-binding-table-indexing-rules, specified indexing>> for the
451intersected geometry.
452If this shader calls code:OpReportIntersectionKHR, a new intersection
453candidate is generated as described
454<<aabb-intersection-candidate-generation, below>>.
455If the intersection shader is ename:VK_SHADER_UNUSED_KHR (which is only
456allowed for a zero shader group) then no further processing of the
457intersection candidate occurs.
458endif::VK_KHR_ray_tracing_pipeline[]
459
460[[aabb-intersection-candidate-generation]]
461ifdef::VK_KHR_ray_tracing_pipeline[]
462Each new candidate generated as a result of this processing is a generated
463intersection candidate that intersects the AABB geometry, with a [eq]#t#
464value equal to the `Hit` parameter of the code:OpReportIntersectionKHR
465instruction.
466The new generated candidate is then independently run through
467<<ray-intersection-confirmation>> as a
468<<ray-triangle-and-generated-intersection-candidates, generated
469intersection>>.
470endif::VK_KHR_ray_tracing_pipeline[]
471
472ifdef::VK_KHR_ray_query[]
473If the ray was traced with code:OpRayQueryProceedKHR, control is returned to
474the shader which executed code:OpRayQueryProceedKHR, returning code:true.
475The resulting ray query has a candidate intersection type of
476code:RayQueryCandidateIntersectionAABBKHR.
477code:OpRayQueryGenerateIntersectionKHR can: be called to commit a new
478intersection candidate with committed intersection type of
479code:RayQueryCommittedIntersectionGeneratedKHR.
480Further ray query processing can: be continued by executing
481code:OpRayQueryProceedKHR with the same ray query, or intersection can: be
482terminated with code:OpRayQueryTerminateKHR.
483endif::VK_KHR_ray_query[]
484ifdef::VK_KHR_ray_tracing_pipeline+VK_KHR_ray_query[]
485Unlike rays traced with code:OpTraceRayKHR, candidates generated in this way
486skip generated intersection candidate confirmation; applications should:
487make this determination before generating the intersection.
488endif::VK_KHR_ray_tracing_pipeline+VK_KHR_ray_query[]
489
490This operation may: be executed multiple times for the same intersection
491candidate.
492
493
494[[ray-triangle-and-generated-intersection-candidates]]
495=== Triangle and Generated Intersection Candidates
496
497For triangle and <<aabb-intersection-candidate-generation, generated
498intersection candidates>>, additional shader code may: be executed based on
499the intersection's opacity.
500
501If the intersection is opaque, the candidate is immediately confirmed as a
502valid hit and passes to the next stage of processing.
503
504For non-opaque intersection candidates, shader code is executed to determine
505whether a hit occurred or not.
506
507ifdef::VK_KHR_ray_tracing_pipeline[]
508If the ray was traced with code:OpTraceRayKHR, an <<shaders-any-hit, any-hit
509shader>> is invoked from the <<shader-binding-table>> according to the
510specified indexing.
511If this shader calls code:OpIgnoreIntersectionKHR, the candidate is dropped
512and no further processing of the candidate occurs.
513If the <<shaders-any-hit, any-hit shader>> identified is
514ename:VK_SHADER_UNUSED_KHR, the candidate is immediately confirmed as a
515valid hit and passes to the next stage of processing.
516endif::VK_KHR_ray_tracing_pipeline[]
517
518ifdef::VK_KHR_ray_query[]
519If the ray was traced with code:OpRayQueryProceedKHR, control is returned to
520the shader which executed code:OpRayQueryProceedKHR, returning code:true.
521As only triangle candidates participate in this operation with ray queries,
522the resulting candidate intersection type is always
523code:RayQueryCandidateIntersectionTriangleKHR.
524code:OpRayQueryConfirmIntersectionKHR can: be called on the ray query to
525confirm the candidate as a hit with committed intersection type of
526code:RayQueryCommittedIntersectionTriangleKHR.
527Further ray query processing can: be continued by executing
528code:OpRayQueryProceedKHR with the same ray query, or intersection can: be
529terminated with code:OpRayQueryTerminateKHR.
530If code:OpRayQueryConfirmIntersectionKHR has not been executed, the
531candidate is dropped and no further processing of the candidate occurs.
532endif::VK_KHR_ray_query[]
533
534This operation may: be executed multiple times for the same intersection
535candidate unless ename:VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR
536was specified for the intersected geometry.
537
538
539[[ray-closest-hit-determination]]
540== Ray Closest Hit Determination
541
542Unless the ray was traced with the code:TerminateOnFirstHitKHR ray flag, the
543implementation must: track the closest confirmed hit until all geometries
544have been tested and either confirmed or dropped.
545
546After an intersection candidate is confirmed, its [eq]#t# value is compared
547to [eq]#t~max~# to determine which intersection is closer, where [eq]#t# is
548the parametric distance along the ray at which the intersection occurred.
549
550  * If [eq]#t < t~max~#, [eq]#t~max~# is set to [eq]#t# and the candidate is
551    set as the current closest hit.
552  * If [eq]#t > t~max~#, the candidate is dropped and no further processing
553    of that candidate occurs.
554  * If [eq]#t = t~max~#, the candidate may: be set as the current closest
555    hit or dropped.
556
557If code:TerminateOnFirstHitKHR was included in the `Ray Flags` used to trace
558the ray, once the first hit is confirmed, the ray trace is terminated.
559
560
561[[ray-result-determination]]
562== Ray Result Determination
563
564Once all candidates have finished processing the prior stages, or if the ray
565is forcibly terminated, the final result of the ray trace is determined.
566
567If a closest hit result was identified by <<ray-closest-hit-determination>>,
568a closest hit has occurred, otherwise the final result is a miss.
569
570ifdef::VK_KHR_ray_tracing_pipeline[]
571For rays traced with code:OpTraceRayKHR, if a closest hit result was
572identified, a <<shaders-closest-hit, closest hit shader>> is invoked from
573the <<shader-binding-table>> according to the
574<<shader-binding-table-indexing-rules, specified indexing>> for the
575intersected geometry.
576Control returns to the shader that executed code:OpTraceRayKHR once this
577shader returns.
578This shader is skipped if either the ray flags included
579code:SkipClosestHitShaderKHR, or if the <<shaders-closest-hit, closest hit
580shader>> identified is ename:VK_SHADER_UNUSED_KHR.
581
582For rays traced with code:OpTraceRayKHR where no hit result was identified,
583the <<shaders-miss, miss shader>> identified by the `Miss Index` parameter
584of code:OpTraceRayKHR is invoked.
585Control returns to the shader that executed code:OpTraceRayKHR once this
586shader returns.
587This shader is skipped if the miss shader identified is
588ename:VK_SHADER_UNUSED_KHR.
589endif::VK_KHR_ray_tracing_pipeline[]
590
591ifdef::VK_KHR_ray_query[]
592If the ray was traced with code:OpRayQueryProceedKHR, control is returned to
593the shader which executed code:OpRayQueryProceedKHR, returning code:false.
594If a closest hit was identified by <<ray-closest-hit-determination>>, the
595ray query will now have a committed intersection type of
596code:RayQueryCommittedIntersectionGeneratedKHR or
597code:RayQueryCommittedIntersectionTriangleKHR.
598If no closest hit was identified, the committed intersection type will be
599code:RayQueryCommittedIntersectionNoneKHR.
600
601No further processing of a ray query occurs after this result is determined.
602endif::VK_KHR_ray_query[]
603