Permalink
Switch branches/tags
Nothing to show
Find file Copy path
a8b732a Sep 19, 2018
1 contributor

Users who have contributed to this file

649 lines (452 sloc) 25.9 KB
Name
NVX_raytracing
Name Strings
GL_NVX_raytracing
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
In progress
Version
Last Modified Date: 2018-09-07
Revision: 1
Number
TBD.
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.
Overview
This extension document modifies GLSL to add new shader stages to support raytracing.
They are namely ray generation, intersection, any hit, closest hit, and miss stages
collectively referred as ray tracing stages. There is an additional callable stage
which is proposed but unimplemented as of release of this extension.
This extension document adds support for the following extensions to be used
within GLSL:
- GL_NVX_raytracing - enables raytracing stages.
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_NVX_raytracing : <behavior>
where <behavior> is as specified in section 3.3.
New preprocessor #defines are added:
#define GL_NVX_raytracing 1
Additions to Chapter 2 of the OpenGL Shading Language Specification
(Overview of OpenGL Shading)
Add Section 2.7, Ray Generation Processor
The <ray generation processor> 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 <ray
generation shaders>. When a set of ray generation shaders are successfully
compiled and linked, they result in a <ray generation executable> 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 traceNVX() calls and process the
results. It can pass data to other raytracing stages through the ray
payload.
Add Section 2.8, Intersection Processor
The <intersection processor> 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 <intersection shaders>. When a set of
intersection shaders are successfully compiled and linked, they result in
an <intersection executable> 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 Raytracing
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 <any-hit processor> 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 <any-hit shaders>. When a set of any-hit
shaders are successfully compiled and linked, they result in an
<any-hit executable> 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 <closest-hit processor> 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 <closest-hit shaders>.
When a set of closest-hit shaders are successfully compiled and linked, they
result in a <closest-hit executable> 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 traceNVX().
Add Section 2.11, Miss Processor
The <miss processor> 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 <miss shaders>. When a set of miss shaders are successfully
compiled and linked, they result in a <miss executable> 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 traceNVX(), but cannot
access data generated by the intersection processor.
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)
accelerationStructureNVX
rayPayloadNVX
rayPayloadInNVX
hitAttributeNVX
Changes to Chapter 4 of The OpenGL Shading Language Specification, Version 4.60
Add following to Section 4.1 (Basic Types)
Raytracing Opaque Types
Types Meaning
----- -------
accelerationStructureNVX A handle representing acceleration structure
used for calculating intersection of rays with
geometry. Used only in a traceNVX call.
Add a new sub-section under Section 4.1.7 (Opaque Types)
4.1.7.x Acceleration Structure Types
accelerationStructureNVX 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, accelerationStructureNVX can only be indexed with
a dynamically uniform integral expression, otherwise results are undefined.
This type is used in traceNVX builtin described in Section 8.19
Members of structure cannot be declared with this type.
Modify Section 4.3 (Storage Qualifiers)
Storage Qualifier Meaning
----------------- -------
rayPayloadNVX Ray generation, any-hit, closest-hit, and miss
shader only. Storage associated with a ray
can which can be written/read by downstream stages
rayPayloadInNVX Closest-hit, any-hit and miss shader only. Storage associated
with ray sent to traceNVX during invocation of parent
ray generation shader/closest-hit shaders.
hitAttributeNVX Intersection, any-hit, and closest-hit shader only.
Storage associated with attributes of geometry
intersected by a ray.
Add a sub-section to Section 4.3 (Storage Qualifiers)
4.3.X rayPayloadNVX 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 read in ray generation, any-hit, closest-hit, and miss shaders
They can be written in 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 hitAttributeNVX 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 reportIntersectionNVX() are undefined. They cannot have any other
storage qualifiers. It is a compile-time error to declare unsized arrays
of this type.
4.3.X rayPayloadInNVX 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
It is a compile-time error to declare unsized arrays of this type.
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, *rayPayloadNVX, *rayPayloadInNVX*, *hitAttributeNVX*,
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 rayPayloadNVX
rayPayloadInNVX
shaderRecordNVX X buffer
Add new sub-section to Section 4.4
4.4.X rayPayloadNVX 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 rayPayloadInNVX 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 hitAttributeNVX Layout Qualifiers
No layout qualifiers are allowed on variables of this type.
Add to end of section 4.4.5, Uniform and Shader Storage Block Layout Qualifiers
The "shaderRecordNVX" qualifier is used to declare a buffer block and represents a
buffer within a shader record as defined in the API in Raytracing chapter of the Vulkan
specification. It is supported only in raytracing stages. It is a compile-time error
to apply this to any block type other than buffer. A buffer block declared with
layout(shaderRecordNVX) can be optionally declared with an instance. There can be only
one shaderRecordNVX 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 shaderRecordNVX. These blocks are initialized by a separate API as specified
in Raytracing 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 uvec2 gl_LaunchIDNVX;
in uvec2 gl_LaunchSizeNVX;
In the any-hit and closest-hit shading languages, built-in variables are declared
as follows
// Work dimensions
in uvec2 gl_LaunchIDNVX;
in uvec2 gl_LaunchSizeNVX;
// Geometry instance ids
in int gl_PrimitiveID;
in int gl_InstanceID;
in int gl_InstanceCustomIndexNVX;
// World space parameters
in vec3 gl_WorldRayOriginNVX;
in vec3 gl_WorldRayDirectionNVX;
in vec3 gl_ObjectRayOriginNVX;
in vec3 gl_ObjectRayDirectionNVX;
// Ray parameters
in float gl_RayTminNVX;
in float gl_RayTmaxNVX;
// Ray hit info
in float gl_HitTNVX;
in uint gl_HitKindNVX;
// Transform matrices
in mat4x3 gl_ObjectToWorldNVX;
in mat4x3 gl_WorldToObjectNVX;
In the intersection language, built-in variables are declared as follows
// Work dimensions
in uvec2 gl_LaunchIDNVX;
in uvec2 gl_LaunchSizeNVX;
// Geometry instance ids
in int gl_PrimitiveID;
in int gl_InstanceID;
in int gl_InstanceCustomIndexNVX;
// World space parameters
in vec3 gl_WorldRayOriginNVX;
in vec3 gl_WorldRayDirectionNVX;
in vec3 gl_ObjectRayOriginNVX;
in vec3 gl_ObjectRayDirectionNVX;
// Ray parameters
in float gl_RayTminNVX;
in float gl_RayTmaxNVX;
// Transform matrices
in mat4x3 gl_ObjectToWorldNVX;
in mat4x3 gl_WorldToObjectNVX;
In the miss shading language, built-in variables are declared as follows
// Work dimensions
in uvec2 gl_LaunchIDNVX;
in uvec2 gl_LaunchSizeNVX;
// World space parameters
in vec3 gl_WorldRayOriginNVX;
in vec3 gl_WorldRayDirectionNVX;
in vec3 gl_ObjectRayOriginNVX;
in vec3 gl_ObjectRayDirectionNVX;
// Ray parameters
in float gl_RayTminNVX;
in float gl_RayTmaxNVX;
Add the following description for gl_LaunchIDNVX:
The input variable gl_LaunchIDNVX 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 items dispatched by a vkCmdTraceRaysNVX call. All shader
invocations inherit the same value for gl_LaunchIDNVX.
Add the following description for gl_LaunchSizeNVX:
gl_LaunchSizeNVX is available in the ray generation, intersection, any-hit,
closest-hit, and miss shaders to specify the <width> and <height>
dimensions passed into a vkCmdTraceRaysNVX 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 Raytracing chapter of the Vulkan specification for more
details.
Add the following description for gl_InstanceCustomIndexNVX:
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 Raytracing 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 Raytracing chapter of the Vulkan specification for
more details.
Add the following description for gl_WorldRayOriginNVX, gl_WorldRayDirectionNVX,
gl_ObjectRayOriginNVX, and gl_ObjectRayDirectionNVX:
The variables gl_WorldRayOriginNVX, gl_WorldRayDirectionNVX, gl_ObjectRayOriginNVX,
and gl_ObjectRayDirectionNVX 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_RayTminNVX and gl_RayTmaxNVX:
The variables gl_RayTminNVX and gl_RayTmaxNVX are available in the intersection,
any-hit, closest-hit, and miss shaders to specify the parametric <Tmin>
and <Tmax> values of the ray being processed. The values are independent
of the space in which the ray and origin exist.
The <Tmin> value remains constant for the duration of the ray query, while
the <Tmax> 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 reportIntersectionNVX() if the corresponding any hit shader does not
ignore the intersection. In a miss shader, the value is identical to the
parameter passed into traceNVX().
Add the following description for gl_HitTNVX:
gl_HitTNVX is available only in the any-hit and closest-hit shaders. This is an
alias of gl_RayTmaxNVX added to closest-hit and any-hit shaders for convenience.
Add the following description for gl_HitKindNVX:
gl_HitKindNVX 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_ObjectToWorldNVX and
gl_WorldToObjectNVX:
The matrices gl_ObjectToWorldNVX and gl_WorldToObjectNVX 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 Raytracing
chapter of the Vulkan specification for more details.
Add a new subsection 7.3.2, "Fixed Constants"
The following constants are provided in the ray generation, closest-hit, and
miss stages only.
const uint gl_RayFlagsNoneNVX = 0U;
const uint gl_RayFlagsOpaqueNVX = 1U;
const uint gl_RayFlagsNoOpaqueNVX = 2U;
const uint gl_RayFlagsTerminateOnFirstHitNVX = 4U;
const uint gl_RayFlagsSkipClosestHitShaderNVX = 8U;
const uint gl_RayFlagsCullBackFacingTrianglesNVX = 16U;
const uint gl_RayFlagsCullFrontFacingTrianglesNVX = 32U;
const uint gl_RayFlagsCullOpaqueNVX = 64U;
const uint gl_RayFlagsCullNoOpaqueNVX = 128U;
These can be used as flags for the 'rayflags' argument for traceNVX call.
Additions to Chapter 8 of the OpenGL Shading Language Specification
(Built-in Functions)
Add Section 8.19, Raytracing Functions
Syntax:
void traceNVX(accelerationStructureNVX 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 <accelerationStructureNVX>
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 <origin> and <direction>,
and the valid parametric range on which intersections can occur is
specified by <Tmin> and <Tmax>.
<rayFlags> is any combination of built-in constants as defined in
Section 7.3 "Built-In Constants".
<cullMask> 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 VkGeometryInstanceNVX as defined in the Raytracing 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 <payload> which is a compile-time constant to select
an application 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 traceNVX() using
different payload types, as long as the shaders executed in the trace call have
defined compatible payload types.
The <sbtRecordOffset> and <sbtRecordStride> parameters influence the
computation of record indices of the <shader binding table> that locate
the intersection, any-hit, and closest-hit shaders during a trace query. See
the Raytracing chapter of the Vulkan specification for more information.
The <missIndex> parameter influences computation of indices into the
<shader binding table> to locate a miss shader during a trace query. See
the Raytracing chapter of the vulkan specification for more information.
Syntax:
bool reportIntersectionNVX(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, <hitT> is committed as the new gl_RayTmaxNVX value of the
current ray and <hitKind> is committed as the new value for gl_HitKindNVX.
Syntax:
void ignoreIntersectionNVX();
This function is only available in an any-hit shader.
Terminates the calling any-hit shader and continues the ray query without
modifying gl_RayTmaxNVX and gl_HitKindNVX.
Syntax:
void terminateRayNVX();
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_RayTmaxNVX value of the current ray query, and hitKind as
the new value for gl_HitKindNVX. It then invokes the current closest-hit
shader.
Issues
1) Do we need to specify the GL_NVX_raytracing as enabled for these new
shader stages?
RESOLVED : Yes, needs to be specified in shaders.
2) How are we going to specify callable shaders?
UNRESOLVED : This feature is currently unimplemented and will be supported
in a future release.
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 traceNVX() call for the ray
payload?
RESOLVED : GLSL does not allow usage of templates, traceNVX() builtin has
last argument as 'int payload'. This corresponds to location qualifier
assigned to any rayPayloadNVX qualified variables which in turn allows
dispatching traceNVX calls with different payload types.
5) Where should we specify how attribute data is passed between the
different raytracing stages?
RESOLVED : rayPayloadNVX/rayPayloadInNVX/hitAttributeNVX
Revision History
Rev. Date Author Changes
---- ----------- ------ -------------------------------------------
1 7-Sep-2018 alele Internal revisions.