《塞尔达传说:旷野之息》技术分析:神作是怎么炼成的

作者:Redneckerz 未来游戏研究所 2019-09-04
本文原载于B站专栏未来游戏研究所,已获译者授权。

原作者:Redneckerz
译者:未来游戏研究所
来源:未来游戏研究所
地址:https://www.bilibili.com/read/cv3239418【编译自resetera



我其实很久以前就想做一篇正式的《塞尔达传说:旷野之息》引擎分析文章了,但一直没时间去弄。然而,现在Switch有了新的视频录制功能后,我想这是一个完美的时机来重游这款游戏并通过我上传到Twitter上的视频来分享我的想法(本文中以动态图与静态图代替)。

我将先从我的研究结果摘要开始,但我也会在文章的后面对每一个技术特性进行细分以便通俗易懂。同时我也会尽可能避免出现重复内容。比如说像是Digital Foundry这样的已经分析了引擎的一部分特性,那我就不会再在这里提及到了。这篇帖子的目的是为了让更多的人接触到其他人不打算费心去调查的,游戏中的技术成就。

总之,这里就是这款引擎特性的总结:

  • Global Illumination | 全局光照 (更具体来讲,是光能传递)
  • Local Reflections | 局部反射 (由菲涅尔反射计算)
  • Physically-based Rendering | 基于物理的渲染
  • Emissive materials/area lights | 自发光材质/区域光源
  • Screen Space Ambient Occlusion | 屏幕空间环境光遮蔽
  • Dynamic Wind Simulation system | 动态风力模拟系统
  • Real-time cloud formation | 实时云体变形 (受风力影响)
  • Rayleigh scattering/Mie Scattering | 瑞利散射/米氏散射
  • Full Volumetric Lighting | 完整体积光照
  • Bokeh DOF and approx. of Circle of Confusion | Bokeh景深与模糊圈的近似值
  • Sky Occlusion and Dynamic Shadow Volumes | 天空遮蔽与动态阴影体
  • Aperture Based Lens Flares | 基于光圈的镜头光晕
  • Sub-surface Scattering | 次表面散射
  • Dynamically Localized Lightning Illumination | 动态局部闪电照明
  • Per-Pixel Sky Irradiance | 逐像素天空辐照度
  • Fog inscatter | 雾光散射
  • Particle Lights | 粒子光源
  • Puddle formation and evaporation | 水坑的形成与蒸发




Global Illumination/Radiosity | 全局光照/光能传递

首先我想要声明一点,所有所谓的实时全局光照方案都是以某种方式伪造出来的,都具有着不同程度的准确性。任何仅仅因为没有使用路径追踪之类的而忽略了《塞尔达:旷野之息》中的全局光照方案的人们应该仔细想想自己究竟在说些什么。最重要的一点是,这一切都是实时渲染的;这不仅仅是烘培入纹理中的光照,这对于一款开放世界游戏来说(尤其是在Wii U上)非常令人钦佩。

那么,光能传递到底是个什么东西?嘛,在3D图形渲染中,它是从不同表面反射的光,并在这个过程中讲颜色信息从一个表面传输到另一个表面的全局光照近似法。光能传递越是准确,为了传输适当的颜色就需要计算更多的反射光。

在《旷野之息》中的引擎用的是光照探针在整个环境中收集在光照探针附近不同表面的颜色信息。并没有什么模拟反射光,只是一个给定区域中基本颜色的一些近似值。《旷野之息》用于计算此信息的算法尚不清楚,但我的最佳猜测是球谐函数或之类的东西,基于颜色平均值与光能传递局部化。与《超级马里奥:奥德赛》不同,《旷野之息》中的光能传递并非二进制而是粒子。从光照探针计算的照明信息似乎与LOD系统在同一个渲染管线层次捆绑串流,使得其效率极高。

观察建议:注意当相机靠近该区域时,岩石悬崖是如何从草地上接收到绿色色调的。

全局光照演示动态图

