• Vulkan RT Pipeline


  • 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

  • Ray Generation Shader


  • Closest-Hit Shader


  • Miss Shader


  • Shadow Ray Pattern

    • Use a separate payload location for shadow rays
    • Shadow miss shader: layout(location=1) rayPayloadInEXT bool isShadowed; void main() { isShadowed = false; }

  • Pipeline Creation


  • 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