当前位置: 首页 > 科技观察

超逼真的渲染!虚幻引擎技术专家解读全局光照系统Lumen

时间:2023-03-19 22:35:26 科技观察

实时全局光照(Real-timeGI)一直是计算机图形学的制胜法宝。多年来,业界也提出了多种方法来解决这个问题。常见的方法包括通过利用某些假设来限制问题域,例如静态几何、粗略场景表示或跟踪粗略探针,以及在两者之间插值光照。在虚幻引擎中,全局光照和反射系统Lumen是由KrzysztofNarkowicz和DanielWright创建的一项技术。目标是构建一个不同于以往解决方案的解决方案,能够实现均匀照明和烘焙般的照明质量。最近,在SIGGRAPH2022上,KrzysztofNarkowicz和他的团队谈到了他们打造Lumen技术的历程。软件光线追踪-高度场目前的硬件光线追踪缺乏强大的GPU算力支持。我们不知道硬件光线追踪的速度有多快,或者即使更新的控制台是否支持它。因此,采用了软件光线追踪的方法。事实证明,它确实是一个非常有用的工具,用于缩放或支持具有大量重叠实例的场景。软件光线追踪提供了使用各种追踪结构的可能性,例如三角形、距离场、面元或高度场。在这里,KrzysztofNarkowicz放弃了三角形并简要研究了面元,但更新它们或跟踪面元对于需要相当高的密度来表示的几何图形来说是相当昂贵的。经过初步探索,高度场是最合适的,因为它们可以很好地映射到硬件中并提供表面表示和简单的连续LOD。因为我们可以使用所有的POM算法,比如min-maxquadtree,所以它的跟踪速度非常快。此外,多个高度字段可以表示复杂的几何图形,类似于栅格化边界体积层次结构。将其视为面元的加速结构也很有趣,其中单个纹素是受限于规则网格的面元。Lumen除了heightfield,还有albedo或者lighting等其他属性,这样每次都可以计算出lighting。在Lumen中,开发者将这个完整的decalprojectionwithsurfacedataCards命名为captureposition的意思。光栅化三角形Raymarched卡Raymarched卡(高度场)太慢,无法对场景中的每张卡进行光线步进。因此需要卡加速结构,开发者选择了4节点的BVH。它是为全场景构建的,每一帧都在CPU上并上传到GPU。然后在跟踪着色器中,我们进行基于堆栈的遍历并对节点进行动态排序,以便首先遍历最近的节点。BVHDebugViewCapturePosition这里棘手的部分是如何定位高度场,以便它捕获整个网格。KrzysztofNarkowicz说,“其中一个想法是基于GPU的全局距离场。我们在每一帧跟踪一小组主要光线,以找到未被卡覆盖的光线。接下来,对于每条未发现的光线,我们利用表面梯度遍历全局距离场,确定一个最优的卡片方向和范围生成新卡片。合并场景而不必为每个网格生成一张新卡片来生成卡片。另一方面,在实践中它变得相当挑剔,因为每次移动相机都会产生不同的结果。另一个想法是importthecardspergridasasinglegridstep.通过构建GeometryBVH来做到这一点,其中每个节点将转换为N张卡片。好姿势我遇到问题是因为BVH节点不是放置卡片的良好代理。然后,研究人员想出了另一个想法:遵循UV展开技术,尝试将表面元素聚类。因为要处理数百万个多边形,所以他们将三角形换成了面元。他们还换用了一种约束较少的自由导向卡,以尝试更好地匹配表面。尝试了自由引导卡位置,这对于简单的形状非常有效,但在收敛到更复杂的形状时遇到了问题。最后,Narkowicz切换回轴对齐卡片,但这次是由面元集群和每个网格生成的。独特的性质还使锥体追踪成为可能。锥形跟踪对于降噪非常有效,因为单个预过滤的锥形跟踪代表数千条单独的光线。Raytracedconetraces对于每张卡片,开发人员还存储了完整的预过滤mip-map链表面高度、光照和材料属性。追踪时,根据锥体足迹选择合适的步进射线并对其进行射线追踪。Tracemergesceneswithoutandwithstuckedges表示在软件中追踪大量非相干光线非常慢。理想情况下,可以使用单个全局结构而不是多个高度字段。准确场景表示,可以用更近似的表示代替以获得更快的速度。一个更复杂的场景,有几十张卡片来追踪每条光线第一个成功的方法是实现纯体素锥体追踪,其中整个场景在运行时被体素化,就像经典的“使用体素锥体追踪的交互式间接照明”文章一样。Rasterizedtriangleraysteppers(heightfield)voxelconetracingraystepperscontinuedwithvoxelconetracing这种方法的主要缺点是由于场景几何体的过度混合而导致泄漏,这在跟踪粗略的低级映射时尤其明显.减少图像泄漏的第一种技术是跟踪全局距离场并仅对靠近表面的体素进行采样。在采样过程中,不透明度会随着采样范围的扩大而累积,当停止跟踪时,不透明度会达到1。这样始终在几何体附近进行精确采样,从而达到减少图形泄漏的目的。第二种技术是对网格内部进行体素化。这大大减少了较厚壁处的泄漏,尽管它也会导致一些过度阻塞。其他实验包括跟踪稀疏体素位和每个面具有透明通道的体素。两个实验的目的都是为了解决射线方向体素插值的问题,即轴对齐的实体墙对于不垂直于墙的射线会变得透明。Voxelbitbricks在8x8x8块中为每个体素存储一个位,以指示给定的体素是否为空。然后使用两阶段DDA算法执行射线步进。具有透明面的体素相似,但具有相同的DDA并沿光线方向增加透明度。事实证明,这两种方法都不能很好地将几何表示为距离域,而且速度要慢得多。具有透明度的体素跟踪合并表示的最早方法是使用全局每场景卡来锥形跟踪全局距离场和阴影命中。也就是说,遍历BVH,找到场景中哪些卡片影响采样点,然后根据圆锥足迹对每张卡片进行适度滑移级别的采样。这篇论文放弃了这种方法,因为它最初并没有被认为只代表远场轨迹,而是被认为是高场射线步进的直接替代。有点讽刺的是,这种被放弃的方法最接近我们两年后最终得出的解决方案。第一个演示在这里,已经可以产生一些相当不错的结果:尽管如此,它仍然存在大量图形泄漏,并且在这个简单的场景中,即使在高端PCGPU上,性能也不是很好。为了解决泄漏问题,处理更多实例,在PS5上处理完成时间不到8毫秒。这个演示可以称为真正的催化剂。与以前的方案相比,第一个也是最大的变化是用距离场跟踪代替高度场跟踪。要对生命点进行着色,请从卡片中为生命点插入光线,因为距离场没有顶点属性,这样,未覆盖的区域只会导致能量损失,不会泄漏。出于同样的考虑,将体素锥体追踪更改为全局距离场射线追踪。同时我们也做了很多不同的优化,通过缓存方案对Lumen的不同部分进行了时间卸载。值得注意的是,如果没有锥体跟踪,我们将不得不更积极地降噪和缓存跟踪,但同样,这是一个漫长而复杂的故事。这是我们发送第一个演示后的最终结果,在PS5上始终低于8毫秒,包括对所有共享数据结构(例如全局距离场)的更新。现在的表现更好,比如最新的demo完成时间接近4毫秒,质量上有明显的提升。总之,这篇文章是对整个Lumen的彻底重写,还有很多不同的想法没有实现。另一方面,有些东西被重新利用。就像原来我们用卡片作为示踪剂的表示,现在它作为网格表面各种计算的缓存。类似于软件跟踪,最初是我们的主要跟踪方法,主要是圆锥跟踪,但最终成为一种缩小和支持具有大量重叠实例的复杂场景的方法。