(更新)起初我假设可能整个环境中都有放置球谐函数来收集色彩采样,因为当林克在整个环境中移动时,它似乎会更新为基本颜色。然而,经过进一步调查后,我现在知道了那些基本颜色反射是由于环境中缺乏颜色变化。当我在一个彼此相邻的许多不同颜色表面的区域测试全局光照时,其全局光照系统是如何运作的就变得豁然开朗了。注意林克在接触红墙时,其颜色是如何传递到面向相反方向上所有表面上的。在红墙相反方向的绿墙也是如此(尽管效果并不是很强烈,因为探针更靠近红墙,因此红墙的颜色本身反射更强烈)。事实上,在任何给定的点上,这在各个方向上都会发生。地面向上传递颜色,而林克头部正上方的任何天花板或是彩色表面都会传递其颜色。探针不断地动态的采样并传递颜色(我们可以认为这就是反射光了),因为探针会因为新的传递而拾取更多的颜色,并且还必须对他们进行采样。最后,最终结果将会停止改变,因为最靠近探针的样本将具有最主要的颜色,无论颜色转移量如何。这一过程井然有序,但非常局部化且速度相当的快。探针具有有限的采样范围,并将这些结果应用于世界空间中的材质上。由于如此般的效率,探针能够近似出许多反射光的效果,但只有在距离探针最近的区域中看起来准确。

(更新)这是一个非常重要的发现。

靠近红墙时其他材质也"染"成红色

靠近绿墙时其他材质也"染"成绿色

全局光照实际上会近似多次反射。在林克的头部上有一个光照探针可以对环境中的大多数材质的色彩进行采样。然后,每一个采样的颜色被传递并以相反的方向反射。有趣的是,强度有被考虑为因素,其受到探针最接近的表面以及反射光的强度影响。

在户外可能看起来效果不太明显,但是当有多个相邻的表面时,全局光照的效果看起来很不错。

  • Local Reflections | 局部反射

(更新) 那么,自从我开始分析这款游戏以来,总是让我头疼的一个区域似乎就是局部反射了。有着如此多看似不一致的情况,因为我的理论最初满天飞。现在我可以自信的说,我已经解开了局部反射是如何运作背后的谜团了。显然,这是一种根据具体情况而三管齐下的方案。

  • Specular Lighting | 镜面光照

阳光,天光,闪电,点光源都属于此类别。起初我以为神庙,塔也是如此(因为它们是自发光的,因此我就假设它们是区域光源),但看到神庙与塔所展现出的非常能够揭露真相的加工痕迹(artifact)时,就可以排除这一点了。不是所有发光的材质都能够照明环境,而神庙与塔可以归属于那些不能的发光材质。

  • Aperture mapped reflections | 光圈映射反射

如果这个术语对你来说感到很新颖,那可能因为它就是如此。基于这款游戏的文本转储,《旷野之息》开发人员标记了他们对虚幻引擎4的场景捕获2D反射的看法。环境是这样反射出来的。林克头部(明确来讲,是光圈)上方的虚拟相机有着相对较小的视野,因此当林克移动时就会使得反射(实时显示)在它们适当的空间内移动,直到光圈再次捕获环境。你可以在以下的视频中看到这类的加工痕迹与视野。

  • Screen Space Reflections | 屏幕空间反射

只有那种看起来像层压材质的才会使用这种模型,而这些仅限于神庙之中。在光泽贴图中的一个数值告诉引擎仅对这些材质使用屏幕空间反射。它们会反射屏幕上的任何内容,能够在任何材质的入射余角看到。然而,这些材质上同样也有使用光圈映射来进行环境反射,这也是让我感到迷惑的源头之一。这些材质反射的不协调表现使得我对神庙外的其他材质也做出了假想。值得庆幸的是,我们把这一点理清了。

观察建议:看看林克的反射与蓝灯的反射的对比。林克必须得在屏幕上才能显示出其反射,而蓝灯不需要在屏幕上也能显示出反射。

屏幕空间反射+镜面高光

(更新)局部反射之谜解开了!

正面的墙不能反射,而侧面的墙则可以

那么,神庙材质具有一层额外的光泽反射层,但他们在外部反射上也使用了同样的反射模型。怪不得这么让人迷惑!

