Eevee 中的路径追踪、光栅化和光线追踪

Cycles 的工作原理是将 相机 每个像素的光线投射到场景中。它们会反射、折射或被物体吸收,直到它们碰到 光源 或达到反射极限。因为许多物体或纹理细节可能小于一个像素,则只从一个像素中跟踪一条光线并 不准确 ,所以 Cycles 从该像素中发射 额外的 随机光线(样本),并随着时间的推移对结果进行平均。这种对随机样本进行平均的蛮力方法被称为 蒙特卡罗模拟 ,当应用于光的路径时,它被称为 路径追踪 path tracing )。

虽然路径追踪在现实世界中并不完全准确(它有一个反弹限制,并且它不可能模拟每个光子),但它可以在计算机图形学中得到最好的图像。你可以想象得到它会非常慢。

大多数 3D 游戏引擎和应用程序视口使用的渲染方法称为 栅格化 光栅化 )。这是渲染计算机图形的最古老的方法之一,当它涉及到简单的场景时,它的速度非常快。它的 工作原理 是将模型的面投影到组成屏幕上 2D 图像的像素上。然后,这些像素可以根据对象的着色器、法线、面是否在阴影中等等调整它们的颜色。

Eevee 通过 OpenGL 3.3 使用栅格化,这就是为什么它可以比其他类型的渲染更快。要记住的 关键 是,这种速度是以准确性为代价的,因为它是与像素信息(即场景的压缩单一视图)打交道,而不是在整个三维空间中相互作用的光路径。

NVIDIA RTX,光线追踪和混合渲染

你可能听说过实时光线追踪的说法,想知道它是如何应用于所有这些内容的。一些游戏已经开始利用 NVIDIA 的新型 RTX 卡,这种卡具有特定的架构,可以跟踪光线。这些游戏实际上并没有单单完全使用某一种渲染技术,而是使用所谓的 混合渲染技术 。他们正在使用一种 只有一个样本和很少反弹 路径追踪 (每个像素只需要一个射线的反弹,技术上称之为 光线追踪 ),只渲染反射和阴影,然后通过 机器学习降噪器 运行,并将结果与光栅化的漫反射和其他通道结合,以获得最终结果。

