本专栏我们主要来学一下Vulkan的光线追踪API的具体实现,本章主要是对其光追API拓展的简介,具体参照官网的两篇文章:Ray Tracing In Vulkan与 Vulkan-Guide。

一、Vulkan光追介绍

1.1 显卡特性

Vulkan光线追踪的版本包括许多Vulkan、SPIR-V和GLSL扩展。

主要的Vulkan扩展是VK_KHR_ray_tracing,它添加了:

  • Acceleration Structure的建造和管理的功能,
  • 支持光线跟踪着色器阶段和pipeline
  • 所有着色器阶段的Ray Query内部函数。

Vulkan光追的某些功能是可选的,因此请确保检查驱动程序上支持的功能和属性!

此扩展的特征由VKPhysicalDeviceRacingFeaturesKHR结构描述。结构体如下:

typedef struct VkPhysicalDeviceRayTracingFeaturesKHR {VkStructureType    sType;void*              pNext;VkBool32           rayTracing;VkBool32           rayTracingShaderGroupHandleCaptureReplay;VkBool32           rayTracingShaderGroupHandleCaptureReplayMixed;VkBool32           rayTracingAccelerationStructureCaptureReplay;VkBool32           rayTracingIndirectTraceRays;VkBool32           rayTracingIndirectAccelerationStructureBuild;VkBool32           rayTracingHostAccelerationStructureCommands;VkBool32           rayQuery;VkBool32           rayTracingPrimitiveCulling;
} VkPhysicalDeviceRayTracingFeaturesKHR;

rayTracing指示对光线跟踪管道和着色器阶段的支持; rayQuery表示支持ray查询功能;
rayTracingPrimitiveCulling表示在光线遍历期间支持剔除某些类型的图元;
rayTracingDirectTraceRays表示支持使用来自缓冲区的维度跟踪光线;
rayTracingDirectAccelerationStructureBuild表示支持使用来自缓冲区的几何信息构建加速度结构;
rayTracingHostAccessionStructureCommands表示支持基于CPU的加速结构构建;
rayTracingShaderGroupHandleCaptuReplay、rayTracingShaderGroupHandleCaptuReplayMixed和rayTracingAccelerationStructureCaptuReplay指示各种形式的捕获和重播调试功能是否可用;

具体光追实现只需要支持rayTracing和rayTracingIndirectTraceRays。还应注意,此扩展需要Vulkan 1.2(或以前版本的扩展)版本中的描述符索引和bufferDeviceAddress功能。

此扩展的可查询属性由vkPhysicalDeviceRacingPropertiesKHR结构描述。这里值得注意的是,着色器头(shaderGroupHandleSize)的大小要求正好为32,而最大递归深度(maxRecursionDepth)仅要求为1。

VK_KHR_ray_tracing依赖于两个额外的扩展,这两个扩展被添加为附加功能的构建块。 这些扩展添加了基础设施,但不能单独启用功能。未来的扩展可能会在API的其他领域建立在这些扩展的基础上,但此时VK_KHR_ray_tracing只允许将此功能用于光线跟踪。

VK_KHR_deferred_host_operations允许将消耗比较大的驱动程序操作在应用程序管理的CPU线程池中执行,从而可以在后台线程上完成工作或跨多个内核并行化。使用光线跟踪,这可以用于光线跟踪管道编译或基于CPU的加速结构构造。
VK_KHR_pipeline_library提供了一组可以链接到管道的着色器的功能。使用光线跟踪可以在增量构建光线跟踪管道时使用。

与VK_KHR_ray_tracing扩展一起使用的着色器作为使用两个新SPIR-V扩展的SPIR-V二进制文件提供给API:

  • SPV_KHR_ray_tracing 添加了对光线跟踪shader阶段和指令的支持
  • SPV_KHR_ray_query 添加了对光线查询shader指令的支持。

开发人员可以使用GLSL或HLSL生成这些二进制文件。对于GLSL,有两个新的GLSL扩展:GLSL_EXT_ray_tracing和GLSL_EXT_ray_query。

HLSL支持也通过DXC(微软的开源HLSL编译器)提供,它允许Vulkan光线跟踪着色器使用微软定义的语法在HLSL中编写,只需稍加修改。