使用光泽材质,可以在屏幕空间(屏幕空间反射)内捕获所有内容的反射。而使用非光泽材质(几乎所有的外部材质),使用与虚幻引擎4中所用到的场景捕获2D反射技术几乎完全相同的技术来捕获环境反射。基本上,虚拟相机(具有自己的视体与视野)位于林克的头部正上方,始终面对主相机的地平线,无论林克的定向如何(这使得有限的屏幕外反射得以实现)。然后将捕获的图像馈送到产生反射的材质中,就好像向电视发出现场直播信号。这意味着图像的馈送是以游戏所运行的任何帧率(30帧)实时投射的。这样使得材质的不同元素得以无需等待新的捕获就能更新。但是,实际捕获画面本身会以低得多的帧率(4到5帧)而更新。只要场景捕获相机从其绝对位置移动,你就能看到这一点。在更新捕获反射之前,当前捕获画面于材质内(例如,水)在相机移动的任何方向实时移动(30帧)。然而,一旦材质接收到更新的捕获,就会更正反射。这种更正的延迟是我们得以真实地了解捕获更新即沿着材质的痕迹(4到5帧)。

你能够在下方链接了解到更多关于捕获技术的知识:

https://docs.unrealengine.com/latest/INT/Resources/ContentExamples/Reflections/1_7/

桥柱的反射稍微有些延迟

你可以在这里看到,过时的反射仍然可以平滑地跟踪林克的行动。没有任何卡顿。然后当新的捕获更新时,反射就得以更正了。这与反射贴图的运作原理不同,反射贴图仅在贴图本身更新时才会更新反射。在这,捕获的反射显然已经过时了,但它仍然以30帧的速度改变自身的位置。

你可以在以下动图中体会到捕获相机的FOV:

由于没有地平线相机末尾视线的颜色反射在材质上

现在为什么所有非自发光材质都只有菲涅尔反射就讲得通了。使用这样的反射技术,这些是它唯一可以正常运作的角度了!

我碰巧找到了这个拱门,并意识到了这是测量捕获相机视野的完美设置:


结合上一些基本的三角学来看


我估算其水平视野为大约115°。在林克还没有穿过拱门前,拱门的反射就已经离屏了,因此我们得知它肯定不是180°的视野了,因为如果是的话,拱门的反射就不会像这样出现视觉错误了。

你还能够看到,当相机距离拱门数英尺并且垂直于拱门时,反射是倾斜的并且与视野成比例,这使得我们可以观察到它的宽度。它会测量场景捕获相机的相对水平视野。

不过我想重申一下,这仅仅是粗略的估算,所以我可能会偏上个10°左右,但在有的角度下使用这个视野是不可能的,因此通过排除法,我们至少能有一个估算值。

  • Physically-based Rendering | 基于物理的渲染

在有人问起来前,不,这并不意味着"物理上看起来正确的材质"。这只不过是应用于3D图形渲染管道的一种方法,所有的材质(纹理表面)在与光交互时独特的改变它们的行为方式。现实世界中就是这样的,这也就是为什么它被称作基于物理的渲染(基于现实世界光物理的概念)。不同的材质导致光的行为不同,也就是为什么我们能够在视觉上区分不同的表面。

传统上,渲染管道依赖于美术师对光与不同的真实世界材质的交互方式的理解,并基于那份理解定义纹理贴图的效果。作为结果,不同的纹理表面之间存在着很多不一致性,以及它们与现实世界中的对应物相比之下(这一点是可以理解的,因为我们不能指望美术师对现实世界中的所有物质都有着百科全书般的知识)。对于PBR,光物理的基本原理是管道本身的一部分,并且所有的纹理表面都被归类为具有独特性质的材质,这些性质将导致光根据这些独特性质运转。这样使得不同表面得以放置于不同的光照条件以及动态相机角度之下,并动态的调整光与这些表面的交互方式。美术师不必像传统工作流程那样预定义这种交互方式。一切都是自动的。由于PBR的效率,开发人员更想要制作其中所有材质都有着影响光的独特性质的游戏。

在《旷野之息》中,其PBR有一点艺术天赋,因此你可能甚至不会注意到其引擎有依赖于这样的管道,因为纹理并不一定需要看起来很逼真。然而,材质上所用到的BDRFs(双向反射分布函数)使得引擎有用PBR这一点比较明确。对于每一个动态光源,它的镜面高光(光源本身显示为反射表面的部分)和这些高光的反射率/折射率是根据入射角(入射光相对于表面法线的角度)和光与之相互作用的任何材质的折射率(当光线接触其表面时,材质"弯曲"了多少的光)动态生成的。如果游戏使用的是传统管道,分配在木头与金属上的镜面高光之间就不会有太大的差异。但在这个游戏中,镜面高光的产生完全取决于光与之相互作用的材质。

