VK_KHR_ray_tracing_position_fetch
This document details the VK_KHR_ray_tracing_position_fetch extension which exposes the ability to fetch vertex positions from an acceleration structure hit when ray tracing.
1. Problem Statement
Acceleration structures used in ray tracing have the position of the geometry provided to them and have to have at least some derived form of the position encoded in them. Applications frequently need to know the position or derived attribute of the triangle on a hit, so it is desirable to be able to share that information to avoid duplication. One of the derived attributes that is of particular interest is the normal of the hit.
2. Solution Space
Options considered:
-
Expose the normal (potentially compressed) of the triangle at the hit
-
Expose the positions of the triangle at the hit
Exposing the normal is only beneficial for an implementation that cannot expose the positions encoded in the acceleration structure, which seems to be a rare case. Exposing the positions of the triangle is more general and the application can easily compute the normal itself.
We choose the latter.
3. Proposal
3.1. New SPIR-V decorations
A new SPIR-V extension SPV_KHR_ray_tracing_position_fetch adds one ray pipeline shader variable decoration:
-
HitTriangleVertexPositionsKHR
which indicates a builtin which contains the vertex position values for a triangle hit in any-hit or closest hit shaders
3.2. New SPIR-V instructions
A new SPIR-V extension SPV_KHR_ray_tracing_position_fetch adds one shader instruction:
-
OpRayQueryGetIntersectionTriangleVertexPositionsKHR
which returns the vertex position values for a triangle hit when using ray query
3.3. New Acceleration structure build flag
-
VK_BUILD_ACCELERATION_STRUCTURE_ALLOW_DATA_ACCESS_KHR
on an acceleration structure indicates that an application wants to be able to read the data from that acceleration structure
3.4. GLSL mapping
The GLSL functionality is defined in GLSL_EXT_ray_tracing_position_fetch.
gl_HitVertexTrianglePositionsEXT -> HitTriangleVertexPositionsKHR decorated OpVariable
rayQueryGetIntersectionTriangleVertexPositionsEXT -> OpRayQueryGetIntersectionTriangleVertexPositionsKHR instruction
3.5. HLSL mapping
HLSL does not provide this functionality natively yet.
However, it is possible to use this functionality via SPIR-V Intrinsics.
The SPIR-V values for ray tracing position fetch are obtained from SPV_KHR_ray_tracing_position_fetch.
3.5.1. Ray Pipelines
In the core HLSL, add the following:
#define BuiltIn 11
#define RayTracingPositionFetchKHR 5336
#define HitTriangleVertexPositionsKHR 5335
[[vk::ext_capability(RayTracingPositionFetchKHR)]]
[[vk::ext_extension("SPV_KHR_ray_tracing_position_fetch")]]
In the function to access the data:
// Adding access to the vertex positions stored in the acceleration structure.
[[vk::ext_decorate(BuiltIn, HitTriangleVertexPositionsKHR)]]
float3 HitTriangleVertexPositions[3];
3.5.2. Ray Queries
In the core HLSL, add the following:
#define RayQueryPositionFetchKHR 5391
#define OpRayQueryGetIntersectionTriangleVertexPositionsKHR 5340
#define RayQueryCandidateIntersectionKHR 0
#define RayQueryCommittedIntersectionKHR 1
[[vk::ext_capability(RayQueryPositionFetchKHR)]]
[[vk::ext_extension("SPV_KHR_ray_tracing_position_fetch")]]
[[vk::ext_instruction(OpRayQueryGetIntersectionTriangleVertexPositionsKHR)]]
float3 RayQueryGetIntersectionTriangleVertexPositionsKHR(
[[vk::ext_reference]] RayQuery<RAY_FLAG_FORCE_OPAQUE> query,
int committed)[3];
Then to use this new instruction:
RayQuery < RAY_FLAG_FORCE_OPAQUE > q;
q.TraceRayInline(topLevelAS, RAY_FLAG_NONE, 0xFF, ray);
q.Proceed();
...
float3 positions[3] = RayQueryGetIntersectionTriangleVertexPositionsKHR(q, RayQueryCommittedIntersectionKHR);