本文档的以下部分将详细介绍光线跟踪功能,包括创建和使用加速结构、主机和延迟操作、光线遍历、光线跟踪管道和光线查询。

1.2 加速结构(Acceleration Structure)

为了在复杂的场景中获得高性能,光线跟踪针对在场景信息上构建的优化数据结构(称为加速结构(Acceleration Structure-AS))执行光线相交。加速结构分为两个层次,如下图所示。

  • 相对更低的一层,bottom-level加速结构,包含组成场景的自定义几何体的三角形或轴对齐边界框(AABBs)。由于每个底层加速结构可能对应于光栅化管道中的多个绘制调用,因此每个底层构建可以采用给定类型的多组几何体。
  • 上层结构,top-level加速结构,包含对一组底层加速结构的引用,每个引用包括该引用的着色和变换信息。

建立任何一种加速结构都会在内存中产生不透明的、特定于实现的格式数据。bottom-level加速结构仅被top-level加速结构引用从而被使用,而top-level加速结构是可以被着色器作为描述符绑定的方式来进行访问。

使用vkCreateAccelerationStructureKHR创建加速结构,与Vulkan中的其他对象一样,加速结构的创建仅定义了加速结构的“形状”,必须使用vkBindAccelerationStructureMemoryKHR将内存分配并绑定到加速结构,然后才能进一步使用。不支持稀疏或专用分配。除了查询加速结构分配本身的内存需求之外,vkGetAccelerationStructureMemoryRequirementsKHR还返回在构建和更新过程中所需的辅助缓冲区的大小。

使用vk {Cmd} BuildAccelerationStructureKHR来执行构建。对于bottom-level加速结构,三角形的顶点数据或AABB的范围信息是从缓冲区中提取的。top-level加速结构从缓冲区的结构中提取每个实例的阴影,变换和参考信息。使用具有特殊标志的相同功能执行对加速度结构的更新,以指示需要从现有加速度结构更新位置。

由于加速结构存储器采用特定于实现的不透明格式,因此存在一组对加速结构数据执行操作的函数:vk {Cmd} CopyAccelerationStructureKHR,vk {Cmd} CopyAccelerationStructureToMemoryKHR和vk {Cmd} CopyMemoryToAccelerationStructureKHR。

除了基本的copy操作之外,这些功能还可以执行受限形式的序列化和反序列化,以保存和恢复具有特定版本兼容性要求的加速结构。

加速结构最终可能会占用比它本身所需空间更多的空间,因此对于大型静态加速结构,减少最终使用的空间量可能是有益的。应用程序可以使用vk {Cmd} WriteAccelerationStructuresPropertiesKHR查询最终的压缩大小,然后使用vk {Cmd} CopyAccelerationStructureKHR来压缩加速结构。

1.3 Host Operations(主机端操作-CPU端)

Acceleration Structure(加速结构)是非常大的资源,管理它们需要大量的处理工作。 与其他渲染工作一起在设备上安排这项工作可能很棘手,特别是在需要主机Host干预的情况下。 Vulkan提供了加速结构操作的主机Host和设备Device变量,使应用程序可以更好地调度这些工作负载。 设备变量-Device Variants(vkCmdAccelerationStructureKHR)放入命令缓冲区并在设备时间轴上执行,而主机变量-Host Variants(vkAccelerationStructureKHR)直接在主机时间轴上执行。

1.4 Deferred Operations(延迟操作)

在CPU上执行加速结构(Acceleration Structure)的构建和更新是相对容易并行化的工作量,我们希望能够在Vulkan中利用它。 应用程序可以在独立的线程上执行独立的命令,但是这种方法要求有足够的命令来充分利用计算机。 这也可能导致负载不平衡,因为某些命令可能要比其他命令花费更长的时间。

为了避免这些麻烦,我们添加了Deferred Operations(延迟操作)以启用命令内的并行性:将单个命令的工作分散到多个CPU内核上。 驱动程序管理的线程池是实现此目的的一种方法,但与Vulkan的低级显式原理不符。 应用程序还运行它们自己的线程池,而且,启用这些线程来执行工作也是一种推荐方案,从而应用程序可以管理驱动程序工作的执行以及其余的负载。

延迟的主机操作是围绕“分工”原则设计的。 应用程序负责的部分如下:

  • 将Commands准备好,并请求延迟执行;

  • 分配工作线程以执行延迟命令;

  • 通过选择要执行的任务以及何时执行这些任务来设置合适的优先级和CPU资源规划;

