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);

4. Issues

None.

5. Further Functionality

None.