基于物理的阴影 – 环境/间接照明

通过M. Pharr和G. Humphreys研究PBRT,我实现了一个基于物理的path示踪器。 现在我正在尝试使用OpenGL将基于物理的渲染应用于实时graphics

我想开始使用Oren-Nayar和Cook-Torrance作为漫reflection和高光BRDF,但是我有一个问题:如何模拟间接照明

在path追踪器(如pbrt中包含的path追踪器)中,间接/环境光由path追踪algorithm“自动”给出,因为它遵循考虑了直接和间接照明的光线path。

如何在OpenGL中使用基于物理的渲染来建模间接照明,所以使用实时计算机graphics?

免责声明:下面的答案由Nathan Reed 发表在“计算机graphics学图像交换”上的 一个类似问题 。

实时graphics部署各种各样的近似值来处理模拟间接照明的计算费用,在运行时性能和照明保真度之间进行折衷。 这是一个积极的研究领域,每年都有新的技术出现。

环境照明

在该范围的最简单的一端,您可以使用环境照明 :应用于场景中的每个对象的全局,全向光源,而不考虑实际的光源或本地可视性。 这并不准确,但是非常便宜,对于艺术家来说很容易调整,并且可以根据场景和期望的视觉风格来看起来不错。

基本环境照明的常见扩展包括:

  • 使环境颜色有方向变化,例如使用球面谐波(SH)或小的立方体贴图 ,并根据每个顶点或像素的法向量在着色器中查找颜色。 这允许在不同方向的表面之间进行一些视觉差异,即使没有直接的光线到达它们也是如此。
  • 应用环境遮挡(AO)技术,包括预先计算的顶点AO,AO纹理贴图, AO字段和屏幕空间AO(SSAO) 。 这些工作都是通过尝试探测到间接光线不太可能reflection到的地方,例如洞和裂缝,并使那里的环境光线变暗。
  • 添加环境立方体贴图以提供环境镜面reflection。 具有像样分辨率的立方体贴图(每张面128平方或256平方)可以在弯曲的有光泽的表面上进行镜面reflection。

烘烤间接照明

可以说,技术的下一个“层面”涉及在场景中进行烘烤 (离线预先计算)间接照明的一些表示。 烘烤的好处是你可以得到相当高质量的结果,而且实时计算费用很less,因为所有的硬件都是在烘烤过程中完成的。 取舍之处在于烘烤过程所需的时间损害了关卡devise者的迭代速度; 需要更多的内存和磁盘空间来存储预先计算的数据; 实时改变照明的能力是非常有限的; 而烘烤过程只能使用静态水平几何体的信息,所以会错过来自dynamic物体(如角色)的间接光照效果。 不过,烘焙照明在今天的AAA游戏中被广泛使用。

烘焙步骤可以使用任何期望的渲染algorithm,包括path追踪,光能传递,或使用游戏引擎本身渲染立方体贴图(或半纤维素 )。

结果可以存储在应用于关卡中的静态几何体的纹理( 光照贴图 )中,和/或也可以将其转换为SH并存储在体积数据结构中,例如辐照体积 (每个纹理存储SH探针的体积纹理)或四面体网格 。 然后,您可以使用着色器查找并插入来自该数据结构的颜色,并将其应用于渲染的几何graphics。 体积法允许烘焙照明应用于dynamic物体以及静态几何体。

光照贴图等的空间分辨率将受到记忆和其他实际约束的限制,所以您可以使用一些AO技术来补充烘焙的照明,以添加烘焙照明无法提供的高频细节,并响应dynamic物体(例如在移动的角色或车辆下使间接光线变暗)。

还有一种称为预计算辐射传输(PRT)的技术 ,它扩展了烘烤以处理更加dynamic的照明条件。 在PRT中,不是烘烤间接照明本身,而是来自某些光源(通常是天空)的传递函数烘焙到场景中所产生的间接光照中。 传递函数被表示为在每个烘焙采样点处从源变换到目标SH系数的matrix。 这允许改变照明环境,并且场景中的间接照明将响应振振有词。 “孤岛惊魂3”和“孤岛惊魂4”使用这种技术来实现连续的日夜循环,间接照明根据一天中每个时间的天空颜色而变化。

关于烘焙的另外一点:为散射和镜面间接照明分别烘焙数据可能是有用的。 因为立方体贴图可以有更多的角度细节,所以立方体贴图的工作比SH更好,但是它们也占用了更多的内存,所以你不能像SH样本一样密集地放置它们。 视差校正可以用来弥补这一点,通过启发式扭曲立方体贴图使其reflection感觉更接近于它周围的几何。

完全实时的技术

最后,可以在GPU上计算完全dynamic的间接照明。 它可以实时响应照明或几何graphics的任意改变。 但是,在运行时间性能,照明保真度和场景大小之间又要进行权衡。 这些技术中的一些需要一个强壮的GPU才能工作,并且可能只适用于有限的场景大小。 他们通常也只支持一次间接光线的反弹。

  • 屏幕空间全局照明 ,SSAO的扩展,在后处理阶段从屏幕上的附近像素收集reflection光。
  • 屏幕空间的光线追踪reflection是通过在通道中通过深度缓冲区的光线进行工作的。 只要reflection的物体在屏幕上,它就可以提供相当高质量的reflection。
  • 即时光能传递是通过使用CPU将光线追踪到场景中,并在每个光线投射点上放置一个点光源来实现的,这个点射光近似地代表了从该光线的所有方向上出射的reflection光。 这些被称为虚拟点光源(VPL)的光线,然后以通常的方式由GPU渲染。
  • reflection阴影贴图(RSM)类似于即时光能,但是VPL是通过从光的角度渲染场景(如阴影贴图)并在该贴图的每个像素处放置VPL来生成的。
  • 光传播体积由放置在整个场景中的SH探针的3D网格组成。 RSM被渲染并用于将reflection光“注入”到最靠近reflection表面的SH探针中。 然后,一个类似洪水的过程将来自每个SH探测器的光传播到网格中的周围点,并将其结果用于对场景应用光照。 这种技术已经扩展到体积光散射 。
  • 体素锥描迹通过对场景几何体素进行体素化(可能使用不同的体素分辨率,在相机附近更细并且在较远处更粗糙),然后将来自RSM的光线注入到体素网格中。 在渲染主场景时,像素着色器通过体素网格执行逐渐增加半径的“锥形轨迹”,以聚集入射光以进行漫reflection或镜面reflection。

由于问题扩大到逼真的场景大小或其他限制,大多数这些技术在当今的游戏中并未广泛使用。 屏幕空间reflection是个例外,这个reflection非常stream行(虽然它通常与立方体贴图一起作为后备,用于屏幕空间部分失效的区域)。

正如您所看到的,实时间接照明是一个巨大的话题,即使这个(相当长的)答案也只能提供一个10,000英尺的概览和上下文进一步阅读。 哪种方法最适合您,将取决于您的特定应用程序的细节,您愿意接受的限制条件以及您需要投入多less时间。