驱动程序部分负责:

  • 跟踪延迟命令的执行状态;
  • 无论选择哪一种最适合工作负载的并行构造(任务,并行循环,依赖关系图,工作队列等),由驱动程序来实现分布式执行;

这样,应用程序可以控制工作的分配和优先级,但是驱动程序可以管理底层细节。

为了使用延迟操作,应用程序首先构造一个VkDeferredOperationKHR对象,该对象封装了延迟命令的执行状态。 该对象在其整个生命周期中将处于两种状态(“完成”或“待处理”)之一,如下图(延迟操作的状态图)所示。

延迟操作在被构建的时候,是一个"Complete"状态。应用程序通过将新的扩展结构附加到命令参数结构的pNext指针上,从而发出对命令的延迟请求。如果驱动能够支持这个deferred请求,则deferred操作将转换为“Pending”状态。请注意,驱动程序可以随意拒绝该请求,而只需在适当位置执行该命令,即可立即完成该命令。

一旦这个命令被延迟执行后,操作是不会被执行的,直到应用程序通过调用vkDeferredOperationJoinKHR分配线程资源给到这个命令。"join"命令告诉驱动程序使用分配的线程来处理与延迟操作关联在一起的命令。应用程序可以将任意数量的线程加入到延迟的操作中,这样做通常会使命令更快地完成。如果分配的线程中,有一个线程在vkDeferredOperationJoinKHR的调用返回值为VK_SUCCESS时,就说明该操作已经是处于”Complete”状态。

请注意,如果有多个线程加入了延迟操作,当驱动了解到不需要这么多线程时,后加入的线程是可以提早返回的。

1.4.1 Case 1:简化版的压缩技术 (Simplified Compact)

压缩对于减少光线跟踪加速结构的内存占用是非常重要的优化。创建具有压缩的加速结构的过程,如下所示:

  1. 确定加速结构在最坏情况下的内存需求;
  2. 分配设备内存(这个就是在GPU上的内存)
  3. 建立加速结构
  4. 确定压缩的大小
  5. 与GPU同步
  6. 分配设备内存
  7. 执行压缩Copy

为了为紧凑的加速结构分配内存,应用程序需要知道其大小。要确定大小,它需要为步骤3和4提交命令缓冲区,并等待其完成。

这个细节使警报铃响在经验丰富的引擎开发人员的脑海中。如果天真地做,这种主机/设备握手会严重降低性能。如果做得好,这将成为复杂性的重要来源,并且可能导致应用程序的设备内存占用量激增,因为紧凑的加速结构需要在设备内存中至少保留一帧。

在Host上构建加速结构使我们可以消除这两个缺点。在Host上构建,我们可以通过在主机上执行初始构建,然后执行从主机内存到设备内存的压缩副本来实现压缩。此副本仍需要监视,以便应用程序可以恢复主机内存,但这是一种更为熟悉的模式,引擎已经实现了这种模式,将纹理和几何数据上传到设备的时候,都是采用类似的方式来处理的。

1.4.1 Case 2:负载均衡(Load Balancing)

在Host端来构建加速结构可通过利用闲置的CPU来提高性能。 假定游戏中的配置文件如下图所示(负载平衡:无主机构建):

在图中,加速结构的构造和更新是在设备(Device)上实现的,但是该应用程序有大量的可用CPU时间。 将这些操作移至主机后,CPU便可以与上一帧渲染并行执行下一帧的加速结构工作。 即使CPU需要更多的时钟时间来执行相同的任务,这也可以提高吞吐量,如下图所示(负载平衡:启用主机构建)。

1.5 光线遍历(Ray Traversal)

在Vulkan中针对加速结构跟踪射线要经历多个逻辑阶段,从而为如何跟踪射线提供了一定的灵活性。最初仅根据其几何特性找到候选相交-沿射线与加速结构中描述的几何对象是否存在相交?

交汇点测试在Vulkan中是水密的-意味着对于加速结构中描述的单个几何对象,光线无法通过三角形之间的间隙泄漏,并且无法报告同一位置处不同三角形的多次碰撞。这不能保证碰巧邻接的相邻对象,但这意味着单个模型中不会有孔,也不会发生过度着色的情况。