另一个表明《旷野之息》使用PBR的关键因素是所有材质上的Fresnel(s不发音) | 菲涅尔反射。首先,大部分使用传统管道的游戏甚至都不会用上菲涅尔反射,因为这样还不如直接用PBR了。正如我之前在讨论局部反射时所解释的那样,菲涅尔反射在入射余角处变得可见(入射光几乎与观察者/相机的视角相互作用的表面平行的角度)。根据菲涅尔反射系数,所有材质在入射余角下都达到了100%的反射率,但反射率的有效性将取决于材质的粗糙度。因此,程序员可以区分"反射率"与"折射率"。一些材质反射所有方向的光(漫反射材质)。即使在100%的反射率下,100%的光也可能从整个表面区域反射出来,但并非所有光都在同一方向上反射,因此光线均匀分布,而你看不到任何镜面反射(表面周围的镜像)。其他材质只会反射入射光相反方向的入射光(镜面材质),因此你只能在适当的角度看到反射,接近90%的光都被反射了。漫反射和镜面反射材质的反射率即便是在入射余角下,其反射率(材质反射入射光能力的有效性)也不总是100%,这就是为什么在入射余角下所有材质都看不到完美的镜面反射,哪怕是在现实世界中也是如此。菲涅尔反射的清晰度将随着产生反射的材质而变化。

观察建议:注意桶子木头上的绿色光源是如何在所有角度看起来都是相同的,而这一相同的绿色光源似乎还改变了金属桶箍(桶上的金属圆圈)的反射。

基于物理的渲染效果演示图

  • Emissive materials and area lights | 自发光材质与区域光源

这一个比较简单。发光物件的材质提供独特的光源,以与材质本身相同的形状照明环境。这些并不是在所有方向上传播的点光源,甚至有时会是在一个方向上照明的简单定向光源。有一点很重要值得一提,只有全局(太阳/月亮/闪电)光源才能投射阴影。然而,双向反射分布函数仍然应用于游戏中所有的光源。

观察建议:注意火剑所投射的光的形状。这一形状与剑本身的形状相匹配,但光的强度将取决于剑与它所照明的表面之间的距离。

自发光材质与区域光源效果图

  • Screen Space Ambient Occlusion | 屏幕空间环境光遮蔽

在现实世界中,当光在环境中反射后会有一定量的"环境光"为环境着色,使其变得完全漫射。如果说阴影是遮挡直射阳光物体的产物的话,那么环境光遮蔽可以被认为是环境中缝隙阻挡环境光的产物。

《旷野之息》中所使用的方案称为SSAO(屏幕空间环境光遮蔽),因为它计算了屏幕空间中的环境光遮蔽并且取决于视点依赖。环境只会在相对于相机垂直时它才会接收环境光遮蔽。

观察建议:当从正面看时,在墙壁中的缝隙中寻找黑暗,阴影的噪声模式效果。同样的噪声模式也从这个角度勾勒出了林克的轮廓。

屏幕空间环境光遮蔽效果演示图

  • Dynamic Wind Simulation system | 动态风力模拟系统

这一个让我感到很惊讶,因为我完全没想到它会如此的强劲。基本上来说,物理系统与风力模拟系统是相关联的。它是完全动态的,并根据各自的重量值影响不同的物体。受影响效果最突出的对象是草地与程序生成的云。

观察建议:如果你仔细观察的话,可以在这里看到草和云的方向性流动是如何与风的变化方向相匹配的。

动态风力模拟系统效果演示图

  • Real-time cloud formation | 实时云体变形

这个游戏没有使用任何意义上的传统天空盒。云体是基于引擎设置的参数程序性生成的。它们会投射出实时的阴影。它们根据太阳在天空中的位置接收到了光照信息。据我所知,云被视为游戏中的实际材质。它们并不是体积云,所以你不会看到任何云隙光之类的东西,但同时它们也不是"天空盒"的云。它们的形成也受到风力系统的影响。

观察建议:注意天空中的云体粒子是如何随机地聚集在一起的。

实时云体变形效果演示图

  • Rayleigh scattering/Mie Scattering | 瑞利散射/米氏散射

