在研究了M. Pharr和G. Humphreys的PBRT之后,我实现了基于物理的路径跟踪器。现在,我正在尝试使用OpenGL ES(在iPhone应用程序中)将基于物理的渲染应用于实时图形。

我想开始使用Oren-Nayar和Cook-Torrance作为漫反射和镜面BRDF,但是我有一个问题:如何为间接照明建模?

在路径跟踪器中(如pbrt中包含的那样),间接/环境光是从路径跟踪算法中自动获得的,因为

我如何使用OpenGL ES编写的基于物理的渲染对间接照明进行建模,以便使用实时计算机图形?

#1 楼

实时图形部署了各种近似值,以处理模拟间接照明的计算开销,在运行时性能和照明保真度之间进行权衡。这是一个活跃的研究领域,每年都有新技术出现。

环境照明

在最简单的范围内,您可以使用环境照明: ,全向光源,适用于场景中的每个对象,而与实际光源或局部可见性无关。这一点都不准确,但是非常便宜,艺术家可以轻松调整,并且可以根据场景和所需的视觉样式看起来还不错。 br />

使环境颜色定向变化,例如使用球谐函数(SH)或小的立方体贴图,并基于每个顶点或像素的法向矢量在着色器中查找颜色。即使在没有直射光的情况下,这也可以在不同方向的表面之间进行视觉区分。
应用环境光遮蔽(AO)技术,包括预先计算的顶点AO,AO纹理贴图,AO场和屏幕空间AO( SSAO)。所有这些方法都是通过尝试检测不易反射间接光的区域(例如孔和缝隙)并使那里的环境光变暗来实现的。具有良好分辨率(每个面128²或256²)的立方体贴图对于在弯曲,发亮的表面上进行高光反射很有说服力。可以说,技术的下一个“层次”涉及烘焙(离线预先计算)场景中间接照明的某种表示形式。烘烤的优点是您可以以很少的实时计算费用获得相当高质量的结果,因为所有硬部件都在烘烤中完成。折衷是烘烤过程所需的时间会损害关卡设计人员的迭代速度;存储预先计算的数据需要更多的内存和磁盘空间;实时更改照明的能力非常有限;并且烘焙过程只能使用来自静态关卡几何体的信息,因此将忽略动态对象(如字符)的间接照明效果。尽管如此,烘焙照明仍然在当今的AAA游戏中得到了广泛使用。

烘焙步骤可以使用任何所需的渲染算法,包括路径跟踪,光能传递或使用游戏引擎本身来渲染立方体贴图(或半立方体) 。

结果可以存储在关卡中应用于静态几何的纹理(光照贴图)中,和/或还可以将其转换为SH并存储在体积数据结构中,例如辐照量(体积)每个纹理像素存储一个SH探针的纹理)或四面体网格。然后,您可以使用着色器从该数据结构中查找和插值颜色,并将其应用于渲染的几何体。体积方法允许将烘焙的光照应用于动态对象以及静态几何体。

光照贴图等的空间分辨率将受到内存和其他实际限制的限制,因此您可以补充烘焙的光照使用某些AO技术的照明可以增加烘焙照明无法提供的高频细节,并响应动态对象(例如在移动的角色或车辆下使间接照明变暗)。

还有一种称为预计算辐射转移(PRT)的技术,该技术可以扩展烘焙以处理更多动态光照条件。在PRT中,您可以将传递函数从某些光源(通常是天空)烘焙到场景中所产生的间接照明,而不是烘焙间接照明本身。传递函数表示为一个矩阵,该矩阵在每个烘烤采样点处从源SH系数转换为目标SH系数。这允许更改照明环境,并且场景中的间接照明将合理地响应。 《孤岛惊魂3》和《孤岛惊魂4》使用此技术实现了连续的昼夜循环,间接照明根据一天中的每个时间的天空颜色而变化。具有单独的烘焙数据以用于漫反射和镜面反射间接照明。立方体贴图在镜面反射方面比SH更好(因为立方体贴图可以具有更多的角度细节),但是它们也占用更多的内存,因此您不能像SH样本那样密集地放置它们。通过试探性地变形立方体贴图,使它的反射感觉更贴近周围的几何体,可以使用视差校正来弥补这一点。 >最后,可以在GPU上计算完全动态的间接照明。它可以实时响应灯光或几何形状的任意变化。但是,再次需要在运行时性能,照明保真度和场景大小之间进行权衡。其中一些技术根本需要强大的GPU才能工作,并且仅对于有限的场景大小才可行。它们通常也仅支持间接反射的单个反射。可以为单个物体提供不错的环境反射。例如,这通常用于赛车游戏中的玩家汽车。

屏幕空间全局照明是SSAO的扩展,可以在后期处理过程中收集屏幕上附近像素的反射光。

屏幕空间光线跟踪反射是通过光线行进穿过深度缓冲区来实现的。后通。只要反射的对象在屏幕上,它就可以提供高质量的反射。

即时辐射性的工作原理是使用CPU将光线跟踪到场景中,并在每个光线照射点上放置点光源,大约代表该光线在所有方向上的出射反射光。然后,GPU以通常的方式渲染了许多称为虚拟点光源(VPL)的光。

反射阴影贴图(RSM)与即时​​光能传递相似,但是VPL由从光的角度渲染场景(例如阴影贴图),并在该贴图的每个像素上放置一个VPL。 RSM被渲染并用于将反射光“注入”到最靠近反射表面的SH探针中。然后,类似洪水填充的过程将来自每个SH探针的光传播到网格中的周围点,其结果用于将照明应用于场景。该技术还扩展到了体积光散射。