一旦找到候选者,便会在确认交集之前进行一系列剔除操作。这些剔除操作基于用于遍历的标记和加速结构的属性来丢弃候选对象,具体的细节请参考详细的规范。剩余的不透明三角形候选对象被确认为有效交点;而AABB和非透明三角形需要着色器代码以编程方式确定是否发生了击中。

遍历一直进行到找到所有可能的候选对象并被确认或丢弃,然后确定最接近的命中为止。遍历也可以尽早结束以避免不必要的处理。这对于检测遮挡或在某些情况下优化可能很有用。

可以通过Vulkan中的两种机制之一来跟踪光线并获得遍历结果:

  • Ray Queries可以在任何着色器阶段直接访问射线遍历逻辑,从而可以将它们插入现有的着色器中,并增强这些着色器所表达的效果。
  • 光线跟踪管线提供了带有动态着色器选择的专用光线跟踪机制,从而为场景和可编程交叉逻辑中使用的材质提供了极大的灵活性。

射线追踪管道和射线查询如下图所示:

二、Vulkan Ray Tracing API 详述

Vulkan API 中对光追提供了一下拓展支持。

  • VK_KHR_acceleration_structure

  • VK_KHR_ray_tracing_pipeline

  • VK_KHR_ray_query

  • VK_KHR_pipeline_library

  • VK_KHR_deferred_host_operations

额外的 SPIR-V 和 GLSL 扩展还为着色器提供了必要的可编程功能:

  • SPV_KHR_ray_tracing

  • SPV_KHR_ray_query

  • GLSL_EXT_ray_tracing

  • GLSL_EXT_ray_query

  • GLSL_EXT_ray_flags_primitive_culling

2.1 VK_KHR_acceleration_structure

加速结构是光线追踪中为了加速光线求交对几何对象进行的一种场景组织形式(可参照:【光线追踪系列十】光追加速结构(BVH树))。通过将对象构建到加速结构中,可以针对已知的数据布局以高效的方式执行光线追踪。VK_KHR_acceleration_structure扩展引入了构建和复制加速结构的功能,以及支持内存序列化的功能。

光线管道 ( VK_KHR_ray_tracing_pipeline) 和光线查询 ( VK_KHR_ray_query)都需要加速结构。

创建加速结构,需要执行以下的步骤:

  1. 创建并对结构体VkAccelerationStructureBuildGeometryInfoKHR赋值:加速结构类型、几何类型、计数和最大尺寸填充实例。此时不需要填充几何数据。
  2. 调用vkGetAccelerationStructureBuildSizesKHR以获取执行构建的内存大小要求。
  3. 分配足够大小的缓冲区来容纳加速结构 ( VkAccelerationStructureBuildSizesKHR::accelerationStructureSize), 并构建临时缓冲区 ( VkAccelerationStructureBuildSizesKHR::buildScratchSize)。
  4. 调用vkCreateAccelerationStructureKHR以在缓冲区内的指定位置创建加速结构。
  5. 调用vkCmdBuildAccelerationStructuresKHR以构建加速结构。之前填充的VkAccelerationStructureBuildGeometryInfoKHR应该在这里用作参数,以及目标加速结构对象、构建暂存缓冲区和几何数据指针(用于顶点、索引和变换)。

2.2 VK_KHR_ray_tracing_pipeline

VK_KHR_ray_tracing_pipeline扩展引入了光线追踪管道。这种新形式的渲染管线独立于传统的光栅化管线。光线追踪管线利用一组专用的着色器阶段,不同于传统的顶点/几何/片段着色器。光线追踪管道还利用专用命令来提交渲染工作(vkCmdTraceRaysKHR和vkCmdTraceRaysIndirectKHR)。这些命令与传统光栅化管道(vkCmdDraw和vkCmdDrawIndirect)中的绘图命令类似。

使用追踪光线:

  1. 使用vkCmdBindPipelinewith绑定光线追踪管道VK_PIPELINE_BIND_POINT_RAY_TRACING_KHR
  2. 调用vkCmdTraceRaysKHR或vkCmdTraceRaysIndirectKHR

光线追踪管道引入了几个新的着色器域。这些描述如下:

