• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2018-2023 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
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 code:OpTraceRayKHR, these values are available as
209a vector of 2 32-bit floating point values in the code:HitAttributeKHR
210storage 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 code:OpTraceRayKHR calls will all behave as
277if code:SkipTrianglesKHR was included in its `Ray Flags` operand.
278
279If code:SkipAABBsKHR was included in the `Ray Flags` operand of the ray
280trace instruction, and the intersection is with an AABB primitive, the
281intersection is dropped, and no further processing of this intersection
282occurs.
283If ename:VK_PIPELINE_CREATE_RAY_TRACING_SKIP_AABBS_BIT_KHR was included in
284the pipeline, traversal with code:OpTraceRayKHR calls will all behave as if
285code:SkipAABBsKHR was included in its `Ray Flags` operand.
286
287
288=== Ray Mask Culling
289
290Instances can: be made invisible to particular rays based on the value of
291slink:VkAccelerationStructureInstanceKHR::pname:mask used to add that
292instance to a top-level acceleration structure, and the `Cull Mask`
293parameter used to trace the ray.
294
295For the instance which is intersected, if [eq]#pname:mask & `Cull Mask` ==
2960#, the intersection is dropped, and no further processing occurs.
297
298
299[[ray-traversal-culling-face]]
300=== Ray Face Culling
301
302As in <<primsrast-polygons-basic,polygon rasterization>>, one of the stages
303of ray traversal is to determine if a triangle primitive is back- or
304front-facing, and primitives can: be culled based on that facing.
305
306If the intersection candidate is with an AABB primitive, this operation is
307skipped.
308
309.Determination
310
311When a ray intersects a triangle primitive, the order that vertices are
312specified for the polygon affects whether the ray intersects the front or
313back face.
314Front or back facing is determined in the same way as they are for
315<<primsrast-polygons-basic,rasterization>>, based on the sign of the
316polygon's area but using the ray space coordinates instead of framebuffer
317coordinates.
318One way to compute this area is:
319
320[latexmath]
321++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
322a = -{1 \over 2}\sum_{i=0}^{n-1}
323      x_r^i y_r^{i \oplus 1} -
324      x_r^{i \oplus 1} y_r^i
325++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
326
327where latexmath:[x_r^i] and latexmath:[y_r^i] are the [eq]#x# and [eq]#y#
328<<ray-intersection-candidate-determination,ray space coordinates>> of the
329[eq]##i##th vertex of the [eq]#n#-vertex polygon (vertices are numbered
330starting at zero for the purposes of this computation) and [eq]#i {oplus} 1#
331is [eq]#(i {plus} 1) mod n#.
332
333By default, if [eq]#a# is negative then the intersection is with the front
334face of the triangle, otherwise it is with the back face.
335If ename:VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR is included in
336slink:VkAccelerationStructureInstanceKHR::pname:flags for the instance
337containing the intersected triangle, this determination is reversed.
338Additionally, if [eq]#a# is 0, the intersection candidate is treated as not
339intersecting with any face, irrespective of the sign.
340
341[NOTE]
342.Note
343====
344In a left-handed coordinate system, an intersection will be with the front
345face of a triangle if the vertices of the triangle, as defined in index
346order, appear from the ray's perspective in a clockwise rotation order.
347ename:VK_GEOMETRY_INSTANCE_TRIANGLE_FLIP_FACING_BIT_KHR was previously
348annotated as
349ename:VK_GEOMETRY_INSTANCE_TRIANGLE_FRONT_COUNTERCLOCKWISE_BIT_KHR because
350of this.
351====
352
353ifdef::VK_KHR_ray_tracing_pipeline[]
354If the ray was traced with code:OpTraceRayKHR, the code:HitKindKHR built-in
355is set to code:HitKindFrontFacingTriangleKHR if the intersection is with
356front-facing geometry, and code:HitKindBackFacingTriangleKHR if the
357intersection is with back-facing geometry, for shader stages considering
358this intersection.
359endif::VK_KHR_ray_tracing_pipeline[]
360
361ifdef::VK_KHR_ray_query[]
362If the ray was traced with code:OpRayQueryProceedKHR,
363code:OpRayQueryGetIntersectionFrontFaceKHR will return true for intersection
364candidates with front faces, or false for back faces.
365endif::VK_KHR_ray_query[]
366
367.Culling
368
369If code:CullBackFacingTrianglesKHR was included in the `Ray Flags` parameter
370of the ray trace instruction, and the intersection is determined as with the
371back face of a triangle primitive, the intersection is dropped, and no
372further processing of this intersection occurs.
373
374If code:CullFrontFacingTrianglesKHR was included in the `Ray Flags`
375parameter of the ray trace instruction, and the intersection is determined
376as with the front face of a triangle primitive, the intersection is dropped,
377and no further processing of this intersection occurs.
378
379This culling is disabled if
380ename:VK_GEOMETRY_INSTANCE_TRIANGLE_FACING_CULL_DISABLE_BIT_KHR was included
381in slink:VkAccelerationStructureInstanceKHR::pname:flags for the instance
382which the intersected geometry belongs to.
383
384Intersection candidates that have not intersected with any face ([eq]#a ==
3850#) are unconditionally culled, irrespective of ray flags and geometry
386instance flags.
387
388The code:CullBackFacingTrianglesKHR and code:CullFrontFacingTrianglesKHR
389`Ray Flags` are mutually exclusive.
390
391
392=== Ray Opacity Culling
393
394Each geometry in the acceleration structure may: be considered either opaque
395or not.
396Opaque geometries continue through traversal as normal, whereas non-opaque
397geometries need to be either confirmed or discarded by shader code.
398Intersection candidates can: also be culled based on their opacity.
399
400.Determination
401
402Each individual intersection candidate is initially determined as opaque if
403ename:VK_GEOMETRY_OPAQUE_BIT_KHR was included in the
404slink:VkAccelerationStructureGeometryKHR::pname:flags when the geometry it
405intersected with was built, otherwise it is considered non-opaque.
406
407ifdef::VK_EXT_opacity_micromap[]
408If the geometry includes an opacity micromap, the opacity of the
409intersection at this point is instead derived as described in
410<<ray-opacity-micromap,Ray Opacity Micromap>>.
411endif::VK_EXT_opacity_micromap[]
412
413ifdef::VK_KHR_ray_tracing_pipeline[]
414If the intersection candidate was generated by an <<shaders-intersection,
415intersection shader>>, the intersection is initially considered to have
416opacity matching the AABB candidate that it was generated from.
417endif::VK_KHR_ray_tracing_pipeline[]
418
419However, this opacity can be overridden when it is built into an instance.
420Setting ename:VK_GEOMETRY_INSTANCE_FORCE_OPAQUE_BIT_KHR in
421slink:VkAccelerationStructureInstanceKHR::pname:flags will force all
422geometries in the instance to be considered opaque.
423Similarly, setting ename:VK_GEOMETRY_INSTANCE_FORCE_NO_OPAQUE_BIT_KHR will
424force all geometries in the instance to be considered non-opaque.
425
426This can again be overridden by including code:OpaqueKHR or code:NoOpaqueKHR
427in the `Ray Flags` parameter when tracing a ray.
428code:OpaqueKHR forces all geometries to behave as if they are opaque,
429regardless of their build parameters.
430Similarly, code:NoOpaqueKHR forces all geometries to behave as if they are
431non-opaque.
432
433ifdef::VK_KHR_ray_query[]
434If the ray was traced with code:OpRayQueryProceedKHR, to determine the
435opacity of AABB intersection candidates,
436code:OpRayQueryGetIntersectionCandidateAABBOpaqueKHR can: be used.
437This instruction will return code:true for opaque intersection candidates,
438and code:false for non-opaque intersection candidates.
439endif::VK_KHR_ray_query[]
440
441.Culling
442
443If code:CullOpaqueKHR is included in the `Ray Flags` parameter when tracing
444a ray, an intersection with a geometry that is considered opaque is dropped,
445and no further processing occurs.
446
447If code:CullNoOpaqueKHR is included in the `Ray Flags` parameter when
448tracing a ray, an intersection with a geometry that is considered non-opaque
449is dropped, and no further processing occurs.
450
451The code:OpaqueKHR, code:NoOpaqueKHR, code:CullOpaqueKHR, and
452code:CullNoOpaqueKHR `Ray Flags` are mutually exclusive.
453
454ifdef::VK_EXT_opacity_micromap[]
455[[ray-opacity-micromap]]
456=== Ray Opacity Micromap
457
458A ename:VK_GEOMETRY_TYPE_TRIANGLES_KHR geometry in the acceleration
459structure may: have an opacity micromap associated with it to give
460finer-grained opacity information.
461
462If the intersection candidate is with a geometry with an associated opacity
463micromap and ename:VK_GEOMETRY_INSTANCE_DISABLE_OPACITY_MICROMAPS_EXT is not
464set in its instance then the micromap is used to determine geometry opacity
465instead of the ename:VK_GEOMETRY_OPAQUE_BIT_KHR flag in the geometry.
466
467The opacity information in the micromap object is accessed using the
468candidate intersection [eq]#u# and [eq]#v# coordinates.
469The integer [eq]#u# and [eq]#v# are computed from [eq]#{lfloor}u{rfloor}
470{plus} {lfloor}v{rfloor}#, clamping [eq]#{lfloor}u{rfloor}# as needed to
471keep the sum less than or equal to [eq]#1 << subdivisionlevel#.
472These values are mapped into a linear index with a space filling curve which
473is defined recursively by traversing into the sub-triangle nearest vertex 0,
474then the middle triangle with ordering flipped, then nearest vertex 1 then
475nearest vertex 2.
476
477image::{images}/micromap-subd.svg[align="center",title="Example ordering for micromap data",align="center",opts="{imageopts}"]
478
479[NOTE]
480.Note
481====
482This encoding is spatially coherent, purely hierarchical, and allows a
483bit-parallel conversion between barycentric address and index values.
484
485See the appendix for reference code implementing this mapping.
486====
487
488The result of the opacity micromap lookup and operations is to treat the
489intersection as opaque, non-opaque, or ignored.
490The interpretation of the values depends on
491ename:VK_GEOMETRY_INSTANCE_FORCE_OPACITY_MICROMAP_2_STATE_EXT in the
492instance of the candidate intersection or
493ename:ForceOpacityMicromap2StateEXT ray flags on the ray.
494If either is set, the opacity micromap information is interpreted in 2 state
495override mode.
496If the result of the micromap lookup is to treat the intersection candidate
497as ignored, no further processing of that candidate is done.
498
499If the associated opacity micromap has format
500ename:VK_OPACITY_MICROMAP_FORMAT_2_STATE_EXT, each element of the micromap
501is represented by a single bit at the index derived above.
502
503If the associated opacity micromap has format
504ename:VK_OPACITY_MICROMAP_FORMAT_4_STATE_EXT, each element is represented by
505a two bit value at the index derived above.
506
507
508[options="header"]
509|====
510| 4 State value | 2 State value | Special index value | 2 State override | Result
511| 0 | 0 | ename:VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_TRANSPARENT_EXT         | Y | Ignored
512| 0 | 0 | ename:VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_TRANSPARENT_EXT         | N | Ignored
513| 1 | 1 | ename:VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_OPAQUE_EXT              | Y | Opaque
514| 1 | 1 | ename:VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_OPAQUE_EXT              | N | Opaque
515| 2 |   | ename:VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_TRANSPARENT_EXT | Y | Ignored
516| 2 |   | ename:VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_TRANSPARENT_EXT | N | Non-opaque
517| 3 |   | ename:VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_OPAQUE_EXT      | Y | Opaque
518| 3 |   | ename:VK_OPACITY_MICROMAP_SPECIAL_INDEX_FULLY_UNKNOWN_OPAQUE_EXT      | N | Non-opaque
519|====
520
521
522endif::VK_EXT_opacity_micromap[]
523
524
525[[ray-intersection-confirmation]]
526== Ray Intersection Confirmation
527
528Depending on the opacity of intersected geometry and whether it is a
529triangle or an AABB, candidate intersections are further processed to
530determine the eventual hit result.
531Candidates generated from AABB intersections run through the same
532confirmation process as triangle hits.
533
534
535=== AABB Intersection Candidates
536
537For an intersection candidate with an AABB geometry generated by
538<<ray-intersection-candidate-determination>>, shader code is executed to
539determine whether any hits should be reported to the traversal
540infrastructure; no further processing of this intersection candidate occurs.
541The occurrence of an AABB intersection candidate does not guarantee the ray
542intersects the primitive bounds.
543To avoid propagating false intersections the application should: verify the
544intersection candidate before reporting any hits.
545
546ifdef::VK_KHR_ray_tracing_pipeline[]
547If the ray was traced with code:OpTraceRayKHR, an <<shaders-intersection,
548intersection shader>> is invoked from the <<shader-binding-table>> according
549to the <<shader-binding-table-indexing-rules, specified indexing>> for the
550intersected geometry.
551If this shader calls code:OpReportIntersectionKHR, a new intersection
552candidate is generated as described
553<<aabb-intersection-candidate-generation, below>>.
554If the intersection shader is ename:VK_SHADER_UNUSED_KHR (which is only
555allowed for a zero shader group) then no further processing of the
556intersection candidate occurs.
557endif::VK_KHR_ray_tracing_pipeline[]
558
559[[aabb-intersection-candidate-generation]]
560ifdef::VK_KHR_ray_tracing_pipeline[]
561Each new candidate generated as a result of this processing is a generated
562intersection candidate that intersects the AABB geometry, with a [eq]#t#
563value equal to the `Hit` parameter of the code:OpReportIntersectionKHR
564instruction.
565The new generated candidate is then independently run through
566<<ray-intersection-confirmation>> as a
567<<ray-triangle-and-generated-intersection-candidates, generated
568intersection>>.
569endif::VK_KHR_ray_tracing_pipeline[]
570
571ifdef::VK_KHR_ray_query[]
572If the ray was traced with code:OpRayQueryProceedKHR, control is returned to
573the shader which executed code:OpRayQueryProceedKHR, returning code:true.
574The resulting ray query has a candidate intersection type of
575code:RayQueryCandidateIntersectionAABBKHR.
576code:OpRayQueryGenerateIntersectionKHR can: be called to commit a new
577intersection candidate with committed intersection type of
578code:RayQueryCommittedIntersectionGeneratedKHR.
579Further ray query processing can: be continued by executing
580code:OpRayQueryProceedKHR with the same ray query, or intersection can: be
581terminated with code:OpRayQueryTerminateKHR.
582endif::VK_KHR_ray_query[]
583ifdef::VK_KHR_ray_tracing_pipeline+VK_KHR_ray_query[]
584Unlike rays traced with code:OpTraceRayKHR, candidates generated in this way
585skip generated intersection candidate confirmation; applications should:
586make this determination before generating the intersection.
587endif::VK_KHR_ray_tracing_pipeline+VK_KHR_ray_query[]
588
589This operation may: be executed multiple times for the same intersection
590candidate.
591
592
593[[ray-triangle-and-generated-intersection-candidates]]
594=== Triangle and Generated Intersection Candidates
595
596For triangle and <<aabb-intersection-candidate-generation, generated
597intersection candidates>>, additional shader code may: be executed based on
598the intersection's opacity.
599
600If the intersection is opaque, the candidate is immediately confirmed as a
601valid hit and passes to the next stage of processing.
602
603For non-opaque intersection candidates, shader code is executed to determine
604whether a hit occurred or not.
605
606ifdef::VK_KHR_ray_tracing_pipeline[]
607If the ray was traced with code:OpTraceRayKHR, an <<shaders-any-hit, any-hit
608shader>> is invoked from the <<shader-binding-table>> according to the
609specified indexing.
610If this shader calls code:OpIgnoreIntersectionKHR, the candidate is dropped
611and no further processing of the candidate occurs.
612If the <<shaders-any-hit, any-hit shader>> identified is
613ename:VK_SHADER_UNUSED_KHR, the candidate is immediately confirmed as a
614valid hit and passes to the next stage of processing.
615endif::VK_KHR_ray_tracing_pipeline[]
616
617ifdef::VK_KHR_ray_query[]
618If the ray was traced with code:OpRayQueryProceedKHR, control is returned to
619the shader which executed code:OpRayQueryProceedKHR, returning code:true.
620As only triangle candidates participate in this operation with ray queries,
621the resulting candidate intersection type is always
622code:RayQueryCandidateIntersectionTriangleKHR.
623code:OpRayQueryConfirmIntersectionKHR can: be called on the ray query to
624confirm the candidate as a hit with committed intersection type of
625code:RayQueryCommittedIntersectionTriangleKHR.
626Further ray query processing can: be continued by executing
627code:OpRayQueryProceedKHR with the same ray query, or intersection can: be
628terminated with code:OpRayQueryTerminateKHR.
629If code:OpRayQueryConfirmIntersectionKHR has not been executed, the
630candidate is dropped and no further processing of the candidate occurs.
631endif::VK_KHR_ray_query[]
632
633This operation may: be executed multiple times for the same intersection
634candidate unless ename:VK_GEOMETRY_NO_DUPLICATE_ANY_HIT_INVOCATION_BIT_KHR
635was specified for the intersected geometry.
636
637
638[[ray-closest-hit-determination]]
639== Ray Closest Hit Determination
640
641Unless the ray was traced with the code:TerminateOnFirstHitKHR ray flag, the
642implementation must: track the closest confirmed hit until all geometries
643have been tested and either confirmed or dropped.
644
645After an intersection candidate is confirmed, its [eq]#t# value is compared
646to [eq]#t~max~# to determine which intersection is closer, where [eq]#t# is
647the parametric distance along the ray at which the intersection occurred.
648
649  * If [eq]#t < t~max~#, [eq]#t~max~# is set to [eq]#t# and the candidate is
650    set as the current closest hit.
651  * If [eq]#t > t~max~#, the candidate is dropped and no further processing
652    of that candidate occurs.
653  * If [eq]#t = t~max~#, the candidate may: be set as the current closest
654    hit or dropped.
655
656If code:TerminateOnFirstHitKHR was included in the `Ray Flags` used to trace
657the ray, once the first hit is confirmed, the ray trace is terminated.
658
659
660[[ray-result-determination]]
661== Ray Result Determination
662
663Once all candidates have finished processing the prior stages, or if the ray
664is forcibly terminated, the final result of the ray trace is determined.
665
666If a closest hit result was identified by <<ray-closest-hit-determination>>,
667a closest hit has occurred, otherwise the final result is a miss.
668
669ifdef::VK_KHR_ray_tracing_pipeline[]
670For rays traced with code:OpTraceRayKHR, if a closest hit result was
671identified, a <<shaders-closest-hit, closest hit shader>> is invoked from
672the <<shader-binding-table>> according to the
673<<shader-binding-table-indexing-rules, specified indexing>> for the
674intersected geometry.
675Control returns to the shader that executed code:OpTraceRayKHR once this
676shader returns.
677This shader is skipped if either the ray flags included
678code:SkipClosestHitShaderKHR, or if the <<shaders-closest-hit, closest hit
679shader>> identified is ename:VK_SHADER_UNUSED_KHR.
680
681For rays traced with code:OpTraceRayKHR where no hit result was identified,
682the <<shaders-miss, miss shader>> identified by the `Miss Index` parameter
683of code:OpTraceRayKHR is invoked.
684Control returns to the shader that executed code:OpTraceRayKHR once this
685shader returns.
686This shader is skipped if the miss shader identified is
687ename:VK_SHADER_UNUSED_KHR.
688endif::VK_KHR_ray_tracing_pipeline[]
689
690ifdef::VK_KHR_ray_query[]
691If the ray was traced with code:OpRayQueryProceedKHR, control is returned to
692the shader which executed code:OpRayQueryProceedKHR, returning code:false.
693If a closest hit was identified by <<ray-closest-hit-determination>>, the
694ray query will now have a committed intersection type of
695code:RayQueryCommittedIntersectionGeneratedKHR or
696code:RayQueryCommittedIntersectionTriangleKHR.
697If no closest hit was identified, the committed intersection type will be
698code:RayQueryCommittedIntersectionNoneKHR.
699
700No further processing of a ray query occurs after this result is determined.
701endif::VK_KHR_ray_query[]
702