资讯动态

DirectX 12光线追踪实战:DXR加速结构与降噪优化指南

发布时间:2026/10/14 1:17:58 来源:尧图企业网站定制
1. 光线追踪到底解决了渲染里的哪些老问题1.1 从光栅化到光线追踪的底层逻辑切换做实时渲染的人都知道过去二十多年我们一直在用光栅化管线。它的核心思路是把三维场景里的三角形投影到屏幕上然后逐像素判断覆盖关系、采样纹理、计算光照。这套流程快是真快但它有个天生的短板它只关心“这个像素被哪个三角形盖住了”而不关心“这个像素背后的世界长什么样”。所以反射、折射、全局光照这些效果传统上只能靠各种贴图技巧去“骗”眼睛。我举个最典型的例子。你在一个光滑地板上放一面镜子光栅化管线要表现镜面反射通常得额外渲染一遍场景把摄像机镜像到地板下方再把结果当作纹理贴回地板表面。这个做法叫平面反射效果凑合但有几个硬伤只能处理平面曲面反射基本没戏每多一个反射面就多一遍场景渲染开销线性增长反射里看不到反射也就是没有多次弹射。光线追踪换了个思路。它从摄像机出发对每个像素发射一条光线去和场景里的几何体求交。命中之后根据材质决定是继续弹射、还是采样光源、还是终止。这个“继续弹射”的能力就是它能天然处理多次反射、折射、软阴影的原因。DirectX RaytracingDXR把这套能力做进了GPU管线里让我们可以在实时帧率下跑光线追踪。1.2 DXR在DirectX 12里的定位与能力边界DXR不是另起炉灶的一套API它是DirectX 12的一个扩展。你可以把它理解成在原有的命令列表、资源绑定、管线状态体系里新增了几种专门给光线追踪用的对象和着色器阶段。核心新增的东西包括加速结构Acceleration Structure、光线生成着色器、命中着色器、未命中着色器、以及光线追踪管线状态对象。这里要特别说清楚一个边界DXR本身不负责“把画面变好看”它只负责“高效地做光线和几何体的求交”。画面好不好看取决于你在命中着色器里写了什么光照模型、弹射几次、怎么采样。很多人第一次接触DXR会误以为开了它画面就自动变电影级实际上你如果命中着色器里只返回一个固定颜色那画面就是一片纯色。所以真正的工作量在着色器逻辑和降噪上API只是提供了基础设施。1.3 为什么现在值得投入精力做DXR从硬件层面看支持DXR的显卡已经覆盖了相当广的价位段不再是旗舰专属。从工具链层面看PIX、RenderDoc这些调试工具对光线追踪的支持也越来越成熟排查问题比早期舒服太多。从内容层面看玩家对画面质量的预期在提升纯光栅化的画面在反射和阴影上已经很难再有质的突破。我个人的判断是如果你在做写实风格的实时渲染项目光线追踪带来的反射和阴影质量提升是那种“一眼就能看出来”的差异。尤其是室内场景、水面、金属材质密集的场景收益非常明显。而如果你做的是卡通渲染或者低多边形风格那DXR的优先级可以往后放因为这类风格本身就不追求物理正确的光照。2. 加速结构光线追踪的性能地基2.1 两级加速结构的设计意图光线追踪最怕的就是“每条光线都和所有三角形求交”。一个中等规模的场景几十万三角形一帧几百万像素每条光线都遍历一遍算力再强也扛不住。加速结构就是用来做空间划分、快速剔除的。DXR用的是两级结构底层加速结构BLAS和顶层加速结构TLAS。BLAS描述的是单个模型内部的三角形分布。比如一个角色模型、一把椅子、一块地形各自构建一个BLAS。BLAS构建完之后是可以复用的只要模型本身的顶点数据不变就不需要重建。TLAS描述的是场景里所有实例的摆放关系每个实例引用一个BLAS并带一个变换矩阵。你移动一个物体只需要更新TLAS里对应实例的变换不用动BLAS。这个设计的好处非常直接场景里如果有大量重复物体比如一片森林里的树、一条街上的路灯它们的BLAS只需要建一次TLAS里放多个实例引用同一个BLAS就行。显存占用和构建时间都能省下来。2.2 构建参数怎么选性能与质量的权衡构建加速结构的时候有几个参数需要你根据场景特点去调。第一个是构建方式分快速构建和快速追踪两种。快速构建优先保证构建速度生成的树质量一般追踪时剔除效率低一些快速追踪优先保证树的质量构建慢但追踪快。怎么选看你的场景是静态为主还是动态为主。静态场景比如建筑漫游、固定关卡用快速追踪一次构建多次受益。动态场景比如每帧都在变形的角色、破碎的物体用快速构建因为你要频繁重建BLAS构建速度比追踪效率更重要。我实测过一个场景快速追踪相比快速构建追踪性能大概能提升百分之十五到二十但构建时间可能翻倍。所以这个取舍要看你的帧预算花在哪。第二个参数是允许的三角形数量上限和是否允许更新。如果你的模型顶点数会变比如布料模拟、顶点动画那BLAS需要允许更新构建时要带上相应的标志位。但更新比重建慢如果变化幅度大不如直接重建。2.3 实例化与变换更新的实操细节TLAS的实例更新是每帧都可能发生的操作。这里有个容易踩的坑很多人以为更新TLAS实例就是改个矩阵实际上你需要重新构建TLAS只是构建时引用的BLAS不用重建。DXR提供了更新实例的接口但底层仍然是一次TLAS的构建过程只是比全量重建快。另一个细节是实例的可见性掩码和命中组。可见性掩码可以控制某条光线是否与某个实例求交这在做阴影光线时特别有用。比如你想让某些物体不投射阴影就可以在阴影光线的实例掩码里把它排除掉省去求交开销。命中组则决定了命中这个实例时调用哪个命中着色器不同材质走不同的着色逻辑。注意BLAS和TLAS的构建都需要在GPU上分配显存而且对对齐有要求。构建前一定要查清楚当前硬件对加速结构缓冲区对齐的具体数值对齐错了会直接导致构建失败或者追踪结果异常这个坑我踩过排查了大半天。3. 着色器体系光线在管线里怎么流动3.1 光线生成、命中、未命中三者的协作DXR的着色器执行模型和传统光栅化很不一样。传统管线是顶点着色器、像素着色器这样按阶段顺序走。光线追踪这边入口是光线生成着色器它负责决定“从哪发射光线、往哪个方向发射、携带什么载荷数据”。你可以把它理解成光栅化里的像素着色器只不过它每个线程处理的是一个像素或者一个采样点。光线发射出去之后会和加速结构求交。如果命中了某个三角形就调用该三角形所属实例绑定的命中着色器。命中着色器里你能拿到命中距离、重心坐标、三角形索引、实例索引这些信息然后根据材质计算颜色、决定是否继续弹射。如果没有命中任何东西就调用未命中着色器通常用来采样环境贴图或者返回天空颜色。这里的关键点是光线弹射不是自动的是你在命中着色器里手动调用TraceRay发出去的。这意味着你可以精确控制弹射次数、弹射方向、以及每次弹射携带什么数据。这个灵活性是DXR强大的地方也是容易写错的地方。弹射次数控制不好要么画面噪点多要么性能崩掉。3.2 载荷与属性的数据传递光线在弹射过程中需要携带数据比如当前累积的颜色、剩余的弹射次数、随机种子等。这些数据通过载荷Payload结构传递。载荷是在光线生成着色器里定义并初始化的命中着色器和未命中着色器都可以读写它。属性Attribute结构则是命中着色器特有的输入包含重心坐标和三角形几何信息。我建议把载荷结构设计得尽量紧凑。因为载荷是在寄存器里传递的太大就会溢出到本地内存性能下降明显。我见过有人把整个材质参数结构体塞进载荷结果追踪性能直接腰斩。正确的做法是载荷里只放必要的累积量材质参数通过实例索引去常量缓冲区或者描述符表里查。3.3 递归深度与性能的平衡光线弹射深度是影响画质和性能最直接的参数。弹射一次只能处理直接光照和一次反射。弹射两次能处理反射里的反射。弹射三次以上全局光照的间接效果才比较完整。但每多一次弹射光线数量是指数级增长的。我的经验是实时渲染里反射弹射两到三次基本够用再往上收益递减得厉害。阴影光线通常只弹射一次因为阴影不需要多次弹射。全局光照的间接光弹射可以配合降噪器用较低弹射次数加时间累积来逼近高质量结果。不要盲目追求高弹射次数先把降噪做好低弹射次数也能出好画面。4. 降噪让噪点画面变得可用的关键一环4.1 为什么光线追踪必须配降噪光线追踪出来的原始画面如果每像素只发射少量光线噪点会非常严重。这是因为蒙特卡洛积分本身是随机采样采样数不够的时候方差很大。你不可能在实时帧率下每像素发射几百条光线所以必须用降噪算法把少量光线的结果“猜”成干净画面。降噪的本质是利用空间邻域和时间历史信息对当前帧的噪声结果做滤波。空间降噪看相邻像素时间降噪看前一帧的对应像素。两者结合就能用每像素一两条光线的成本得到接近每像素几十条光线的画质。这个技术路线在实时渲染里已经是标配了。4.2 时间累积与运动向量的配合时间降噪的核心是运动向量。你需要知道当前帧的像素在上一帧对应哪个位置才能把历史信息正确地重投影过来。运动向量通常由引擎在渲染几何体时生成包含摄像机和物体的运动。如果运动向量不对时间降噪就会产生拖影或者闪烁。我踩过的一个坑是透明物体和粒子的运动向量处理。这些物体往往不写入运动向量缓冲区导致降噪时历史信息对不上画面出现鬼影。解决办法是在降噪的拒绝逻辑里对这类区域加大空间降噪的权重减少时间历史的依赖。或者干脆给它们单独做一套降噪参数。4.3 降噪器的选型与参数调优降噪器可以自己写也可以用现成的方案。自己写的话通常基于联合双边滤波或者SVGFSpatio-Temporal Variance Guided Filter这类算法。用现成方案的话各家硬件厂商和引擎都有提供。选型的时候重点看几个指标对运动向量的依赖程度、对透明物体的处理、以及性能开销。参数调优方面最关键的几个是空间滤波核大小、时间累积帧数上限、以及方差引导的阈值。空间核太大画面会糊太小噪点去不干净。时间累积帧数太多运动物体会有拖影。方差引导阈值决定了滤波在哪些区域更激进通常平坦区域可以激进一些边缘区域要保守。这些参数没有万能值得根据你的场景和光照条件去试。5. 混合渲染光栅化与光线追踪怎么分工5.1 哪些效果交给光线追踪最划算全场景光线追踪在实时渲染里仍然太贵所以主流做法是混合渲染光栅化负责主要可见性光线追踪负责那些光栅化做不好的效果。那哪些效果最值得交给光线追踪我的排序是反射、阴影、环境光遮蔽、全局光照。反射排第一因为光栅化的反射方案限制太多而光线追踪反射质量提升最直观。阴影排第二尤其是大面积软阴影和接触阴影光线追踪能做出非常自然的效果。环境光遮蔽排第三它本质上是短距离的光线追踪开销相对小。全局光照排最后因为它的弹射次数要求高降噪压力大通常放在管线最后做补充。5.2 光线追踪反射的实现要点光线追踪反射的实现思路是在光栅化渲染完G-Buffer之后对需要反射的像素发射反射光线。反射方向由摄像机到像素的向量和像素法线计算得出。光线命中场景后取命中点的着色结果作为反射颜色。如果反射光线没命中就采样环境贴图。这里有个细节反射光线的起点要沿法线偏移一点避免自相交。偏移量太小会出噪点太大会漏掉近距离的反射细节。我一般用像素世界坐标加上法线乘以一个跟距离相关的系数近距离偏移小远距离偏移大。另外粗糙表面的反射需要发射多条光线做抖动然后降噪否则反射会像镜子一样锐利不符合材质表现。5.3 光线追踪阴影的优化技巧阴影光线的做法是从着色点向光源发射一条光线如果中途被遮挡就是阴影否则就是受光。听起来简单但优化空间很大。第一个技巧是阴影光线的起点也要偏移避免自阴影噪点。第二个技巧是使用任意命中着色器阴影光线只关心“有没有命中”不关心“命中了什么”所以可以用更轻量的任意命中着色器命中即返回不执行完整着色逻辑。第三个技巧是光源采样。对于面光源阴影光线要射向光源上的随机点这样出来的阴影才有半影效果。采样点数量决定了阴影的软硬程度和噪点水平。我通常用两到四个采样点配合时间降噪效果和性能比较平衡。第四个技巧是阴影光线的距离限制超过光源距离的命中直接忽略减少无效求交。6. 性能分析与常见瓶颈排查6.1 用调试工具定位光线追踪开销光线追踪的性能问题比光栅化更难定位因为它涉及加速结构遍历、着色器执行、降噪等多个环节。我常用的工具是PIX和RenderDoc。PIX对DXR的支持比较完整能看到每条光线的弹射次数分布、加速结构遍历的耗时、以及各个着色器的执行时间。一个实用的排查思路是先把降噪关掉看原始光线追踪的耗时。如果原始耗时就已经很高那问题在加速结构或者着色器逻辑。如果原始耗时正常开了降噪才卡那问题在降噪器。然后再细分把反射、阴影、全局光照逐个关掉看哪个环节是大头。这个二分排查法能快速缩小范围。6.2 加速结构构建与更新的开销控制加速结构构建是容易被忽视的性能黑洞。尤其是动态场景如果每帧重建所有BLAS开销会非常大。优化方向有几个一是尽量复用BLAS只有顶点数据变了才重建二是对于形变物体考虑用允许更新的BLAS而不是重建三是控制TLAS的实例数量太多实例会让TLAS构建和遍历都变慢。还有一个细节是构建的时机。加速结构构建是GPU操作可以和渲染命令并行。如果你能在上一帧的末尾就把下一帧需要的加速结构构建好就能隐藏掉这部分开销。这需要你对场景的更新频率有清晰的规划不是所有物体都需要每帧更新。6.3 光线发散与缓存效率光线发散是指同一组光线方向差异很大导致GPU的缓存命中率下降。在光线追踪里光线发散会显著影响性能因为加速结构遍历和纹理采样都依赖缓存。减少发散的方法包括按材质或者按区域对光线排序、使用更紧凑的加速结构、以及控制弹射方向的范围。我实测过一个场景把反射光线的方向按半球区域做排序后再发射追踪性能提升了大概百分之十。这个优化在反射粗糙度低的时候效果更明显因为方向集中。粗糙度高的时候光线本来就散排序收益有限。所以这个优化要看你的材质分布不是万能药。7. 实操落地一个最小可用的DXR集成流程7.1 环境准备与设备能力查询动手之前先确认你的开发环境和目标硬件支持DXR。在代码里你需要查询设备的DXR支持等级通常分一级和二级。一级支持基本的加速结构和光线追踪管线二级增加了允许更新的BLAS等特性。查询到支持之后才能创建DXR相关的设备和命令队列。开发环境方面Windows SDK和显卡驱动都要更新到较新的版本。调试工具建议装PIX它对DXR的调试支持最完善。编译的时候注意着色器模型要选6.3以上因为DXR的着色器阶段是6.3引入的。如果你的项目还在用更老的着色器模型需要先升级。7.2 加速结构构建的代码骨架构建BLAS的大致流程是准备三角形的顶点缓冲和索引缓冲填写构建描述结构指定三角形数量、顶点格式、是否允许更新等参数然后调用构建接口。构建是异步的需要配合围栏或者事件来同步。构建完成后BLAS就可以被TLAS引用了。TLAS的构建类似但描述的是实例。每个实例包含一个变换矩阵、一个BLAS引用、一个实例ID、一个命中组索引、以及一个可见性掩码。把所有实例填进一个数组然后调用TLAS构建接口。TLAS构建完之后就可以在光线追踪管线里使用了。这里要注意TLAS构建时引用的BLAS必须已经构建完成否则会报错。7.3 光线追踪管线状态对象的创建管线状态对象PSO在DXR里叫光线追踪管线状态对象它比光栅化的PSO复杂一些。你需要指定光线生成着色器、命中着色器组、未命中着色器、以及弹射深度、载荷大小等参数。命中着色器组可以包含多个命中着色器通过命中组索引来区分。创建PSO的时候弹射深度和载荷大小这两个参数要特别小心。弹射深度设小了光线弹到一半就停了画面会缺效果。设大了性能浪费。载荷大小设小了数据放不下会出错。设大了寄存器压力大性能下降。我的建议是先用一个保守的值跑通然后再根据实际需求逐步调整。7.4 每帧的调度与同步每帧的调度顺序大致是更新场景数据、更新TLAS实例、构建或更新加速结构、设置光线追踪管线状态、发射光线、降噪、合成到最终画面。这里面加速结构的更新和光线追踪的发射之间需要同步确保光线追踪用的是最新的加速结构。同步用围栏或者事件都可以关键是不要过度同步导致GPU流水线停顿。我一般把加速结构构建放在帧的开头和上一帧的降噪、合成并行这样能隐藏一部分构建开销。光线追踪的发射放在G-Buffer渲染之后因为反射和阴影需要G-Buffer里的法线和深度信息。8. 常见问题速查与避坑经验8.1 画面异常类问题排查现象可能原因排查方向画面全黑光线生成着色器没发射光线或载荷没写回检查TraceRay调用和载荷赋值反射错位反射方向计算错误或法线空间不对确认法线在世界空间还是切线空间阴影噪点严重阴影光线起点偏移不足或采样数太少加大偏移量增加光源采样画面闪烁时间降噪历史信息对不上检查运动向量和拒绝逻辑加速结构构建失败对齐错误或参数越界核对对齐要求和三角形数量8.2 性能类问题排查性能问题我总结了一个排查顺序先看加速结构构建耗时再看光线追踪着色器耗时最后看降噪耗时。加速结构构建如果超过帧预算的百分之十就要考虑优化构建策略。光线追踪着色器耗时高通常是弹射次数太多或者着色逻辑太重。降噪耗时高可能是滤波核太大或者分辨率太高。还有一个容易被忽视的点是描述符表的绑定。光线追踪需要绑定加速结构、纹理、常量缓冲区等资源如果描述符表切换频繁会有额外开销。尽量把同一批次的光线追踪用到的资源放在同一个描述符表里减少切换。8.3 画质类问题调优画质问题主要集中在噪点、拖影、和细节丢失上。噪点问题优先加采样数和优化降噪参数。拖影问题检查运动向量和降噪的时间累积权重。细节丢失通常是降噪太激进把高频信息滤掉了需要调小空间滤波核或者提高方差引导阈值。我个人的经验是画质调优不要一次调多个参数每次只动一个观察变化。因为降噪参数之间会相互影响一起调很容易迷失方向。另外准备几个典型场景做对比测试比如静态室内、动态角色、水面反射每个场景关注不同的画质维度。提示光线追踪的画质和性能是强耦合的调画质的时候一定要盯着帧时间。有时候画质提升一点点性能掉一大截这种参数就要慎重。9. 后续可扩展的方向9.1 路径追踪的渐进式引入如果你已经把反射和阴影的光线追踪跑通了下一步可以考虑引入路径追踪来做全局光照。路径追踪的思路是让光线在场景里多次弹射每次弹射都根据材质做随机采样最终累积出全局光照效果。实时路径追踪通常配合时间累积和降噪用较低的每帧采样数逐步逼近收敛结果。引入路径追踪的时候建议先从漫反射全局光照做起因为漫反射的弹射方向分布比较均匀噪点相对好处理。镜面反射的路径追踪噪点更集中降噪难度更大。另外路径追踪对加速结构的要求更高因为光线弹射次数多了遍历次数也多了加速结构的质量直接影响性能。9.2 硬件光追单元的深度利用新一代硬件在光线求交上有专门的加速单元这些单元对特定类型的操作有优化。比如有些硬件对轴对齐包围盒的遍历有加速有些对三角形求交有加速。了解你目标硬件的特性在加速结构构建和着色器逻辑上做针对性优化能拿到额外的性能收益。一个具体的做法是根据硬件特性调整加速结构的构建参数。比如某些硬件对宽树的遍历效率更高那构建时就可以调整分支因子。这些参数通常不在文档的显眼位置需要你去查硬件厂商的开发者文档或者做实验测试。9.3 与内容创作管线的配合光线追踪的落地不只是渲染端的事内容创作管线也要配合。比如材质的粗糙度、金属度、法线这些参数在光线追踪下的表现和光栅化下不一样美术需要重新校准。加速结构的构建也影响资产的组织方式比如哪些物体应该合并成一个BLAS哪些应该独立。我建议在项目早期就让美术和渲染程序一起定一套光线追踪友好的资产规范。比如限制单个BLAS的三角形数量、规范实例的命名和分组、统一材质的参数范围。这些规范定得越早后期返工越少。等到项目后期再改成本会高很多。最后分享一个我在实际项目里的小技巧光线追踪的调试不要只盯着最终画面要学会看中间缓冲。把反射缓冲、阴影缓冲、降噪前的原始缓冲都可视化出来很多问题一眼就能看出来。比如反射缓冲里如果有明显的块状伪影那多半是加速结构或者光线发散的问题而不是降噪的问题。这个习惯帮我省了很多排查时间。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