体素圆锥跟踪通过对场景几何体进行体素化(可能使用不同的体素分辨率,在相机附近更精细,远处更粗糙)进行工作,然后从RSM进入体素网格。渲染主场景时,像素着色器通过体素网格执行“圆锥轨迹”(半径逐渐增大的射线行军),以收集入射光以进行漫反射或镜面阴影。由于将问题扩展到实际场景大小或其他限制,今天这些技术中的大多数并未广泛用于游戏中。屏幕空间反射是一个例外,它非常流行(尽管对于屏幕空间部分发生故障的区域,它通常与多维数据集贴图一起用作备用)。间接照明是一个巨大的话题,即使这个答案(相当长!)也只能提供10,000英尺的概览和上下文,以供进一步阅读。哪种方法最适合您,将在很大程度上取决于特定应用程序的详细信息,您愿意接受哪些约束以及必须投入多少时间。

评论


$ \ begingroup $
@Nathan,谢谢您的详细回答。我知道这是一个很大的话题(也是一个很大的研究课题)。最大的问题是在线文档是零散的,很难找到合适的方法。我的项目是goo.gl/Fgo21x:BRDF查看器(受WDAS查看器启发),用于显示最常见的基于经验和基于物理的BRDF模型,并支持使用光谱数据(三刺激值)进行颜色计算。这是研究OpenGL的教育项目。
$ \ endgroup $
–Fabrizio Duroni
2016年9月12日23:50

$ \ begingroup $
我认为最好的第一种方法是使用您提到的通用扩展名:SH或小型立方体贴图+环境立方体贴图(用于反射和折射)。你怎么看待这件事? (我在不眠之夜下班后正在开发此应用程序:)。再次感谢您收集以上链接的资源(我现在有很多材料需要研究)。
$ \ endgroup $
–Fabrizio Duroni
16 Sep 12'在23:53

$ \ begingroup $
@FabrizioDuroni是的!对于BRDF查看器,简单的定向环境和环境立方体贴图应该很棒。
$ \ endgroup $
–内森·里德(Nathan Reed)
16/09/13在20:29

$ \ begingroup $
也许这属于您的类别之一,但是老式的多维数据集渲染到所有面孔不是技术上完全实时的技术吗?另外,是否还可以使用用于散射反射的环境立方体贴图来增强基本环境?
$ \ endgroup $
–user3412
16-10-6在23:34



$ \ begingroup $
@racarate对不起,我花了一段时间回答,但是的,你是对的!我想我想提一提,但是忘了。 :)无论如何,我添加了它。 (我确实提到在第一个要点上使用立方体贴图进行扩散。)
$ \ endgroup $
–内森·里德(Nathan Reed)
16-10-12在4:54



#2 楼

这是实时CG中仍然存在的主要“难题”,并且正在进行大量研究来解决它。

最大的障碍是,在光栅图形中,场景的每个组成部分都是“在真空中”渲染的-每个三角形的渲染均不参考场景中的其他三角形,像素也是如此,与光线跟踪方法相反,在光线跟踪方法中,每条射线都可以访问内存中的整个场景。因此,实时程序员需要使用怪异的技巧来进行诸如反射和阴影之类的操作,这同样适用于全局照明。慢但很棒的功能,例如光能传递或离线路径跟踪,然后将照明信息与常规顶点数据一起保存。这对于静态几何非常有用,但是一旦添加移动对象,就会出现问题。 Michal Iwanicki很好地介绍了他们如何解决“ The Last of Us”。它们基本上是整个球体表面的傅立叶变换,通过丢弃高频分量,您可以在每种颜色仅9个系数的情况下获得视觉上令人愉悦的,大多是精确的环境照明。例如,Unity使用S.H.为了在场景的各个点烘烤“光探测器”,移动的物体可以在附近的探测器之间进行插值,以获取其位置处的间接光的近似值。罗宾·格林(Robin Green)的论文基本上就是这种技术的圣经,但是它的工作量很大。目前最热门的技术似乎是Voxel Cone Tracing,它不涉及任何预烘焙步骤。我本人不太熟悉它,但是据我了解,它涉及将场景体素化为低分辨率的Minecraft风格的世界,将体素放入像八叉树这样的可快速遍历的空间结构中,然后将其宽广从每个点发出光线(锥体),并检查它们击中了哪些体素以收集反射光。 NVidia目前正在大力推动这一工作,并且在这里和这里都有论文。

#3 楼

路径跟踪是一种计算量很大的算法,不适合实时。 PBRT的体系结构也不适合实时,PBRT的主要目标是使用无偏蒙特卡洛积分来解决渲染方程。有关更多信息,请参见https://en.wikipedia.org/wiki/Unbiased_rendering。

没有很多优化和约束,我怀疑您是否能够在移动设备上达到不错的性能。

无论如何,路径跟踪都可以在OpenGL中实现,我建议研究一下功能强大的计算着色器。与Desktop GL相比,OpenGL ES 3.1支持具有一些次要限制的计算着色器。

通读此页面以获取更多信息:https://github.com/LWJGL/lwjgl3-wiki/ wiki / 2.6.1.Ray-tracing-with-OpenGL-Compute-Shaders-(第一部分)

祝你好运!