光线追踪
光线追踪使用与图形和计算管线都不同的单独渲染管线(请参阅 光线追踪管线)。
在光线追踪管线中,可以调用 管线追踪光线 指令来执行 光线遍历,从而在其执行期间调用各种光线追踪着色器阶段。光线追踪管线对象和遍历的加速结构中存在的几何体之间的关系,通过一个称为着色器绑定表的 VkBuffer 对象传递给光线追踪命令。OpExecuteCallableKHR
也可以在光线追踪管线中使用,以调用 可调用着色器。
在执行期间,控制在调度和其他操作之间交替。调度功能是特定于实现的,负责工作负载执行。着色器阶段是可编程的。 遍历是指遍历加速结构以查找光线与几何体的潜在交点的过程,是固定功能。
管线的可编程部分在单射线编程模型中公开,每次调用处理一个光线。可以使用标准内存屏障同步内存操作。在光线追踪管线中必须不使用 Workgroup
范围和存储类为 Workgroup
的变量。
着色器调用指令
着色器调用是指一条可能通过创建执行不同着色器阶段的一个或多个调用来导致执行在其他地方继续的指令。
下表列出了所有着色器调用指令以及每个指令可以直接调用的阶段。
指令 | 相交 | 任何命中 | 最近命中 | 未命中 | 可调用 |
---|---|---|---|---|---|
|
X |
X |
X |
X |
|
|
X |
X |
X |
X |
|
|
X |
||||
|
X |
||||
|
X |
X |
|||
|
X |
X |
|||
|
X |
X |
着色器调用指令创建的调用由实现分组为子组。这些子组可能与父调用的子组无关。
管线追踪光线指令可以递归使用;调用的着色器可以自己执行管线追踪光线指令,最大深度由 maxRecursionDepth
或 maxRayRecursionDepth
限制定义。
直接从 API 调用的着色器始终具有 0 的递归深度;由管线追踪光线指令执行的每个着色器的递归深度都比调用它的着色器的递归深度高 1。应用程序必须不调用递归深度大于管线中指定的 maxRecursionDepth
或 maxPipelineRayRecursionDepth
值的着色器。
对于其他可能递归的着色器调用指令(例如 OpExecuteCallableKHR
),没有显式的递归限制,但存在由 堆栈大小 确定的上限。
调用重打包指令是一条光线追踪指令,其中实现可能会更改正在执行的调用集。当遇到重打包指令时,该调用会被暂停,并开始新的调用并执行该指令。执行重打包指令(可能导致其他光线追踪着色器阶段执行)后,新调用结束,原始调用恢复,但可能在不同的子组中或在同一子组中以不同的 SubgroupLocalInvocationId
恢复。当子组中的一部分调用执行调用重打包指令时,那些不执行此指令的调用将保留在相同的子组中,并具有相同的 SubgroupLocalInvocationId
。
OpTraceRayKHR
、OpTraceRayMotionNV
、OpReorderThreadWithHintNV
、OpReorderThreadWithHitObjectNV
、OpReportIntersectionKHR
和 OpExecuteCallableKHR
指令是调用重打包指令。
在着色器调用指令之前、指令之后或由指令创建的执行调用是着色器调用相关的。
如果实现更改了子组的构成,则调用重新打包指令必须相应地更改 SubgroupSize
、SubgroupLocalInvocationId
、SMIDNV
、WarpIDNV
以及从中派生的内置变量(SubgroupEqMask
、SubgroupGeMask
、SubgroupGtMask
、SubgroupLeMask
、SubgroupLtMask
)的值。当在光线生成、最近命中、未命中、相交和可调用着色器中使用这些 BuiltIn
变量时,应用程序必须使用 Volatile
语义。同样,应用程序必须对在相交着色器中使用的任何带有 RayTmaxKHR
修饰的 Builtin
使用 Volatile
语义。
子组操作在可编程的光线追踪着色器阶段中是允许的。但是,着色器调用指令对子组指令或执行该指令的动态实例的子组范围指令的结果的潜在有效位置设置了限制。例如,在调用重新打包指令之后使用在该指令之前计算的投票操作的结果时,必须小心。投票结果可能不正确,因为调用集可能已更改。 尽管要求将 对于时钟操作,不应将在重新打包指令的动态实例之前读取的 |
当光线追踪着色器执行一个调用重新打包指令的动态实例,该指令导致另一个光线追踪着色器被调用时,它们的指令通过 着色器调用顺序 相关联。
对于着色器调用相关的光线追踪调用
光线追踪命令
光线追踪命令 在光线追踪管道中引发工作。光线追踪命令被记录到命令缓冲区中,并且当由队列执行时,将产生根据绑定的光线追踪管道执行的工作。在将任何光线追踪命令记录到该命令缓冲区之前,必须将光线追踪管道绑定到命令缓冲区。
要调度光线追踪,请使用
// Provided by VK_NV_ray_tracing
void vkCmdTraceRaysNV(
VkCommandBuffer commandBuffer,
VkBuffer raygenShaderBindingTableBuffer,
VkDeviceSize raygenShaderBindingOffset,
VkBuffer missShaderBindingTableBuffer,
VkDeviceSize missShaderBindingOffset,
VkDeviceSize missShaderBindingStride,
VkBuffer hitShaderBindingTableBuffer,
VkDeviceSize hitShaderBindingOffset,
VkDeviceSize hitShaderBindingStride,
VkBuffer callableShaderBindingTableBuffer,
VkDeviceSize callableShaderBindingOffset,
VkDeviceSize callableShaderBindingStride,
uint32_t width,
uint32_t height,
uint32_t depth);
-
commandBuffer
是将命令记录到的命令缓冲区。 -
raygenShaderBindingTableBuffer
是保存光线生成着色器阶段的着色器绑定表数据的缓冲区对象。 -
raygenShaderBindingOffset
是光线生成着色器用于追踪的字节偏移量(相对于raygenShaderBindingTableBuffer
)。 -
missShaderBindingTableBuffer
是保存未命中着色器阶段的着色器绑定表数据的缓冲区对象。 -
missShaderBindingOffset
是未命中着色器用于追踪的字节偏移量(相对于missShaderBindingTableBuffer
)。 -
missShaderBindingStride
是missShaderBindingTableBuffer
中每个着色器绑定表记录的字节大小。 -
hitShaderBindingTableBuffer
是保存命中着色器阶段的着色器绑定表数据的缓冲区对象。 -
hitShaderBindingOffset
是命中着色器组用于追踪的字节偏移量(相对于hitShaderBindingTableBuffer
)。 -
hitShaderBindingStride
是hitShaderBindingTableBuffer
中每个着色器绑定表记录的字节大小。 -
callableShaderBindingTableBuffer
是保存可调用着色器阶段的着色器绑定表数据的缓冲区对象。 -
callableShaderBindingOffset
是可调用着色器用于追踪的字节偏移量(相对于callableShaderBindingTableBuffer
)。 -
callableShaderBindingStride
是callableShaderBindingTableBuffer
中每个着色器绑定表记录的字节大小。 -
width
是光线追踪查询维度的宽度。 -
height
是光线追踪查询维度的高度。 -
depth
是光线追踪查询维度的深度。
当命令执行时,会组装一个 width
× height
× depth
条光线的光线生成组。
要调度光线追踪,请使用
// Provided by VK_KHR_ray_tracing_pipeline
void vkCmdTraceRaysKHR(
VkCommandBuffer commandBuffer,
const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable,
const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable,
const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable,
const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable,
uint32_t width,
uint32_t height,
uint32_t depth);
-
commandBuffer
是将命令记录到的命令缓冲区。 -
pRaygenShaderBindingTable
是一个 VkStridedDeviceAddressRegionKHR,它保存了光线生成着色器阶段的着色器绑定表数据。 -
pMissShaderBindingTable
是一个 VkStridedDeviceAddressRegionKHR,它保存了 Miss 着色器阶段的着色器绑定表数据。 -
pHitShaderBindingTable
是一个 VkStridedDeviceAddressRegionKHR,它保存了 Hit 着色器阶段的着色器绑定表数据。 -
pCallableShaderBindingTable
是一个 VkStridedDeviceAddressRegionKHR,它保存了可调用着色器阶段的着色器绑定表数据。 -
width
是光线追踪查询维度的宽度。 -
height
是光线追踪查询维度的高度。 -
depth
是光线追踪查询维度的深度。
当命令执行时,会组装一个 width
× height
× depth
条光线的光线生成组。
当绑定的光线追踪管线启用调用掩码图像时,该管线将使用命令指定的调用掩码图像
// Provided by VK_HUAWEI_invocation_mask
void vkCmdBindInvocationMaskHUAWEI(
VkCommandBuffer commandBuffer,
VkImageView imageView,
VkImageLayout imageLayout);
-
commandBuffer
是将记录命令的命令缓冲区 -
imageView
是一个图像视图句柄,指定调用掩码图像。imageView
可以是 VK_NULL_HANDLE,这等效于指定一个填充为 1 的值的图像视图。 -
imageLayout
是当访问调用掩码图像时,可从imageView
访问的图像子资源的布局。
要调度光线追踪,并在设备上获取一些参数,请使用
// Provided by VK_KHR_ray_tracing_pipeline
void vkCmdTraceRaysIndirectKHR(
VkCommandBuffer commandBuffer,
const VkStridedDeviceAddressRegionKHR* pRaygenShaderBindingTable,
const VkStridedDeviceAddressRegionKHR* pMissShaderBindingTable,
const VkStridedDeviceAddressRegionKHR* pHitShaderBindingTable,
const VkStridedDeviceAddressRegionKHR* pCallableShaderBindingTable,
VkDeviceAddress indirectDeviceAddress);
-
commandBuffer
是将命令记录到的命令缓冲区。 -
pRaygenShaderBindingTable
是一个 VkStridedDeviceAddressRegionKHR,它保存了光线生成着色器阶段的着色器绑定表数据。 -
pMissShaderBindingTable
是一个 VkStridedDeviceAddressRegionKHR,它保存了 Miss 着色器阶段的着色器绑定表数据。 -
pHitShaderBindingTable
是一个 VkStridedDeviceAddressRegionKHR,它保存了 Hit 着色器阶段的着色器绑定表数据。 -
pCallableShaderBindingTable
是一个 VkStridedDeviceAddressRegionKHR,它保存了可调用着色器阶段的着色器绑定表数据。 -
indirectDeviceAddress
是一个缓冲区设备地址,它是指向 VkTraceRaysIndirectCommandKHR 结构的指针,该结构包含光线追踪参数。
vkCmdTraceRaysIndirectKHR
的行为类似于 vkCmdTraceRaysKHR,不同之处在于,光线追踪查询维度是在执行期间由设备从 indirectDeviceAddress
读取的。
VkTraceRaysIndirectCommandKHR
结构定义如下:
// Provided by VK_KHR_ray_tracing_pipeline
typedef struct VkTraceRaysIndirectCommandKHR {
uint32_t width;
uint32_t height;
uint32_t depth;
} VkTraceRaysIndirectCommandKHR;
-
width
是光线追踪查询维度的宽度。 -
height
是光线追踪查询维度的高度。 -
depth
是光线追踪查询维度的深度。
VkTraceRaysIndirectCommandKHR
的成员与 vkCmdTraceRaysKHR 中类似命名的参数具有相同的含义。
要调度光线追踪,并在设备上获取一些参数,请使用
// Provided by VK_KHR_ray_tracing_maintenance1 with VK_KHR_ray_tracing_pipeline
void vkCmdTraceRaysIndirect2KHR(
VkCommandBuffer commandBuffer,
VkDeviceAddress indirectDeviceAddress);
-
commandBuffer
是将命令记录到的命令缓冲区。 -
indirectDeviceAddress
是一个缓冲区设备地址,它是一个指向包含光线追踪参数的 VkTraceRaysIndirectCommand2KHR 结构的指针。
vkCmdTraceRaysIndirect2KHR
的行为类似于 vkCmdTraceRaysIndirectKHR,区别在于着色器绑定表参数以及调度维度是在执行期间由设备从 indirectDeviceAddress
读取的。
VkTraceRaysIndirectCommand2KHR
结构定义如下:
// Provided by VK_KHR_ray_tracing_maintenance1 with VK_KHR_ray_tracing_pipeline
typedef struct VkTraceRaysIndirectCommand2KHR {
VkDeviceAddress raygenShaderRecordAddress;
VkDeviceSize raygenShaderRecordSize;
VkDeviceAddress missShaderBindingTableAddress;
VkDeviceSize missShaderBindingTableSize;
VkDeviceSize missShaderBindingTableStride;
VkDeviceAddress hitShaderBindingTableAddress;
VkDeviceSize hitShaderBindingTableSize;
VkDeviceSize hitShaderBindingTableStride;
VkDeviceAddress callableShaderBindingTableAddress;
VkDeviceSize callableShaderBindingTableSize;
VkDeviceSize callableShaderBindingTableStride;
uint32_t width;
uint32_t height;
uint32_t depth;
} VkTraceRaysIndirectCommand2KHR;
-
raygenShaderRecordAddress
是此命令使用的光线生成着色器绑定表记录的VkDeviceAddress
。 -
raygenShaderRecordSize
是一个VkDeviceSize
,表示位于基址raygenShaderRecordAddress
的光线生成着色器绑定表记录的字节数。 -
missShaderBindingTableAddress
是此命令使用的未命中着色器绑定表中第一个记录的VkDeviceAddress
。 -
missShaderBindingTableSize
是一个VkDeviceSize
,表示位于missShaderBindingTableAddress
处的未命中着色器绑定表的总大小,此命令可能会访问该表。 -
missShaderBindingTableStride
是未命中着色器绑定表中记录之间的VkDeviceSize
字节数。 -
hitShaderBindingTableAddress
是此命令使用的命中着色器绑定表中第一个记录的VkDeviceAddress
。 -
hitShaderBindingTableSize
是一个VkDeviceSize
,表示位于hitShaderBindingTableAddress
处的命中着色器绑定表的总大小,此命令可能会访问该表。 -
hitShaderBindingTableStride
是命中着色器绑定表中记录之间的VkDeviceSize
字节数。 -
callableShaderBindingTableAddress
是此命令使用的可调用着色器绑定表中第一个记录的VkDeviceAddress
。 -
callableShaderBindingTableSize
是一个VkDeviceSize
,表示位于callableShaderBindingTableAddress
处的可是调用着色器绑定表的总大小,此命令可能会访问该表。 -
callableShaderBindingTableStride
是可调用着色器绑定表中记录之间的VkDeviceSize
字节数。 -
width
是光线追踪查询维度的宽度。 -
height
是光线追踪查询维度的高度。 -
depth
是光线追踪查询维度的深度。
VkTraceRaysIndirectCommand2KHR
的成员具有与 vkCmdTraceRaysKHR 的同名参数相同的含义。
间接着色器绑定表缓冲区参数必须满足与 vkCmdTraceRaysIndirectKHR 和 vkCmdTraceRaysKHR 中对应的参数相同的内存对齐和绑定要求。
着色器绑定表
着色器绑定表 是一种资源,它建立了光线追踪管线和为光线追踪管线构建的加速结构之间的关系。它指示了在加速结构中每个几何体上操作的着色器。此外,它还包含每个着色器访问的资源,包括纹理索引、缓冲区设备地址和常量。应用程序将着色器绑定表作为 VkBuffer 对象分配和管理。
着色器绑定表中的每个条目由 shaderGroupHandleSize
字节的数据组成,这些数据要么是通过 vkGetRayTracingShaderGroupHandlesKHR 查询来引用那些指定的着色器,要么全部为零以引用零着色器组。零着色器组的行为就像它是一个完全由 VK_SHADER_UNUSED_KHR
组成的着色器组。由步幅指定的其余数据是应用程序可见的数据,可以由着色器中的 ShaderRecordBufferKHR
块引用。
在光线追踪管线中使用的着色器绑定表被传递给 vkCmdTraceRaysNV、vkCmdTraceRaysKHR 或 vkCmdTraceRaysIndirectKHR 命令。在光线追踪管线上执行的着色器中,着色器绑定表是只读的。
使用 ShaderRecordBufferKHR
存储类标识的着色器变量用于访问提供的着色器绑定表。此类变量必须
-
类型为
OpTypeStruct
,或此类型的数组, -
使用
Block
修饰符标识,并且 -
使用 偏移量和步幅赋值 中指定的
Offset
、ArrayStride
和MatrixStride
修饰符显式布局。
ShaderRecordBufferKHR
存储类中任何 Block
修饰变量的成员的 Offset
修饰符 必须 不会导致该变量所需的空间超出范围 [0, maxStorageBufferRange
)。
从光线追踪管线访问着色器绑定表 必须 与 VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR
管线阶段 和 VK_ACCESS_SHADER_READ_BIT
的 访问类型 同步。
由于不同的着色器记录缓冲区可以与同一个着色器关联,因此如果同一个着色器的不同调用可以在着色器记录缓冲区中引用不同的数据,例如,如果同一个着色器在着色器绑定表中出现两次,并且具有不同的着色器记录缓冲区,则具有 |
索引规则
为了在光线追踪调度期间执行正确的着色器并访问正确的资源,实现必须能够在执行的各个阶段定位着色器绑定表条目。这是通过定义一组索引规则来实现的,这些规则计算着色器绑定表中记录相对于内存中缓冲区基址的位置。应用程序必须以一种方式组织着色器绑定表的内存内容,使得应用索引规则将引导到正确的记录。
射线生成着色器
每次光线追踪调度只执行一个射线生成着色器。
对于 vkCmdTraceRaysKHR,射线生成着色器的位置由 pRaygenShaderBindingTable->deviceAddress
参数指定,无需索引。所有访问的数据必须小于 pRaygenShaderBindingTable->size
字节(从 deviceAddress
开始)。pRaygenShaderBindingTable->stride
未使用,必须等于 pRaygenShaderBindingTable->size
。
对于 vkCmdTraceRaysNV,射线生成着色器的位置由 raygenShaderBindingTableBuffer
和 raygenShaderBindingOffset
参数指定,无需索引。
命中着色器
用于计算相交、任意命中和最近命中着色器位置的基础是与顶层加速结构的每个实例一起存储的 instanceShaderBindingTableRecordOffset
值 (VkAccelerationStructureInstanceKHR)。此值确定给定实例的着色器绑定表记录的起始位置。
在以下规则中,geometryIndex
指的是实例内相交几何体的 几何体索引。
sbtRecordOffset
和 sbtRecordStride
值作为参数传递给在着色器中调用的 traceNV
() 或 traceRayEXT
()。有关更多详细信息,请参阅 OpenGL Shading Language Specification 的第 8.19 节(光线追踪函数)。在 SPIR-V 中,这些对应于 管道跟踪射线 指令的 SBTOffset
和 SBTStride
参数。
然后将此计算的结果添加到 pHitShaderBindingTable->deviceAddress
(传递给 vkCmdTraceRaysKHR 的设备地址)或 hitShaderBindingOffset
(传递给 vkCmdTraceRaysNV 的基础偏移量)。
对于 vkCmdTraceRaysKHR,计算 pHitShaderBindingTable
中命中着色器绑定表记录地址的完整规则是
-
pHitShaderBindingTable->deviceAddress
+pHitShaderBindingTable->stride
× (instanceShaderBindingTableRecordOffset
+geometryIndex
×sbtRecordStride
+sbtRecordOffset
)
所有访问的数据必须小于从基址开始的 pHitShaderBindingTable->size
字节。
对于 vkCmdTraceRaysNV,偏移量和步长来自直接参数,因此计算 hitShaderBindingTableBuffer
中命中着色器绑定表记录地址的完整规则是
-
hitShaderBindingOffset
+hitShaderBindingStride
× (instanceShaderBindingTableRecordOffset
+geometryIndex
×sbtRecordStride
+sbtRecordOffset
)
未命中着色器
当射线查询未能找到给定场景几何体的交点时,将执行未命中着色器。在整个光线追踪调度中,可能会执行多个未命中着色器。
用于计算未命中着色器位置的基础是 pMissShaderBindingTable->deviceAddress
(传递给 vkCmdTraceRaysKHR 的设备地址)或 missShaderBindingOffset
(传递给 vkCmdTraceRaysNV 的基础偏移量)。
missIndex
值作为参数传递给在着色器中调用的 traceNV
() 或 traceRayEXT
()。有关更多详细信息,请参阅 OpenGL Shading Language Specification 的第 8.19 节(光线追踪函数)。在 SPIR-V 中,这对应于 管道跟踪射线 指令的 MissIndex
参数。
对于 vkCmdTraceRaysKHR,计算 pMissShaderBindingTable
中未命中着色器绑定表记录地址的完整规则是
-
pMissShaderBindingTable->deviceAddress
+pMissShaderBindingTable->stride
×missIndex
所有访问的数据必须小于从基址开始的 pMissShaderBindingTable->size
字节。
对于 vkCmdTraceRaysNV,偏移量和步长来自直接参数,因此计算 missShaderBindingTableBuffer
中未命中着色器绑定表记录地址的完整规则是
-
missShaderBindingOffset
+missShaderBindingStride
×missIndex
可调用着色器
当光线追踪着色器请求时,将执行可调用着色器。在整个光线追踪调度中,可能会执行多个可调用着色器。
用于计算可调用着色器位置的基础是 pCallableShaderBindingTable->deviceAddress
(传递给 vkCmdTraceRaysKHR 的设备地址)或 callableShaderBindingOffset
(传递给 vkCmdTraceRaysNV 的基础偏移量)。
sbtRecordIndex
值作为参数传递给在着色器中调用的 executeCallableNV
() 或 executeCallableEXT
()。有关更多详细信息,请参阅 OpenGL Shading Language Specification 的第 8.19 节(光线追踪函数)。在 SPIR-V 中,这对应于 OpExecuteCallableNV
或 OpExecuteCallableKHR
指令的 SBTIndex
参数。
对于 vkCmdTraceRaysKHR,计算 pCallableShaderBindingTable
中可调用着色器绑定表记录地址的完整规则是
-
pCallableShaderBindingTable->deviceAddress
+pCallableShaderBindingTable->stride
×sbtRecordIndex
所有访问的数据必须小于从基址开始的 pCallableShaderBindingTable->size
字节。
对于 vkCmdTraceRaysNV,偏移量和步长来自直接参数,因此计算 callableShaderBindingTableBuffer
中可调用着色器绑定表记录地址的完整规则是
-
callableShaderBindingOffset
+callableShaderBindingStride
×sbtRecordIndex
光线追踪管道堆栈
光线追踪管道可能有一组大量的着色器,这些着色器可能以各种调用链组合调用以执行光线追踪。为了存储给定着色器执行的参数,实现可能会使用内存中的数据堆栈。此堆栈的尺寸必须设置为应用程序执行的任何调用链中所有着色器的堆栈大小之和。
如果未显式设置堆栈大小,则管道的堆栈大小为
-
rayGenStackMax + min(1,
maxPipelineRayRecursionDepth
) × max(closestHitStackMax, missStackMax, intersectionStackMax + anyHitStackMax) + max(0,maxPipelineRayRecursionDepth
-1) × max(closestHitStackMax, missStackMax) + 2 × callableStackMax
其中 rayGenStackMax、closestHitStackMax、missStackMax、anyHitStackMax、intersectionStackMax 和 callableStackMax 是由管道定义的任何着色器组中任何着色器的各个着色器阶段查询的最大堆栈值。
这个堆栈大小可能非常大,因此应用程序可能需要在管线编译后提供更准确的堆栈大小。应用程序提供的值是所有可能调用链中,所有着色器在调用链中的总和的最大值,其中考虑了任何关于调用链属性的应用程序特定知识。
例如,如果一个应用程序有两种类型的最近命中和未命中着色器可以使用,但第一级的射线只会使用第一种(可能是反射),而第二级只会使用第二种(例如,遮挡或阴影射线),那么应用程序可以通过类似于以下方式计算堆栈大小:
这保证不大于默认堆栈大小计算,默认堆栈大小计算假设两个调用级别都可能是两者中较大的那个。 |
光线追踪捕获回放
与bufferDeviceAddressCaptureReplay类似,rayTracingPipelineShaderGroupHandleCaptureReplay
功能允许查询可在未来回放中使用的不透明数据。
在捕获阶段,捕获/回放工具应使用 vkGetRayTracingCaptureReplayShaderGroupHandlesKHR 查询着色器组句柄回放的不透明数据。
在回放期间,在管线创建时使用 VkRayTracingShaderGroupCreateInfoKHR::pShaderGroupCaptureReplayHandle
提供不透明数据,会使实现生成与捕获阶段相同的着色器组句柄,允许捕获/回放工具重用先前记录的着色器绑定表缓冲区内容,或通过再次调用 vkGetRayTracingCaptureReplayShaderGroupHandlesKHR 获取相同的句柄。