-
Pipeline Overview
- Unlike rasterization (vertex → fragment), RT pipeline has 5 shader stages
- Ray generation → [intersection → any-hit] → closest-hit / miss
- Hardware traverses the TLAS/BLAS, calling shaders at each stage
- Shader Binding Table (SBT) maps ray types to shader programs
-
Shader Stages
- Ray Generation (
.rgen)
- Entry point — one invocation per pixel (or per ray)
- Calls
traceRayEXT() to launch rays
- Reads result from payload, writes to output image
- Intersection (
.rint)
- Custom intersection test for non-triangle geometry (AABBs, spheres, curves)
- Not needed for triangle geometry — hardware handles it
- Calls
reportIntersectionEXT(t, hitKind) to report a hit
- Any-Hit (
.rahit)
- Called for every potential hit (not just closest)
- Used for: alpha testing, transparency, counting hits
- Can call
ignoreIntersectionEXT() to reject a hit
- Can call
terminateRayEXT() to stop traversal
- Closest-Hit (
.rchit)
- Called once for the closest confirmed hit
- Main shading happens here: BRDF evaluation, shadow rays, etc.
- Access to
gl_HitTEXT, gl_PrimitiveID, gl_InstanceCustomIndexEXT
- Miss (
.rmiss)
- Called when ray hits nothing
- Returns sky/environment color
- Can have multiple miss shaders (one per ray type)
-
Shader Binding Table (SBT)
- Maps ray types to shader programs
- Layout:
[RayGen | Miss shaders | Hit groups | Callable shaders]
- Each entry is a shader handle (32 bytes) + optional inline data
- Alignment requirements
shaderGroupHandleSize — typically 32 bytes
shaderGroupBaseAlignment — typically 64 bytes
shaderGroupHandleAlignment — typically 32 bytes
- Each region must be aligned to
shaderGroupBaseAlignment
- SBT regions
- Ray generation: exactly 1 shader
- Miss: one per ray type (e.g., primary rays, shadow rays)
- Hit groups: one per (geometry type × ray type) combination
- Each hit group =
{closest-hit, any-hit, intersection} shaders
- Indexing formula
hitGroupIndex = instanceSBTOffset + geometryIndex * sbtStride + rayContributionToHitGroupIndex
instanceSBTOffset = VkAccelerationStructureInstanceKHR.instanceShaderBindingTableRecordOffset
- Building the SBT
-
Shadow Ray Pattern
- Use a separate payload location for shadow rays
- Shadow miss shader:
layout(location=1) rayPayloadInEXT bool isShadowed; void main() { isShadowed = false; }
-
Ray Recursion Depth
maxPipelineRayRecursionDepth — max nested traceRayEXT calls
- Depth 1: primary rays only (no shadow rays from hit shader)
- Depth 2: primary + shadow rays (most common)
- Higher depth: expensive — prefer iterative approach with payload
- For path tracing: use iterative loop in rgen shader, not recursive hit shaders