在现实世界中,当光线到达地球的大气层时,会被空气分子散射,从而形成了地球的蓝天,因为较短波长的蓝光比其他颜色的光更容易散射。然而,当太阳接近地平线时,它就必须得穿过更多的大气层,从而导致大部分蓝光在太阳光到达观察者眼镜时散射,留下波长更长的橙色和红色光到达肉眼。《旷野之息》数学上地近似了这个算法(我其实是在今年早些时候通过文本转储代码中发现的!)显然这一算法也解释了米氏散射的由来,它使得雾得以在天空中出现。

老实说,要不是我查看了该文本转储中的代码,我是绝对不可能想到游戏中有模拟这一现象的。想要伪造出这种效果很容易。然而,在观察了水中天空的倒影之后,这一切都说得通了。这种散射光实时地反射入整个环境中。若是单纯的天空盒会使得这一点不可能实现。

观察建议:注意天空中橙色与红色的不同色调是如何以相同的颜色反映在环境上的。尽管未在动图中展示这一点,但是天空中的散射光也以其他的颜色照明了环境以及水面,这取决于光是如何散射的。


观察建议:注意随着太阳落山,雪的颜色也随之发生变化。


观察建议:在此动图开头,水面至少有5个不同的反射。神庙(蓝色),山丘(绿色),旗帜(黑色轮廓),天空(橙色)和太阳(粉色)。山丘,旗帜,和神庙的反射都通过场景捕获反射而实现,太阳则通过镜面光照(作为镜面高光)而实现,天空也通过镜面光照而实现反射,但并不是镜面高光。随着暴雨的来临,反射的变化是完全动态的。来自乌云的天空遮蔽会实时改变天空中瑞利散射的光照。最终,橙色天光不能够再达到水的表面而逐渐消失,但太阳仍然存在,因为它没有被完全遮挡住。然而,由于天空中如此多的米氏散射,太阳的颜色从粉色变成了白色!即便如此,最终云体变得对太阳来说太多了,完全遮挡了它,仅留下了来自神庙的光与山丘的部分反射。

由瑞利/米氏,镜面光照以及屏幕空间反射所呈现的光照系统其一

由瑞利/米氏,镜面光照以及屏幕空间反射所呈现的光照系统其二

  • Full Volumetric Lighting | 完整体积光照

除了天空中的云,环境中的每个部分及其中的每个物体都有可能在适当的光照条件下实时创建光束。这个游戏使用的是屏幕空间环境光遮蔽来辅助这一效果,但体积光照并非视点依赖。你可以在本文中的阴影体部分找到更多有关体积光照运作原理的信息。

观察建议:注意光束是如何在大型建筑结构投射的阴影中产生的。

完整体积光照效果演示图

  • Bokeh DOF and approx. of Circle of Confusion | Bokeh景深与模糊圈的近似值

我认为引擎所用到的另一个令人惊讶的功能是延迟光照/着色。那么我要稍微简化一点,因为这可以真正地在技术上解释首先为什么现实世界中会出现散景效果。可以说当光进入肉眼/相机的光圈(开口)时,入射光线开始会聚到焦平面的单个点上。随着光越来越集中在这个平面上,它的外观变得越来越锐利,越来越小。随着光远离该平面并变得更加散焦,它的外观变得越来越大,越来越模糊。

家喻户晓的散景效应是当进入相机镜头的光点呈现出在它们通过光圈时的形状(例如,六边形)。模糊圈是当人类无法区分完全聚焦的光点与略微失焦的光点时的聚焦区域。景深通常由模糊圈来决定。有趣的是,当使用希卡望远镜与相机符文时,《旷野之息》会模拟出这两种概念。我的猜测是它是基于纹素(纹理要素)数据在屏幕空间中计算的,然后作为后期特效应用。

观察建议:注意相机的十字线与金属盒上闪耀的蓝色灯光。当相机对焦于远离光源的远景时,光源就会变得模糊,同时变得更大。当相机直接对焦于光源时,则会出现相反的情况。蓝色光源所形成的圆形形状称为散景效果。

Bokeh景深效果演示图

  • Sky Occlusion and Dynamic Shadow Volumes | 天空遮蔽与动态阴影体

除了游戏中的物理系统以外,这些着色特性毫无疑问是《旷野之息》中计算方面上来讲性能损耗最高的要素。