如上图,光追着色器主要的运行步骤分为一下几步:

  1. 光线生成着色器代表光线追踪的起点。光线追踪命令(vkCmdTraceRaysKHR和vkCmdTraceRaysIndirectKHR)启动一个着色器调用网格,类似于计算着色器。光线生成着色器构造光线并通过调用 traceRayEXT()开始跟踪。此外,它还处理来自命中组的结果。
  2. 当光线与最近的几何体相交时,会执行最近的命中着色器。应用程序可以支持任意数量的最近命中着色器。它们通常用于执行光照计算,并且可以递归地追踪额外的光线。
  3. 当光线在遍历期间不与任何几何体相交时,将执行未命中着色器而不是最近的命中着色器。未命中着色器的常见用途是对环境贴图进行采样。
  4. 内置的相交测试是光线三角形测试。求交着色器允许自定义求交处理。
  5. 与最近命中着色器类似,任何命中着色器在报告交点后执行。不同之处在于,在由 [tmin, tmax]定义的光线间隔中的任何交点而不是最接近光线原点的交点处调用任何命中着色器。any-hit 着色器用于过滤交叉点,因此通常用于实现alpha 测试。

2.3 VK_KHR_ray_query

VK_KHR_ray_query扩展支持跟踪来自所有着色器类型的光线,包括图形、计算和光线跟踪管线。

光线查询要求光线遍历代码明确包含在着色器中。这与光线追踪管道不同,其中光线生成、求交测试和光线几何命中的处理表示为单独的着色器阶段。因此,虽然光线查询允许从更广泛的着色器阶段跟踪光线,但它也限制了 Vulkan 实现可能应用于光线调度和跟踪的优化范围。

该扩展不会引入额外的 API 入口点。它只是为相关的 SPIR-V 和 GLSL 扩展(SPV_KHR_ray_query和 GLSL_EXT_ray_query)提供 API 支持。

提供的功能与提供的功能VK_KHR_ray_query互补VK_KHR_ray_tracing_pipeline,两个扩展可以一起使用。

比如如下代码:

