Name NV_ray_tracing Name Strings GL_NV_ray_tracing Contact Eric Werness (ewerness 'at' nvidia.com), NVIDIA Ashwin Lele (alele 'at' nvidia.com), NVIDIA Contributors Christoph Kubisch, NVIDIA Nuno Subtil, NVIDIA Ignacio Llamas, NVIDIA Martin Stich, NVIDIA Steven Parker, NVIDIA Robert Stepinski, NVIDIA Daniel Koch, NVIDIA Status Shipping Version Last Modified Date: 2020-12-16 Revision: 9 Dependencies This extension can be applied to OpenGL GLSL versions 4.60 (#version 460) and higher. This extension is written against revision 5 of the OpenGL Shading Language version 4.60, dated September 4, 2017. This extension interacts with revision 43 of the GL_KHR_vulkan_glsl extension, dated October 25, 2017. This extension interacts with GL_KHR_shader_subgroup. This extension interacts with GL_NV_shader_subgroup_partitioned. This extension interacts with GL_ARB_shader_ballot. This extension interacts with GL_ARB_shader_group_vote. This extension interacts with GL_ARB_shader_clock. This extension interacts with GL_EXT_shader_realtime_clock. This extension interacts with GL_NV_shader_sm_builtins. Overview This extension document modifies GLSL to add new shader stages to support ray tracing. They are namely ray generation, intersection, any hit, closest hit, miss stages and callable collectively referred as ray tracing stages. This extension document adds support for the following extensions to be used within GLSL: - GL_NV_ray_tracing - enables ray tracing stages. Mapping to SPIR-V ----------------- For informational purposes (non-normative), the following is an expected way for an implementation to map GLSL constructs to SPIR-V constructs: ray generation shader -> RayGenerationNV Execution model intersection shader -> IntersectionNV Execution model any-hit shader -> AnyHitNV Execution model closest-hit shader -> ClosestHitNV Execution model miss shader -> MissNV Execution model callable shader -> CallableNV Execution model accelerationStructureNV type -> OpTypeAccelerationStructureNV instruction rayPayloadNV storage qualifier -> RayPayloadNV storage class rayPayloadInNV storage qualifier -> IncomingRayPayloadNV storage class hitAttributeNV storage qualifier -> HitAttributeNV storage class callableDataNV storage qualifier -> CallableDataNV storage class callableDataInNV storage qualifier -> IncomingCallableDataNV storage class shaderRecordNV decorated buffer block -> ShaderRecordBufferNV storage class gl_LaunchIDNV -> LaunchIdNV decorated OpVariable gl_LaunchSizeNV -> LaunchSizeNV decorated OpVariable gl_PrimitiveID -> PrimitiveId decorated OpVariable gl_InstanceID -> InstanceId decorated OpVariable gl_InstanceCustomIndexNV -> InstanceCustomIndexNV decorated OpVariable gl_WorldRayOriginNV -> WorldRayOriginNV decorated OpVariable gl_WorldRayDirectionNV -> WorldRayDirectionNV decorated OpVariable gl_ObjectRayOriginNV -> ObjectRayOriginNV decorated OpVariable gl_ObjectRayDirectionNV -> ObjectRayDirectionNV decorated OpVariable gl_RayTminNV -> RayTminNV decorated OpVariable gl_RayTmaxNV -> RayTmaxNV decorated OpVariable gl_IncomingRayFlagsNV -> IncomingRayFlagsNV decorated OpVariable gl_HitTNV -> HitTNV decorated OpVariable gl_HitKindNV -> HitKindNV decorated OpVariable gl_ObjectToWorldNV -> ObjectToWorldNV decorated OpVariable gl_WorldToObjectNV -> WorldToObjectNV decorated OpVariable gl_RayFlagsNoneNV -> constant, no semantic needed gl_RayFlagsOpaqueNV -> constant, no semantic needed gl_RayFlagsNoOpaqueNV -> constant, no semantic needed gl_RayFlagsTerminateOnFirstHitNV -> constant, no semantic needed gl_RayFlagsSkipClosestHitShaderNV -> constant, no semantic needed gl_RayFlagsCullBackFacingTrianglesNV -> constant, no semantic needed gl_RayFlagsCullFrontFacingTrianglesNV -> constant, no semantic needed gl_RayFlagsCullOpaqueNV -> constant, no semantic needed gl_RayFlagsCullNoOpaqueNV -> constant, no semantic needed traceNV -> OpTraceNV instruction reportIntersectionNV -> OpReportIntersectionNV instruction ignoreIntersectionNV -> OpIgnoreIntersectionNV instruction terminateRayNV -> OpTerminateRayNV instruction executeCallableNV -> OpExecuteCallableNV instruction Modifications to the OpenGL Shading Language Specification, Version 4.60 Including the following line in a shader can be used to control the language features described in this extension: #extension GL_NV_ray_tracing : where is as specified in section 3.3. New preprocessor #defines are added: #define GL_NV_ray_tracing 1 Additions to Chapter 2 of the OpenGL Shading Language Specification (Overview of OpenGL Shading) Add Section 2.7, Ray Generation Processor The is a programmable unit that operates on an incoming ray and its associated data. It runs independently from other graphics and compute processors. Compilation units written in the OpenGL Shading Language to run on this processor are called . When a set of ray generation shaders are successfully compiled and linked, they result in a that runs on the ray generation processor. The ray generation processor is similar to the compute processor. It is used to execute ray tracing queries using traceNV() calls and process the results. It can pass data to other ray tracing stages through the ray payload. Add Section 2.8, Intersection Processor The is a programmable unit that evaluates ray-primitive intersections and reports the results to other programmable units. It runs independently from other graphics and compute processors. Compilation units written in the OpenGL Shading Language to run on this processor are called . When a set of intersection shaders are successfully compiled and linked, they result in an that runs on the intersection processor. The intersection processor will use an implementation-specific built-in intersection shader if the ray query is operating on a triangle primitive. Otherwise, an application defined intersection shader is used if the ray query is operating on an axis-aligned bounding box. See the Ray Tracing chapter of the Vulkan specification for more information. The intersection processor operates on a single primitive at a time. The intersection processor can generate data that can be read by any-hit hit and closest-hit processors. The intersection processor cannot read or modify the ray payload. Add Section 2.9, Any-Hit Processor The is a programmable unit that operates on rays that have had intersections reported and evaluates whether the intersection should be accepted. It runs independently from other graphics and compute processors. Compilation units written in the OpenGL Shading Language to run on this processor are called . When a set of any-hit shaders are successfully compiled and linked, they result in an that runs on the any-hit processor. The order in which intersections are found along a ray, and therefore the order in which the any-hit processor is executed, is unspecified. The any-hit shader or the closest-hit must to be invoked at some point during traversal, unless the ray is forcibly terminated. Any-hit shaders have read-only access to the data generated by the intersection processor. They may read and modify the ray payload. The application may specify flags to avoid executing any-hit shaders for certain instances, primitives or rays in order to improve performance. Add Section 2.10, Closest-Hit Processor The is a programmable unit that operates on rays that have had intersections reported. It runs independently from other graphics and compute processors. Compilation units written in the OpenGL Shading Language to run on this processor are called . When a set of closest-hit shaders are successfully compiled and linked, they result in a that runs on the closest-hit processor. The closest-hit processor is executed at most one time when traversal is finished and an intersection has accepted. Closest hit shaders have read-only access to the data generated by the intersection processor. They may read and modify the ray payload. They can also recursively generate a new ray query through a call to traceNV(). Add Section 2.11, Miss Processor The is a programmable unit that operates on rays that have not had any intersections reported by other programmable units. It runs independently from other graphics and compute processors. Compilation units written in the OpenGL Shading Language to run on this processor are called . When a set of miss shaders are successfully compiled and linked, they result in a that runs on the miss processor. The miss processor is invoked instead of the closest-hit processor if no intersection is reported during traversal. Miss shaders can access the ray payload and can trace new rays through a call to traceNV(), but cannot access data generated by the intersection processor. Add Section 2.12, Callable Processor The is a programmable unit that operates on arbitrary data associated with a ray and invoked from other programmable units in the ray tracing pipeline. It is similar in concept to an indirect function call mechanism. It runs independently from other graphics and compute processors. Compilation units written in the OpenGL Shading Language to run on this processor are called . The callable processor can be invoked from a ray-generation, closest-hit, miss or another callable shader stage. They can only access data passed in to the callable from parent stage. They can be invoked by indexing into the shader binding table. Refer to Ray Tracing chapter of the Vulkan specification for further details. Changes to Chapter 3 of The OpenGL Shading Language Specification, Version 4.60 Modify Section 3.6, (Keywords) (add the following to the list of reserved keywords) accelerationStructureNV rayPayloadNV rayPayloadInNV hitAttributeNV callableDataNV callableDataInNV Changes to Chapter 4 of The OpenGL Shading Language Specification, Version 4.60 Add following to Section 4.1 (Basic Types) Ray Tracing Opaque Types Types Meaning ----- ------- accelerationStructureNV A handle representing acceleration structure used for calculating intersection of rays with geometry. Used only in a traceNV call. Add a new sub-section under Section 4.1.7 (Opaque Types) 4.1.7.x Acceleration Structure Types accelerationStructureNV is an opaque type representing a structure used during ray tracing to accelerate queries of intersections of rays with scene geometry. It is declared and behaves like above described opaque types. When aggregated into arrays within a shader, accelerationStructureNV can only be indexed with a dynamically uniform integral expression, otherwise results are undefined. This type is used in traceNV builtin described in Section 8.19 Members of structure cannot be declared with this type. Modify Section 4.3 (Storage Qualifiers) Storage Qualifier Meaning ----------------- ------- rayPayloadNV Ray generation, any-hit, closest-hit, and miss shader only. Storage associated with a ray can which can be written/read by downstream stages rayPayloadInNV Closest-hit, any-hit and miss shader only. Storage associated with ray sent to traceNV during invocation of parent ray generation shader/closest-hit shaders. hitAttributeNV Intersection, any-hit, and closest-hit shader only. Storage associated with attributes of geometry intersected by a ray. callableDataNV Ray generation, closest-hit, miss and callable shader only. Storage associated with data to be passed on as input to the callable. Can be written/read by downstream callable stage callableDataInNV Callable shader only. Storage associated with data passed into callable stage from invoking parent stage. Add a sub-section to Section 4.3 (Storage Qualifiers) 4.3.X rayPayloadNV Variables These are allowed only in ray generation, any-hit, closest-hit, and miss shaders only. It is a compile time error to use them in any other stage. They can be both read and written to in ray generation, any-hit, closest-hit, and miss shaders. They cannot have any other storage qualifiers. It is a compile-time error to declare unsized arrays of this type. 4.3.X hitAttributeNV Variables These are allowed only in intersection, any-hit, and closest-hit shaders. It is a compile-time error to use them in any other stage. They can be read in any-hit, and closest-hit shaders. They can be written to only in intersection shaders. There can be only a single variable at global scope with this qualifier in stages where this qualifier is permitted. If multiple variables are present, the results of reportIntersectionNV() are undefined. They cannot have any other storage qualifiers. It is a compile-time error to declare unsized arrays of this type. For the case of triangle geometry with no custom intersection shaders, any-hit and closest-hit shaders can access barycentric weights of the point of intersection of ray with triangle by declaring a hitAttributeNV variable of two 32-bit floating point elements For example, (either of) hitAttributeNV vec2 baryCoord; hitAttributeNV block { vec2 baryCoord; } hitAttributeNV float baryCoord[2]; 4.3.X rayPayloadInNV Variables These are allowed only in any-hit, closest-hit, and miss shaders only. It is a compile-time error to use them in any other stage. They can be read to and written in any-hit, closest-hit, and miss shaders There can be only a single variable at global scope with this qualifier in stages where this qualifier is permitted. If multiple variables are present results of accessing these variables are undefined. It is a compile-time error to declare unsized arrays of this type. The type of this variable must match the type of rayPayloadNV as passed by the upstream shader, otherwise the results are undefined. 4.3.X callableDataNV Variables These are allowed only in ray generation, closest-hit, miss and callable shaders only. It is a compile-time error to use them in any other stage. They can be both read and written to in supported stages. They cannot have any other storage qualifiers. It is a compile-time error to declare unsized arrays of this type. 4.3.X callableDataInNV Variables These are allowed only in callable shaders. It is a compile-time error to use them in any other stage. They can be both read and written to in callable shaders. They cannot have any other storage qualifiers. There can be only a single variable at global scope with this qualifier. If multiple variables are present, result of accessing these variables is undefined. It is a compile-time error to declare unsized arrays of this type. The type of this variable must match the type of callableDataNV as passed by the parent shader invoking this callable, otherwise the results are undefined. Add following to Section 4.3.4 (Input Variables) Ray tracing stages do not permit user defined input variables. They support some built-in inputs as described in Section 7. All other inputs are retrieved explicitly from image loads, texture fetches, loads from uniform or storage buffers, or other user supplied code. It is illegal to redeclare these built-in input variables. Add following to Section 4.3.6 (Output Variables) Ray tracing stages do not have any built-in outputs nor permit any user defined output variables. Add following to Section 4.3.8 (Shared Variables) Ray tracing stages do not permit declaring variables with 'shared' storage qualifier. Add the following to Section 4.3.9 (Interface Blocks) "Input, output, uniform, *rayPayloadNV, *rayPayloadInNV*, *hitAttributeNV*, *callableDataNV*, *callableDataInNV* and buffer variable declarations can be grouped into named interface blocks..." "It is compile time error to use input, output or patch interface qualifier for blocks in ray tracing shader stages" Modify table in Section 4.4 (Layout Qualifiers) Layout Qualifier Qualifier Individual Block Block Allowed Only Variable Member Interface ---------------- --------- ---------- ------ ------ --------- location X X rayPayloadNV rayPayloadInNV callableDataNV callableDataInNV shaderRecordNV X buffer Add new sub-section to Section 4.4 4.4.X rayPayloadNV Layout Qualifiers The layout qualifiers are : layout-qualifier-id : location = integer-constant-expression Non-block variables declared with these qualifiers must have a valid location layout qualifier. For interface blocks, only top level block declaration can have valid location layout qualifier. It is illegal to have layout qualifier on members of the block. 4.4.X rayPayloadInNV Layout Qualifiers The layout qualifiers are : layout-qualifier-id : location = integer-constant-expression Non-block variables declared with these qualifiers must have a valid location layout qualifier. For interface blocks, only top level block declaration can have valid location layout qualifier. It is illegal to have layout qualifier on members of the block. 4.4.X hitAttributeNV Layout Qualifiers No layout qualifiers are allowed on variables of this type. 4.4.X callableDataNV Layout Qualifiers The layout qualifiers are : layout-qualifier-id : location = integer-constant-expression Non-block variables declared with these qualifiers must have a valid location layout qualifier. For interface blocks, only top level block declaration can have valid location layout qualifier. It is illegal to have layout qualifier on members of the block. 4.4.X callableDataInNV Layout Qualifiers The layout qualifiers are : layout-qualifier-id : location = integer-constant-expression Non-block variables declared with these qualifiers must have a valid location layout qualifier. For interface blocks, only top level block declaration can have valid location layout qualifier. It is illegal to have layout qualifier on members of the block. Add to end of section 4.4.5, Uniform and Shader Storage Block Layout Qualifiers The "shaderRecordNV" qualifier is used to declare a buffer block and represents a buffer within a shader record as defined in the API in Ray Tracing chapter of the Vulkan specification. It is supported only in ray tracing stages. It is a compile-time error to apply this to any block type other than buffer. A buffer block declared with layout(shaderRecordNV) can be optionally declared with an instance. There can be only one shaderRecordNV buffer block per stage otherwise a link/compile time error will be generated. It is a compile time error to use layout qualifiers such as binding and set along with shaderRecordNV. These blocks can only be read from and not written to. It is a compile-time error to modify members of such blocks. These blocks are initialized by a separate API as specified in Ray Tracing chapter of the Vulkan specification. Additions to Chapter 7 of the OpenGL Shading Language Specification (Built-in Variables) Modify Section 7.1, Built-in Languages Variables In the ray generation shading language, built-in variables are declared as follows // Work dimensions in uvec3 gl_LaunchIDNV; in uvec3 gl_LaunchSizeNV; In the any-hit and closest-hit shading languages, built-in variables are declared as follows // Work dimensions in uvec3 gl_LaunchIDNV; in uvec3 gl_LaunchSizeNV; // Geometry instance ids in int gl_PrimitiveID; in int gl_InstanceID; in int gl_InstanceCustomIndexNV; // World space parameters in vec3 gl_WorldRayOriginNV; in vec3 gl_WorldRayDirectionNV; in vec3 gl_ObjectRayOriginNV; in vec3 gl_ObjectRayDirectionNV; // Ray parameters in float gl_RayTminNV; in float gl_RayTmaxNV; in uint gl_IncomingRayFlagsNV; // Ray hit info in float gl_HitTNV; in uint gl_HitKindNV; // Transform matrices in mat4x3 gl_ObjectToWorldNV; in mat4x3 gl_WorldToObjectNV; In the intersection language, built-in variables are declared as follows // Work dimensions in uvec3 gl_LaunchIDNV; in uvec3 gl_LaunchSizeNV; // Geometry instance ids in int gl_PrimitiveID; in int gl_InstanceID; in int gl_InstanceCustomIndexNV; // World space parameters in vec3 gl_WorldRayOriginNV; in vec3 gl_WorldRayDirectionNV; in vec3 gl_ObjectRayOriginNV; in vec3 gl_ObjectRayDirectionNV; // Ray parameters in float gl_RayTminNV; in float gl_RayTmaxNV; in uint gl_IncomingRayFlagsNV; // Transform matrices in mat4x3 gl_ObjectToWorldNV; in mat4x3 gl_WorldToObjectNV; In the miss shading language, built-in variables are declared as follows // Work dimensions in uvec3 gl_LaunchIDNV; in uvec3 gl_LaunchSizeNV; // World space parameters in vec3 gl_WorldRayOriginNV; in vec3 gl_WorldRayDirectionNV; in vec3 gl_ObjectRayOriginNV; in vec3 gl_ObjectRayDirectionNV; // Ray parameters in float gl_RayTminNV; in float gl_RayTmaxNV; in uint gl_IncomingRayFlagsNV; In the callable shading language, built-in variables are declared as follows // Work Dimensions in uvec3 gl_LaunchIDNV; in uvec3 gl_LaunchSizeNV; Add the following description for gl_LaunchIDNV: The input variable gl_LaunchIDNV is available in the ray generation, intersection, any-hit, closest-hit, and miss languages to specify the index of the work item being processed. One work item is generated for each of the width times height times depth items dispatched by a vkCmdTraceRaysNV call. All shader invocations inherit the same value for gl_LaunchIDNV. Add the following description for gl_LaunchSizeNV: gl_LaunchSizeNV is available in the ray generation, intersection, any-hit, closest-hit, and miss shaders to specify the and dimensions passed into a vkCmdTraceRaysNV call. Add the following description for gl_PrimitiveID: gl_PrimitiveID is available in the intersection, any-hit and closest-hit shaders to specify the index of the triangle or bounding box being processed. See the Ray Tracing chapter of the Vulkan specification for more details. Add the following description for gl_InstanceCustomIndexNV: gl_InstanceCustomIndex is available in the intersection, any-hit and closest-hit shaders to specify the application defined value of the instance that intersects the current ray. Only lower 24 bits are valid, upper 8 bits will be ignored. See the Ray Tracing chapter of the Vulkan specification for more details. Add the following description for gl_InstanceID: gl_InstanceID is available in the intersection, any-hit, and closest-hit shaders to specify the index of the instance that intersects the current ray. See the Ray Tracing chapter of the Vulkan specification for more details. Add the following description for gl_WorldRayOriginNV, gl_WorldRayDirectionNV, gl_ObjectRayOriginNV, and gl_ObjectRayDirectionNV: The variables gl_WorldRayOriginNV, gl_WorldRayDirectionNV, gl_ObjectRayOriginNV, and gl_ObjectRayDirectionNV are available in the intersection, any-hit, closest-hit, and miss shaders to specify the origin and direction of the ray being processed in both world and object space respectively. Add the following description for gl_RayTminNV and gl_RayTmaxNV: The variables gl_RayTminNV and gl_RayTmaxNV are available in the intersection, any-hit, closest-hit, and miss shaders to specify the parametric and values of the ray being processed. The values are independent of the space in which the ray and origin exist. The value remains constant for the duration of the ray query, while the value changes throughout the lifetime of the ray query that produced the intersection. In the closest-hit shader, the value reflects the closest distance to the intersected primitive. In the any-hit shader, it reflects the distance to the primitive currently being intersected. In the intersection shader, it reflects the distance to the closest primitive intersected so far. The value can change in the intersection shader after calling reportIntersectionNV() if the corresponding any hit shader does not ignore the intersection. In a miss shader, the value is identical to the parameter passed into traceNV(). Add the following description for gl_IncomingRayFlagsNV: gl_IncomingRayFlagsNV is available in intersection, closest-hit, any-hit, and miss, shaders to specify the current ray's flags as passed via the 'rayflags' argument of traceNV() call resulting in invocation of current shader stage. Add the following description for gl_HitTNV: gl_HitTNV is available only in the any-hit and closest-hit shaders. This is an alias of gl_RayTmaxNV added to closest-hit and any-hit shaders for convenience. Add the following description for gl_HitKindNV: gl_HitKindNV is available in the any hit and closest hit languages to describe the intersection that triggered the execution of the current shader. Values are sent from the intersection shader. Add the following description for gl_ObjectToWorldNV and gl_WorldToObjectNV: The matrices gl_ObjectToWorldNV and gl_WorldToObjectNV are available in the intersection, any-hit, and closest-hit shaders to specify the current object-to-world and world-to-object transformation matrices respectively, which are determined by the instance of the current intersection. See the Ray Tracing chapter of the Vulkan specification for more details. Add a new subsection 7.3.2, "Fixed Constants" The following constants are provided in all ray tracing shader stages const uint gl_RayFlagsNoneNV = 0U; const uint gl_RayFlagsOpaqueNV = 1U; const uint gl_RayFlagsNoOpaqueNV = 2U; const uint gl_RayFlagsTerminateOnFirstHitNV = 4U; const uint gl_RayFlagsSkipClosestHitShaderNV = 8U; const uint gl_RayFlagsCullBackFacingTrianglesNV = 16U; const uint gl_RayFlagsCullFrontFacingTrianglesNV = 32U; const uint gl_RayFlagsCullOpaqueNV = 64U; const uint gl_RayFlagsCullNoOpaqueNV = 128U; These can be used as flags for the 'rayflags' argument for traceNV call, or for comparing value to gl_IncomingRayFlagsNV. Additions to Chapter 8 of the OpenGL Shading Language Specification (Built-in Functions) Add Section 8.19, Ray Tracing Functions Syntax: void traceNV(accelerationStructureNV topLevel, uint rayFlags, uint cullMask, uint sbtRecordOffset, uint sbtRecordStride, uint missIndex, vec3 origin, float Tmin, vec3 direction, float Tmax, int payload); This function is only available in the ray generation, closest hit, and miss shaders. Initiates a ray query against a top-level structure, triggering the execution of various intersection and any-hit shaders as ray-geometry intersections are being evaluated, and finally the execution of either a closest-hit or miss shader, depending on whether an intersection was found. The ray's origin and direction are specified by and , and the valid parametric range on which intersections can occur is specified by and . is any combination of built-in constants as defined in Section 7.3 "Built-In Constants". is an 8 bit mask which specifies the instances to be intersected i.e visible to the traced ray. This mask will be combined with the mask field specified in VkGeometryInstanceNV as defined in the Ray Tracing chapter of Vulkan Specification using a bitwise AND operation. The instance is visible only if the result of the operation is non-zero. The upper 24 bits of this value are ignored. If the value is zero, no instances are visible. Associated with the ray is which is a compile-time constant to select a shader defined structure containing data that will be passed to other shader stages. This can be accessed for reading and writing by each any-hit shader invoked along the ray, and by the miss or closest-hit shader at the end of the query. It is possible for a shader to contain multiple invocations of traceNV() using different payload types, as long as the shaders executed in the trace call have defined compatible payload types. Different payload types are chosen based on the different values of the compile-time constant which correspond the the rayPayload/rayPayloadIn qualified variables having the same value for the location layout qualifier. The and parameters influence the computation of record indices of the that locate the intersection, any-hit, and closest-hit shaders during a trace query. See the Ray Tracing chapter of the Vulkan specification for more information. The parameter influences computation of indices into the to locate a miss shader during a trace query. See the Ray Tracing chapter of the vulkan specification for more information. Syntax: bool reportIntersectionNV(float hitT, uint hitKind); This function is only available in intersection shaders. Invokes the current hit shader once an intersection shader has determined that a ray intersection has occurred. If the intersection occurred within the current ray interval, the any hit shader corresponding to the current intersection shader is invoked. If the intersection is not ignored in the any-hit shader, is committed as the new gl_RayTmaxNV value of the current ray and is committed as the new value for gl_HitKindNV. Syntax: void ignoreIntersectionNV(); This function is only available in an any-hit shader. Terminates the calling any-hit shader and continues the ray query without modifying gl_RayTmaxNV and gl_HitKindNV. Syntax: void terminateRayNV(); This function is only available in an any-hit shader. Terminates the calling any-hit shader and stops the ray query. It commits the hitT as the new gl_RayTmaxNV value of the current ray query, and hitKind as the new value for gl_HitKindNV. It then invokes the current closest-hit shader. Syntax: void executeCallableNV(uint sbtRecordIndex, int callable) This function is available only in ray generation, closest-hit, miss, and callable stage. Invokes the callable located at 'sbtRecordIndex' in the shader binding table. Refer to Ray Tracing chapter of Vulkan specification for details. is a compile-time constant used to select an shader defined structure containing data that will be passed to a callable shader stage and can be accessed for reading and writing by the callable. It is possible for a shader to contain multiple invocations of executeCallableNV() using different types, as long as the shaders executed in the callable have defined compatible callableDataInNV types. Different callable data types are chosen based on the different values of the compile-time constant which corresponds to callableDataNV/callableDataInNV qualified variables having the same value for the location layout qualifier. Example : Ray Generation Shader : #version 460 core #extension GL_NV_ray_tracing : enable layout(location = 0) rayPayloadNV vec4 payload; layout(location = 0) callableDataNV float blendColor; layout(binding = 0, set = 0) uniform accelerationStructureNV acc; layout(binding = 1, rgba32f) uniform image2D img; layout(binding = 1, set = 0) uniform rayParams { vec3 rayOrigin; vec3 rayDir; uint sbtOffset; uint sbtStride; uint missIndex; uint callableSbtIndex; }; vec3 computeDir(vec3 inDir) { inDir.x = inDir.x + float(gl_LaunchIDNV.x / gl_LaunchSizeNV.x); inDir.y = inDir.y + float(gl_LaunchIDNV.y / gl_LaunchSizeNV.y); return inDir; } void main() { vec4 imgColor = vec4(0); traceNV(acc, gl_RayFlagsOpaqueNV, 0xff, sbtOffset, sbtStride, missIndex, rayOrigin, 0.0, computeDir(rayDir), 100.0f, 0 /* payload */); executeCallableNV(callableSbtIndex, 0 /* blendColor */); imgColor = payload + vec4(blendColor) ; imageStore(img, ivec2(gl_LaunchIDNV), imgColor); } Callable Shader: #version 460 core #extension GL_NV_ray_tracing : enable layout(location = 0) callableDataInNV float outColor; layout(shaderRecordNV) buffer block { uvec2 blendWeight; }; void main() { outColor = float((blendWeight.x >> 5U) & 0x7U + blendWeight.y & 0x3U); } Interactions with GL_KHR_shader_subgroup If GL_KHR_shader_subgroup is supported, the following built-in variables are available in the ray generation, intersection, any-hit, closest-hit, miss, and callable shading languages: mediump in uint gl_SubgroupSize; mediump in uint gl_SubgroupInvocationID; highp in uvec4 gl_SubgroupEqMask; highp in uvec4 gl_SubgroupGeMask; highp in uvec4 gl_SubgroupGtMask; highp in uvec4 gl_SubgroupLeMask; highp in uvec4 gl_SubgroupLtMask; and have the same sematics. Additionally, all the "Shader Invocation Group Functions" that are not listed as compute-only are available in the ray generation, intersection, any-hit, closest-hit, miss, and callable shading languages. Interactions with GL_NV_shader_subgroup_partitioned If GL_NV_shader_subgroup_partitioned is supported, subgroupPartitionNV() and all the subgroupPartitioned*NV() builtin functions are available in the ray generation, intersection, any-hit, closest-hit, miss, and callable shading languages. Interactions with GL_NV_shaders_sm_builtins If GL_NV_shader_sm_builtins is supported, the builtin variables added by this extension are available in the ray generation, intersection, any-hit, closest-hit, miss, and callable shading languages. Interactions with GL_ARB_shader_ballot If GL_ARB_shader_ballow is supported, the builtin variables and functions added by this extension are available in the ray generation, intersection, any-hit, closest-hit, miss, and callable shading languages. Interactions with GL_ARB_shader_group_vote If GL_ARB_shader_group_vote is supported, the builtin functions added by this extension are available in the ray generation, intersection, any-hit, closest-hit, miss, and callable shading languages. Interactions with GL_ARB_shader_clock If GL_ARB_shader_clock is supported, the new timing functions added by this extension are available in the ray generation, intersection, any-hit, closest-hit, miss, and callable shading languages. Interactions with GL_EXT_shader_realtime_clock If GL_EXT_shader_realtime_clock is supported, the new timing functions added by this extension are available in the ray generation, intersection, any-hit, closest-hit, miss, and callable shading languages. Issues 1) Do we need to specify the GL_NV_ray_tracing as enabled for these new shader stages? RESOLVED : Yes, needs to be specified in shaders. 2) How are we going to specify callable shaders? RESOLVED : Callables are implemented as a separate shader stage. 3) Where should we define GLSL flags that are used to define ray types and built in hit kinds? RESOLVED : Added them as built-in constants to Section 7.3 4) Should we allow type polymorphism in the traceNV() call for the ray payload? RESOLVED : GLSL does not allow usage of templates, traceNV() builtin has last argument as 'int payload'. This corresponds to location qualifier assigned to any rayPayloadNV qualified variables which in turn allows dispatching traceNV calls with different payload types. 5) Where should we specify how attribute data is passed between the different ray tracing stages? RESOLVED: rayPayloadNV/rayPayloadInNV/hitAttributeNV/callableDataNV callableDataInNV 6) This extension adds gl_InstanceID for the intersection, any hit, and closest hit shaders, but in KHR_vulkan_glsl, gl_InstanceID is replaced with gl_InstanceIndex. Which should be used for Vulkan in this extension? RESOLVED: This extension uses gl_InstanceID and maps it to InstanceId in SPIR-V. It is acknowledged that this is different than other shader stages in Vulkan. There are two main reasons for the difference here: - symmetry with gl_PrimitiveID which is also available in these shaders - there is no "baseInstance" relevant for these shaders, and so ID makes it more obvious that this is zero-based. 7) Are subgroup operations supported in ray tracing stages? RESOLVED: Yes. All the non-compute-only builtin variables and functions are available in all of the ray tracing shader stages. That is, everything except: gl_NumSubgroups, gl_SubgroupID, and subgroupMemoryBarrierShared(). 8) Does the miss shading stage really have gl_ObjectRayOriginNV and gl_ObjectRayDirectionNV built-ins given that there was no object intersected? RESOLVED: It was noticed that these were inadvertently included by this extension when EXT_ray_tracing was being developed and removed there since they cannot possibly be well-defined values in the miss shading language. However, we decided to leave them in NV_ray_tracing for compatibility. Note that SPIR-V validation may still warn about use of these in a miss shader, since their use is almost certainly a mistake. Revision History Rev. Date Author Changes ---- ----------- ------ ------------------------------------------- 9 16-Dec-2020 dgkoch Add interactions with subgroup and clock extensions 8 30-Nov-2020 dgkoch Add issue 8 about gl_ObjectRay params in miss shader 7 15-Oct-2019 dgkoch Fix github issues #93, #95 6 25-Mar-2019 ewerness Callables shouldn't have incoming ray flags 5 04-Mar-2019 alele Clarify readonly semantics for buffer block with shaderRecordNV qualifier. 4 21-Nov-2018 dgkoch Fix storage class SPIR-V mappings. 3 20-Nov-2018 dgkoch Add mapping to SPIR-V. Add issue 6 clarifying use of gl_InstanceID. 2 1-Oct-2018 alele Add support for callables Add gl_IncomingRayFlags Allow rayflags in all stages Clarify barycentrics passed implicitly for default triangle intersection Update launch builtins to support 3D grids Rename NVX_raytracing to NV_ray_tracing Add examples 1 7-Sep-2018 alele Internal revisions.