即便云本身没有任何体积,但它们仍能将(软)阴影投射到环境当中。然而,太阳与来自天空的散射光动态地照明整个环境,而环境与其中所有的物体根据该照明投射出自己的阴影。如果环境中的照明即便是在天空完全被阴云覆盖的情况下仍然保持不变的话就会显得很不真实。由于遮蔽区域的直接光照比较少,环境光(漫反射,非定向光)将会在这些区域的照明中发挥更大的作用,并且这些区域中的所有阴影都将变得更为柔和并开始匹配它们周边环境的颜色。

该引擎还是用了阴影体而非简单的阴影贴图,并且游戏中的每一个阴影投射器都是这样实现的。阴影体在指定的3D空间内投射,而不仅仅是环境中的表面与物体。除了在执行阴影体时看起来更为真实的天空遮蔽,同时当它与能够接收阴影的大气层雾相结合时,在3D空间内动态生成阴影体还可以提供完整实时体积光照所带来的优势,而在《旷野之息》中正是如此。

观察小技巧:观察旗帜的硬阴影是如何变得更加柔和,并随着突如其来的暴风雨开始从环境光中接收更多的颜色。

天空遮蔽与动态阴影体其一

观察建议:注意旗帜的运动是如何与产生的光束相关联的。光束之间的暗区是因旗帜的阴影体而存在的。旗帜的动态扭曲告诉了我们这些阴影体是实时生成的。


天空遮蔽与动态阴影体其二

  • Aperture Based Lens Flares | 基于光圈的镜头光晕

99%玩这个游戏的人都忽视了这一特性,所以老实说我都不确定到底值不值得实施这玩意。

基本上,当来自明亮光源的光线以某种倾斜的角度进入相机镜头时,由于在相机要素内部反射的光线,它们会产生称为镜头光晕的光学加工痕迹。大多数游戏只是将光晕作为后期效果来模拟这种效果,当相机略偏于相机视体时就会出现这种效果。光在相机本身内部反射这一概念甚至没有被作为因素而考虑。

在《旷野之息》中,由于引擎已经模拟了景深的相机光圈,它可以追踪光圈与太阳的相对位置,并计算出应该生成多少镜头光晕,即便太阳并不在屏幕上。但这还并不是一切!具有变焦功能的相机更容易出现镜头光晕,并且光晕会根据光圈的形状/大小和变焦级别而改变形状与大小。令人惊讶的是,《旷野之息》也近似出了这些效果!

观察建议:你可以看到,即便太阳在屏幕外,镜头光晕(圆形光线加工痕迹)仍然存在。更重要的是,镜头光晕的形状,大小与清晰度随着相机变焦级别而变化。


基于光圈的镜头光晕效果演示图

  • Sub-surface Scattering | 次表面散射

在现实世界中,有些表面是半透明的(不要与透明混淆),这意味着光能穿过其表面并散射于其内部。现实世界中半透明表面的部分例子为人体皮肤,葡萄,蜡,以及牛奶。在3D图形中对光的这种独特行为建模称作次表面散射或SSS。与大多数实时3D渲染方案相同,程序员已经提出了数种近似这种效果的方法,而无需在分子水平上模拟光的反弹。《旷野之息》中所用的方法相对简单但很有效。

任何应具有一定程度半透明度的表面都将会有多层材质以生成次表面散射。第一层是内部材质。这种材质通常用照明信息来烘培,使其具有半透明的样子。光穿过材质但实际上并没有实时照明材质本身。在这种材质之上的材质就是表面材质。这种材质在两者中持主导地位,在大多数光照条件下你所看到的都是这种材质。

这些材质之间的关系以这样的方式运作,即任一材质的主要外观总是由入射光与透射光之间的比率决定。如果表面材质反射的光比内部材质透射的光更多,那么表面材质的不透明度将与其接收的光成正比例增长。如果内部材质透射的光比表面材质反射的光多,那么表面材质的不透明度将与其未接收的光成正比例降低。根据入射率/透射率来平衡表面材质的不透明度是非常巧妙且效率高的一种方法,可以使材质具有次表面散射效果。

观察建议:注意能够在外部表面看到马厩内部的光的漫反射照明。林克在屋顶上的阴影同时也被了来自内部的光照照明,但当在地面时不会这样。

次表面散射其一

更新:对次表面散射的进一步调查。当更多的太阳光照明这些植被时,其下侧的亮度/颜色会发生变化。