我建议大家观看这段视频,看看这项技术如何影响游戏和 Eevee 之类的渲染引擎:

  • Beyond Turing - Ray Tracing and the Future of Computer Graphics
  • 这是一种非常聪明的技术,我非常高兴看到这种技术能够实时运行,但是它并不能在短时间内让栅格化取代路径追踪。相反, 深度学习降噪器 是路径追踪取代栅格化的重要一步。

    Eevee 和 Cycles 之间的关键着色差异

    我们很容易将功能当成一个清单(环境遮挡,折射等....),看到它们都出现在两个引擎中,并假设它们都具有相同的功能。然而,由于渲染方法的不同,虽然 Eevee 渲染在很多方面可以令人信服地接近 Cycles,但在以下方面仍然存在困难:

    Cycles 环境遮挡( AO )是基于 三维空间中表面之间的距离 。Eevee AO 是基于 (根据屏幕看到的 2D 图像上的)表面之间的距离 。它仍然看起来很好,因为它使用一个 深度通道 来决定在哪里淡出 AO,这样它就不会在它后面很远的对象上投射(你会在 2.79 的视口 AO 中注意到这一点)。然而,在 深度截断 生效之前,你仍然会经常看到遮挡 “附加” 到对象上。

    Eevee 只能遮挡相距物体一定的距离。在上面的第一个 Cycles 渲染中,注意到盒子的侧面有很大的渐变,而猴头所在的表面有很小的渐变。明暗之间的尖锐和广泛过渡的组合看起来非常自然。在 Eevee 中,这两个渐变区域的大小是相同的,导致盒子的两边看起来是平坦的,而猴子下方的遮挡部分看起来过于黑暗。

    Cycles 的全局照明(也就是间接照明、光能传递等)深入到它的工作原理中。光路从每次反弹中获取数据(比如已经被吸收的颜色),并使用这些信息来决定当它到达下一个表面时该怎么做。

    Eevee 肯定无法获得反弹信息,所以它使用 光照探针 来近似它。光照探针基本上是 从它们所在的空间点拍摄场景的快照,并将适当的颜色投射到它们附近的物体上 。这被称为 烘焙 ,数据被存储,而不是每帧都更新。因此,带有烘焙间接照明的物体 不应该 被动画化。

    大量的光照探针将使得场景看起来与 Cycles 中一样,但当然这将需要非常长时间的烘焙。光照探针数量的限制意味着它们之间的空间必然只是近似的,可能会产生瑕疵。在上面的渲染中,注意蓝色立方体上的暗斑,以及它与地面接触处的不均匀遮挡。

  • 辐照度体积探针( Irradiance Volume Probe ) —— 内框中的辐照度将照亮我们的场景,内框到外框的范围则是辐照度衰减区
  • 借鉴一下 Unity

    摘自 Unity 文档 :通过 光照探针 可以捕获并使用穿过场景空白空间的光线的相关信息。

    与光照贴图类似,光照探针存储了有关场景中的光照的 “烘焙” 信息。 不同之处 在于,光照贴图存储的是有关光线照射到场景中的 表面 的光照信息,而光照探针存储的是有关光线穿过场景中的 空白空间 的信息。

    光照探针是在烘焙期间测量(探测)光照的场景位置。在运行时,系统将使用距离 动态游戏对象 最近的探针的值来估算照射到这些对象的间接光。

  • 一个非常简单的场景显示了放置在两个立方体周围的光照探针

    在这一点上,你可以有把握地假设 Cycles 的任何特性都是通过反射光线来工作的,所以强烈的反射并不奇怪。Eevee 使用了一些技巧来试图模仿这一点,但当然,它仍然采用的是一种不那么具有准确性的方式。 屏幕空间反射 的工作原理是 将相机拍摄的图像翻转过来 。它是速度很快,在大多数情况下看起来也很好,但不能用于 相机看不到 的东西, 如物体的背部或底部

    Eevee 还可以使用 反射探针 ,反射探针是 像虚拟相机一样的平面、立方体或球体 它们渲染周围的东西,然后把图像映射到物体上 。因为平面非常简单,它们可以 实时更新 ,但立方体和球体贴图 需要烘焙 ,因此它们获取数据的对象在动画时看起来 并不正确 。并且一个物体是完美的立方体或球体的情况也很少见,所以映射也会引入一些不完美。

    建筑内的小球,由于没有光落在上面,导致它的渲染是完全黑色的

    虽然可以开启 Screen Space Reflection 增加一些反射效果来改善,但是当我们拉近相机以后,瑕疵则越发的明显

    因为 SSR 仅仅是利用了你屏幕上看到的东西,然后进行简单反转。由于当镜头拉近之后,屏幕上的信息变少了( 它无法知道相机背后是什么样子 ),所以瑕疵就越发的明显。

    所以此时 反射立方体贴图 就派上用场了

    当该立方体贴图烘焙完毕,明显我们可以看到它不再是一个黑色小球

    并且随着镜头拉近,也不会出现之前那样的明显瑕疵

    注意 :烘焙间接照明的时候同时还会烘焙环境光遮蔽(AO),如果你已经在 Eevee 中开启了 AO 选项,那么效果可能就有点过头了,具体需要结合 AO 其下的 Distance Factor 参数进行调校 。

    借鉴一下 Unity

    摘自 Unity 文档 反射探针 非常像一个 捕捉周围各个方向的球形视图的摄像机。然后,捕捉的图像将存储为 立方体贴图 可供具有反射材质的对象使用 。可在给定场景中使用多个反射探针,并可将对象设置为使用由最近探针生成的立方体贴图。带来的结果是对象上的反射可根据环境发生令人信服的变化。

  • 一个反射探针显示附近对象的反射

    虽然这两个渲染引擎都支持透明材质,但它并不是任何渲染引擎都喜欢处理的事情。Cycles 的透明度受到反弹次数的 限制 ,在反弹之后,材料将呈现为纯黑色。

    Eevee 的 Alpha Blend 材质设置是通过 从后到前 将材质层叠在一起,它需要一个限制,以避免缓慢到像冰川一样移动。当它达到这个极限后,它就不会画更多的面,如果你有太多的层,就会导致一个 糊状渲染

    另一方面,Eevee 的 Alpha Clip 从前到后 将材质分层,看起来很漂亮,很清爽。作为 代价 的是这种材质要么是完全不透明的,要么是透明的, 不能处理 两者之间的任何混合。当你远离它们的时候,它们也会变得更加透明。在上面的例子中,你可以看到后面的树的树枝通过树叶清晰地显示出来,即使它几乎完全被遮挡住了。

    在 Eevee 中,折射 是通过扭曲物体背后的东西来完成的,或者是根据其法线和厚度从立方体贴图中看到的东西 。这意味着光不会像在 Cycles 中那样在物体内部反弹,也不会觉察到从各个角度进入的光。这可能会导致一个梦幻般的玻璃球、气泡或水坑,但当涉及到复杂的对象时,它并不能完全达到标准。即使是我们在 Blender 内部使用的光线追踪折射,也无法与我们在 Cycles 中使用的全路径追踪的效果相比。

    Eevee 中的阴影基本上是 通过捕捉每个光能看到什么样的图像,并检查其上每个像素,以确定它是否包含在该光中 。阴影的分辨率越高,需要检查的像素就越多,结果也就越准确。软阴影和接触阴影有助于弥补阴影映射技术通常的 视觉局限性 ,但如果没有 Cycles 所具有的光反射,就很难获得自然的效果。

    Cycles 不受分辨率或映射技术的限制,几个反弹产生的差异对 VFX 合成等东西 至关重要

    Tips: image.png

    Eevee 秒杀 Cycles 渲染的是 “神射线”,即 光线通过体积投射 。虽然 Eevee 不太准确,但在大多数情况下它看起来足够好,而且完全没有噪声。你甚至可以添加 3D 纹理使它更有趣。

    然而,复杂的体积量则是另一回事。浓密的烟雾是需要实际的射线散射的,光发射或从体积到其他物体投射阴影也是需要它的。

    次表面散射

    Eevee 使用物体的厚度及其法线来近似次表面下的光散射。当少量使用时,它看起来相当不错,比如说你想要的皮肤。与 Cycles 相比,它的 缺点 是表面薄,细节清晰,特别是在使用 Random Walk SSS 方法时。在上面的渲染中, 注意 下巴和上颚周围没有清晰的轮廓。另一方面,它的尾巴却看起来正好。

    头发和毛皮

    Eevee 中的头发比实时头发看起来更好看,它可以处理相当多的头发。看看 Daniel Bystedt 制作的这只老虎的演示就知道它的可行性了!

  • Tiger - Breakdown - Blender 2.8 Eevee development test
  • 当你看它们投下的阴影时,Eevee 头发的限制就开始发挥作用了,而且我们使用 Cycles Principled Hair BSDF 时,它缺乏通过丝线组的散射。在上面的例子中,看看头发在脖子和肩膀的交汇处,额头上的阴影,以及沿着头部一侧头发的颜色渐变。

    复杂的材质

    Eevee 可以处理一些极其复杂的节点设置! 上图显示了 Kent 的完全硬木着色包。 只是不要太疯狂 —— Eevee有每个材质 24 个纹理的 硬性限制 。你不太可能在常规的 PBR 工作流程中遇到这种情况,但这是需要 注意 的,因为在混合新材质时肯定有可能遇到这种情况。

    你不能在 Eevee 中使用 True Vector 置换,尽管这可能会在 Blender 稍后版本更新。

    它也 很难渲染 复杂的凹凸细节。在上图中,注意勺子上的木纹。因为 Cycles 平均了许多样本,它看起来比实时版本更详细,实时版本使用相对较少的 屏幕空间反射 样本。改进的凹凸贴图在 2.81 之后的 Eevee 的路线图上,开发人员表示新方法应该更接近于 Cycles 的质量。

    更新: Eevee 的凹凸渲染得到了改进,它看起来确实很接近 Cycles。

    Cycles 支持大多数来源的运动模糊,而 Eevee 目前 只支持 相机运动模糊。物体移动或骨骼枢轴变形( armatures deforming )不会有任何影响。它也不支持像滚动百叶窗这样的花哨效果。这并不是栅格化的固有限制,所以它很可能在未来被更新。Cycles 以同样的方式开始,随着时间的推移,它的运动模糊有了极大的改善。这不是一个微不足道的问题,可能需要相当长的时间来实现。

    更新: 动态模糊现在在 Eevee 中工作得很好,即使是骨骼绑定了的角色,虽然它不支持滚动快门(一个相当小众的用例,我从来没有真正需要)。

    Eevee 支持景深,看起来很不错!不过它仍然是近似值,而 Cycles 是物理上的精确值。区别实际上只表现 在清晰和模糊区域之间的过渡 ( 注意 上图中沿着下巴的尖刺),以及缺乏像 多边形形状 和 变形失真( anamorphic distortion ) 这些花里胡哨的东西( bells and whistles )。但对于大多数情况,它的效果非常不错,而且速度非常快。Blender 2.81 2.82 在 Eevee DOF 方面有很大的改进,这应该会使它更接近 Cycles。

    路径追踪为我们提供了关于光线传播的有趣数据,这使我们能够创建很酷但反常的效果,如顶部焦散或某些通道看不见的物体。这些信息 根本不可能 在 Eevee 中获得。

    多边形计数

    Eevee 渲染速度总是比 Cycles 快,但在渲染多少个多边形而不崩溃的竞赛中,Cycle 会以 很大的优势 获胜。这是因为它使用了 实例化 ,以及与栅格化引擎不同的 路径追踪程序处理多边形的方式

    最后一点对于视觉特效工作来说是 非常重要 的。Eevee 有主要的如 雾、法线和 AO ,但它仍然 缺少重要 的东西,如 向量、对象和材质索引、阴影、发光,和隐射(Cryptomatte) 。这些也可能随着时间的推移而改进,但永远无法在缺乏的光线信息的基础上进行同样数量的微调。

    更新: Eevee 现在也支持 漫射、镜面、体积、发射、环境、阴影、bloom 和隐射通道 Vector 是目前 唯一缺少 的主要工具。

    进行这些比较的目的并不是要削弱您对 Eevee 的热情,而是让您能够做出明智的决定, 决定为每个特定的项目使用哪种渲染器 。记住 —— 截止日期比看起来更近! 在许多情况下,选择速度而不是质量是完全正确的。我们的选择越多越好!