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