次表面散射其二(1)

次表面散射其二(2)

观察建议:注意表面材质是如何因为接收了更多的光线而变得更不透明,使其内部材质变得模糊。


次表面散射其三(1)

观察建议:注意表面材质是如何因为接收了较少的光线而变得更加清晰,使其内部材质变得清楚。


次表面散射其三(2)

  • Dynamically Localized Lightning Illumination | 动态局部闪电照明

许多游戏通过将闪电作为全局光源而实现环境照明,在整个环境中闪烁,所有阴影投射器都以预定的大小和方向投射阴影。

在《旷野之息》中,雷击基本上就是超大的一坨相机闪光灯,每一个都有着自己的半径与强度,并且能够在地图上的任何一处劈下,无论玩家位于何处。《旷野之息》其闪电的有趣之处在于阴影动态地对应于阴影投射器最近的雷击的强度与位置。这一系统可能是我在所有游戏中见过的最酷的闪电系统。

观察建议:注意每一次雷击时其阴影大小,方向与对比度的变化。


  • Per-Pixel Sky Irradiance | 逐像素天空辐照度

如果说辐射率是来自太阳的辐射量的话,那么辐照度就可以说是给定表面实际接收的辐射量。对于散射天光来说,这是一个相当重要的变量,因为我们之所以能够在夜晚看向太空的主要原因就是因为没有它!《旷野之息》使用一种跟踪太阳相对于天顶位置的算法来计算辐照度,并且在日落期间,它开始逐像素地移除天光,直至没有剩下的辐照度为止。当天空中没有了云层与米氏散射后,星星将开始出现在天空中,即便天还没有完全黑下来。夜晚与白天之间的颜色渐变过渡实在是令人印象深刻。

观察建议:本身你是可以在太阳落山时星星出现的,但由于Twitter+动态二重压缩,这一点也就看不到了。


  • Fog inscatter | 雾光散射

在现实世界中,雾像物理对象那样接收光与影。如果雾是体积的话,那么计算机图形的计算效率就会很低。《旷野之息》通过创建一份雾噪声模式(类似于它们的环境光遮蔽噪声模式,但不限于屏幕空间)并应用来自太阳和天光的辐射值来生成光散射来解决这个问题。当你将其与阴影体结合使用时,不仅可以获得体积光照,即便在没有体积的情况下它看起来也会像是有体积的雾。

观察建议:注意山上的雾是如何呈现出环境中可用光的颜色的,同时看起来还很有体积感。



  • Particle Lights | 粒子光源

游戏中几乎每一个粒子都是自发光的。其中许多同时也照明了环境。许多粒子不是将粒子视作物体而渲染,而是可以在3D空间的所有方向上发光的简单的点光源。

观察建议:注意无论相机如何移动,发光的余烬是如何在3D空间内独立移动的。



观察建议:雪粒子在《旷野之息》中是视为粒子光源渲染的。一种产生了雪粒子能够反射太阳光的错觉的方法。不过这也可能仅仅是不同的美术选择就是了。


观察建议:注意萤火虫是如何照明它们周边环境的。


  • Puddle formation and evaporation | 水坑的形成与蒸发

可能是游戏中最奇妙但也最聪明的渲染解决方案了。在游戏世界的整个地形之下,存在一层水面材质的平面,当下雨时,水面材质将升高与降低以用水填充水池,并在太阳回来时蒸发掉这些水。根据水面与地面的相对距离,会用上一个水沫材质层。这一过程非常简单,同时也是游戏中又一个令人印象深刻的动态效果。

观察建议:仔细观察在下雨时水池是如何"填充"满水的。

水坑的生成

观察建议:仔细观察雨停且太阳出来时水面是如何"蒸发”的。

水坑的蒸发

我其实还回去翻阅了一下这游戏的文本转储,几乎证实了我所提到的所有内容。看来我应该先去翻翻文本转储而不是在游玩过程中调查引擎,这样就轻松多了!

总之,这里是Pastbin链接:https://pastebin.com/Jc9b0BCp

于是,本次分析就已经结束了。与往常一样,如果你对帖子中所提供的信息有任何疑问的话,欢迎随时告诉我。



最新评论
暂无评论
参与评论

商务合作 查看更多

编辑推荐 查看更多