rayQueryEXT rq; rayQueryInitializeEXT(rq, accStruct, gl_RayFlagsNoneEXT, 0 , origin, tMin, direction, tMax); while (rayQueryProceedEXT(rq)) {if (rayQueryGetIntersectionTypeEXT(rq, false) == gl_RayQueryCandidateIntersectionTriangleEXT) {// ... rayQueryConfirmIntersectionEXT(rq); }
} if (rayQueryGetIntersectionTypeEXT(rq, true) == gl_RayQueryCommittedIntersectionNoneEXT) {// ...
}

2.4 VK_KHR_pipeline_library

VK_KHR_pipeline_library主要是介绍管线库。管线库是一种特殊的管线,它可以使用VK_PIPELINE_CREATE_LIBRARY_BIT_KHR 结构体来创建,不能直接绑定和使用。相反,这些管线表示着色器、着色器组和相关状态的集合,可以链接到其他管线。

VK_KHR_pipeline_library没有直接引入任何新的 API 函数,也没有定义如何创建管线库。相反,此功能留给其他使用 VK_KHR_pipeline_library。目前,唯一的例子是VK_KHR_ray_tracing_pipeline。 VK_KHR_pipeline_library被定义为一个单独的扩展,以允许将来在其他扩展中使用相同功能的可能性,而不会引入对光线跟踪扩展的依赖。

创建光线跟踪管线库,需要执行以下操作:

  1. 在VkRayTracingPipelineCreateInfoKHR::flags中赋值VK_PIPELINE_CREATE_LIBRARY_BIT_KHR结构体,之后调用vkCreateRayTracingPipelinesKHR;

要将光线追踪管线库链接到一个完整的管线,需要执行:

  1. 设置VkRayTracingPipelineCreateInfoKHR::pLibraryInfo为指向一个VkPipelineLibraryCreateInfoKHR的实例
  2. 填充VkPipelineLibraryCreateInfoKHR::pLibraries要用作链接输入的管线库,并设置VkPipelineLibraryCreateInfoKHR::libraryCount
    为适当的值

2.5 VK_KHR_deferred_host_operations

VK_KHR_deferred_host_operations引入了一种跨多个线程分配 CPU 任务的机制。不是在 Vulkan 驱动程序中引入线程池,VK_KHR_deferred_host_operations主要是允许应用程序创建和管理线程。

与VK_KHR_pipeline_library一样,VK_KHR_deferred_host_operations被定义为一个单独的扩展,以允许将来在其他扩展中使用相同功能的可能性,而不会仅依赖于对光线跟踪扩展。

只有特别注明支持延迟的操作才可以延迟。目前支持延迟的操作是vkCreateRayTracingPipelinesKHR, vkBuildAccelerationStructuresKHR,vkCopyAccelerationStructureKHR, vkCopyMemoryToAccelerationStructureKHR,和vkCopyAccelerationStructureToMemoryKHR

请求延迟操作,需要执行以下步骤:

  1. 创建并赋值VkDeferredOperationKHR,之后调用创建对象函数vkCreateDeferredOperationKHR
  2. 调用您希望延迟的操作,将VkDeferredOperationKHR 作为参数。
  3. 检查VkResult上述操作返回的:

VK_OPERATION_DEFERRED_KHR 表示操作被成功推迟

VK_OPERATION_NOT_DEFERRED_KHR 表示操作立即成功完成

其他错误值都表示发生了错误

将线程加入延迟操作,并使用 CPU 时间来推进操作:

  1. 调用在每个你想进行延迟操作的线程中调用vkDeferredOperationJoinKHR
  2. 使用vkDeferredOperationJoinKHR函数来检查VkResult结果:

VK_SUCCESS: 表示操作完成
VK_THREAD_DONE_KHR:表示没有更多的工作要分配给调用线程, 但其他线程可能仍有一些额外的工作要完成。当前线程不应尝试通过vkDeferredOperationJoinKHR再次调用来重新加入

VK_THREAD_IDLE_KHR:表示暂时没有工作分配给调用线程,但将来可能会有额外的工作可用。当前线程可能会在调用线程上执行一些其他有用的工作,vkDeferredOperationJoinKHR稍后通过再次调用重新加入可能会证明是有益的

操作完成后(vkDeferredOperationJoinKHR即已返回 VK_SUCCESS),调用vkGetDeferredOperationResultKHR以获取操作结果。

三、Vulkan光线追踪相关管线

3.1 光线追踪管线

应用程序可以将特定的着色器与场景中的对象相关联,为这些对象定义诸如材质参数和相交逻辑之类的东西。随着遍历的进行,当光线与对象相交时,实现将自动执行关联的着色器(如下图所示)。

光线跟踪管道与Vulkan中的图形管道相似,但具有增加的功能,可以管理更多的着色器,并将对特定着色器的引用存储到内存中。

使用vkCmdTraceRaysKHR和当前绑定的射线跟踪管道启动射线跟踪管道工作。该命令将调用一组应用程序定义的射线生成线程,这些线程可以从着色器调用traceRaysEXT(),从而开始在指定的加速结构上进行遍历。在遍历期间,如果跟踪和加速结构需要,则相交处的应用程序着色器代码和任何命中着色器都可以控制遍历的方式。遍历完成后,将调用未命中或最接近的命中着色器。

可以使用相同的着色器选择机制来调用可调用着色器,但是要在直接遍历上下文之外。

不同的着色器阶段可以使用所有遍历阶段之间的射线有效载荷结构和遍历控制着色器的射线属性结构来传递参数和结果。

为了使遍历阶段能够知道在给定的遍历步骤之后要调用哪个着色器以控制或响应遍历,该实现使用着色器绑定表。每个着色器条目都包括从实现中查询给定着色器组的着色器组句柄,以及可选的着色器缓冲区记录,应用程序可将其用于实例特定的数据,例如缓冲区设备地址或描述符索引。遍历通过对跟踪射线API调用的参数,对traceRayEXT着色器调用的参数以及存储在加速结构中的信息的组合,通过遍历计算出任何给定着色器的地址。

可以与其他管道类型一样直接创建光线跟踪管道,但是由于光线跟踪管道可以比其他管道类型具有更多数量级的着色器,我们可能要添加着色器,因此扩展添加了另一种机制:管道库(Pipeline libraries)。管道库是一个包括状态和着色器以及其他标志的管道,用来表示那些我们不打算直接绑定到API,而是打算用作要包含在以后的管道中使用的库。管线库可用于多个光线跟踪管线,从而允许在多个管线中重复使用着色器编译。光线跟踪管道创建可能包括创建过程中的一组管道库管道以及一组射线跟踪着色器。每个着色器的所有编译状态必须匹配才能创建兼容的最终管道。除了管道库之外,可以在射线管道构造中使用延迟的主机操作以实现进一步的并行化。

请注意,尽管管道库是作为单独的扩展公开的,但它们仅在当前集成在一起才能与射线跟踪管道一起使用。

Ray Pipeline Shaders (GLSL)示例

// Ray generation shader 射线生成的shader
#version 460 core
#extension GL_EXT_ray_tracing : enable
layout(location = 0) rayPayloadEXT vec4 payload;
layout(binding = 0, set = 0) uniform accelerationStructureEXT acc;
layout(binding = 1, rgba32f) uniform image2D img;
layout(binding = 1, set = 0) uniform rayParams
{vec3 rayOrigin;vec3 rayDir;uint sbtOffset;uint sbtStride;uint missIndex;
};
void main() {traceRayEXT(acc, gl_RayFlagsOpaqueEXT, 0xff, sbtOffset,sbtStride, missIndex, rayOrigin, 0.0,computeDir(rayDir, gl_LaunchIDEXT, gl_LaunchSizeEXT),100.0f, 0 /* payload */);imgColor = payload + vec4(blendColor) ;imageStore(img, ivec2(gl_LaunchIDEXT), payload);
}// Closest hit shader
#version 460 core
#extension GL_EXT_ray_tracing : enable
layout(location = 0) rayPayloadInEXT vec4 payload;void main() {payload = vec4(0.0, 1.0, 0.0, 1.0);
}// Miss shader
#version 460 core
#extension GL_EXT_ray_tracing : enable
layout(location = 0) rayPayloadInEXT vec4 payload;void main() {payload = vec4(0.0, 0.0, 0.0, 0.0);
}

3.2 Ray Queries(射线查询)

射线查询可用于执行射线遍历并在任何着色器阶段将结果返回。 除了需要加速结构外,仅使用一组新的着色器指令执行射线查询。

射线查询使用加速结构进行初始化,以进行查询,确定遍历属性的射线标志,剔除蒙版以及所跟踪射线的几何描述。

遍历期间,着色器可以访问潜在和已确定的相交的属性以及ray查询本身的属性,从而可以基于要相交的几何图形,如何相交以及在何处进行复杂的决策,如下图:

Ray Query Example (GLSL)

以下是GLSL中射线查询的不完整示例,说明了着色器如何使用射线查询来检测给定位置是否在阴影中。可以将其添加到片段着色器中,以进行光照计算。大多数射线查询的总体结构通常是相似的-初始化,循环执行,然后进行最终确定。

// 可以随便你嵌入到Vertex Shader还是Fragment Shader中。。。
rayQueryEXT rayQuery;
rayQueryInitializeEXT(rayQuery, accelerationStructure,gl_RayFlagsTerminateOnFirstHitEXT,cullMask, origin, tMin, direction, tMax);while(rayQueryProceedEXT(rayQuery)) {if (rayQueryGetIntersectionTypeEXT(rayQuery, false) ==gl_RayQueryCandidateIntersectionTriangleEXT){... // Determine if an opaquetriangle hit occurredif (opaqueHit) rayQueryConfirmIntersectionEXT(rayQuery);}else if (rayQueryGetIntersectionTypeEXT(rayQuery, false) ==gl_RayQueryCandidateIntersectionAABBEXT){... // Determine if an opaque hit occurred in an AABBif (opaqueHit) rayQueryGenerateIntersectionEXT(rayQuery, ...);}
}if (rayQueryGetIntersectionTypeEXT(rayQuery, true) ==gl_RayQueryCommittedIntersectionNoneEXT)
{// Not shadow!
} else {// Shadow!
}

Vulkan_Ray Tracing 01_API基础相关推荐

  1. Vulkan_Ray Tracing 05_光线追踪管线

    本文主要参考NVIDIA Vulkan Ray Tracing Tutorial教程,环境配置与程序均可参照此文档执行(个人水平有限,如有错误请参照原文). 一.光线追踪管线 在光线追踪时,与光栅化不 ...

  2. Vulkan_Ray Tracing 13_Callable Shader

    本文主要参考NVIDIA Vulkan Ray Tracing Tutorial教程,环境配置与程序均可参照此文档执行(个人水平有限,如有错误请参照原文). 一.可调用着色器 可调用着色器可以访问一个 ...

  3. Vulkan_Ray Tracing 11_Intersection Shader(相交着色器)

    本文主要参考NVIDIA Vulkan Ray Tracing Tutorial教程,环境配置与程序均可参照此文档执行(个人水平有限,如有错误请参照原文). 本部分主要展示如何使用相交着色器及不同的材 ...

  4. 轻松掌控全链路服务监控:方案概述与对比 | 真的很干!

    点击上方"搜云库技术团队",选择"设为星标" 回复"1024"或"面试题"获取4T学习资料 0 - 问题背景 随着微服务 ...

  5. 全链路监控细节和难点剖析!

    点击上方蓝色"方志朋",选择"设为星标" 回复"666"获取独家整理的学习资料!原文 | https://www.jianshu.com/p ...

  6. 主流微服务全链路监控系统之战

    点击上方蓝色"方志朋",选择"设为星标"回复"666"获取独家整理的学习资料!问题背景随着微服务架构的流行,服务按照不同的维度进行拆分,一次 ...

  7. 实现一个全链路监控平台很难吗?Pinpoint、skywalking、zipkin,哪个实现比较好?...

    点击上方蓝色"方志朋",选择"设为星标"回复"666"获取独家整理的学习资料! 随着微服务架构的流行,服务按照不同的维度进行拆分,一次请求往 ...

  8. 实现一个全链路监控平台很难吗?一点都不难。。。

    0 问题背景 随着微服务架构的流行,服务按照不同的维度进行拆分,一次请求往往需要涉及到多个服务.互联网应用构建在不同的软件模块集上,这些软件模块,有可能是由不同的团队开发.可能使用不同的编程语言来实现 ...

  9. 一文搞懂全链路监控:方案概述与比较!

    作者:陶邦仁 https://www.jianshu.com/p/92a12de11f18 0 - 问题背景 随着微服务架构的流行,服务按照不同的维度进行拆分,一次请求往往需要涉及到多个服务.互联网应 ...

  10. 轻松掌控全链路监控:方案概述与对比 | 真的很干!

    点击上方"朱小厮的博客",选择"设为星标" 回复"资料"获取新整理的1TB资料 来源:http://uee.me/ba8Mw 0 - 问题背 ...

最新文章

  1. 阿里云HBase全新发布X-Pack NoSQL数据库再上新台阶
  2. 如何修改Linux主机名
  3. pca降维的基本思想_R语言进行PCA分析
  4. Qt捕捉窗口关闭事件
  5. 洛谷 P3063 [USACO12DEC]牛奶的路由Milk Routing
  6. 活动预约报名小程序已优化点与待优化点
  7. html展示base64有长度限制,网页上的base64码太长?科普base64究竟是啥
  8. 网易微专业高级前端开发工程师2022
  9. 嵌入式设备的容器化App
  10. 一寸照纯红色底图片_一寸照纯红色底图片
  11. 【GANs】Generative Adversarial Nets
  12. 三、实战---爬取百度指定词条所对应的结果页面(一个简单的页面采集器)
  13. MATLAB中实现特定像素区域处理
  14. C. Edgy Trees
  15. dockers 安装 awvs
  16. 恭喜民兴商学院黄一老师荣获资深金融经济讲师资格证书!
  17. 代码思路分享 计算机毕业设计Python+Hadoop+Spark+Hive旅游可视化 旅游数据分析 数据仓库 旅游推荐系统 旅游大数据 大数据毕业设计 大数据毕设
  18. 几个常用普通文件上传空间
  19. 解析数据分析中的SAS
  20. linux服务器改gpt模式,做一个lvm反复安装时变成了GPT格式,我想把它重新格式化成MBR的怎么做?...

热门文章

  1. 极化SAR图像四成分分解
  2. Cisco 交换机的操作
  3. 航空摄影与正射摄影的区别
  4. 百度大脑人脸情绪实时识别攻略
  5. 微信开通检测 检测号码是否开通微信
  6. ltp install
  7. Android 快递接口
  8. 疫情过后,制造业中小企业应用工业互联网数字化转型之路的探讨
  9. CF838D Airplane Arrangements
  10. 微信小程序 富文本编辑器 editor