分类目录归档:Global Illumination

DXR对如VXGI之类的全局光照算法有多大的影响?

看到知乎上有关于DXR能否取代VXGI之类的全局光照算法,这里将其回答分享给观众号的朋友们。

首先DXR和VXGI并不是一类事物,其中算是一个框架,而后者是一个全局光照算法。如果非要比较的话,也许可以说成“以DXR所能实现的光线追踪算法在GI方面能够替代现在的VXGI算法吗?”,如果问题是这样,那答案就非常简单,那就是现在光线追踪算法远远不能做到实时。不过问题又来了,可DXR说它是“实时光线追踪”(real-time ray tracing)啊,所以这就导致了题主的困惑。

要解开这个困惑,我们从三个方面来阐述,首先是DXR的实时光线追踪到底是不是真的,如果不是真的,它到底包含了那些内容;其次是将现有DXR能实现的效果与VXGI进行比较;最后是如果DXR仅仅是一个光线追踪框架,VXGI能否集成进DXR中。

DXR实现了完全的实时光线追踪了吗?

这个答案毫不犹豫的是:No!

你在GDC上看到的所谓real-time ray-traced demo,实际上并不是整个渲染都是基于光线追踪的,整个渲染的大部分工作都还是传统的光栅化来完成的,DXR基本上只用来做反射,环境遮挡,和面积光源产生的软阴影等少数几项事情。为什么,因为一条光线的成本太高了,所以目前DXR能够实时完成的事情,基本上满足两个条件:一是每一帧处理的像素数量很低,例如目前实现的几种效果都是针对屏幕空间(screen space)的像素发射光线,也就是光栅化生成的可视图像所在的那些像素;二是每个像素只发射一条或者少数几条光线,例如反射只需要对屏幕空间的每个像素沿反射方向只发射一条反射光线,而AO和针对面积光源的Shadow rays也只需要少数几条光线即可。这样下来,整个场景每一帧也就是针对屏幕空间的每个像素发射少数几条光线而已,仅此而已,甚至两次以上反弹想都不用想。但即便这样,你都需要一个买不起的Volta。

另外也有一种情况,那就是完全使用光线追踪,而不包含光栅化,这种情况就是从摄像机向每个屏幕空间的像素所在的范围随机发射一条光线,然后根据BRDF随机选择一个方向,并且反弹控制在极少的数量,例如2,3次,这样下来每个屏幕空间的像素差不多也只有几条光线,整个过程都是基于蒙特卡洛方法的,由于光线数量非常少,所以最后的结果就需要严重依赖于降噪(denoising),文大他们展示的一些这些面的工作大概就是这个思路。这和上面的两个条件基本上也是吻合的,即只对屏幕空间的像素发射光线,并且每个像素只产生很少的几条光线?

那我们在激动什么呢?其实DXR并没有什么技术的革新,是NVidia在宣传显卡而已,在向你兜售未来,开玩笑的。我觉得DXR的意义就是将这种少数光线能做的事情开始引入到光线追踪算法中,这不仅仅是说我们迈出了第一步的事情,实际上它带来的画面提升也是非常大的,比如传统的光栅化只能处理点光源,即便是面积光源,也大都是被近似为一个“点光源”后按照阴影贴图的方式来做,但是使用DXR,面积光源完全按真实的物理方式去计算,这种效果的提升不仅仅是“画质”上的提升,它是由近似向物理正确上的提升,你看GDC上那些Demo,即便是简单的场景,使用DXR的面积光源要比光栅化的画面效果要好得多,因为整个场景更加接近自然。

但是,但是,但是,我们离完全的实时光线追踪是不是近了,毕竟我们迈出了第一步不是?

通常人类做一件事情,只要迈出第一步,第二,三……步通常很简单,最后99步可能非常困难,但是对于光线追踪来讲,第一步跟第二步的距离会非常漫长,毕竟光线一反弹起来就不可收拾。

现有的DXR GI与VXGI的比较

那当然也是不好比较了,DXR目前实现的主要是反射,AO和面积光源,VXGI实现的主要是间接光照,你让DXR去追踪一下间接光试试,估计10块Volta都不够!

当然它们都能处理AO,仅就针对AO而言,从效率上讲,VXGI肯定要快,毕竟它是对阶层式(hierarchical)的稀疏场景执行圆锥体追踪(cone tracing),而DXR是对整个几何场景的所有三角形网格执行光线追踪(ray tracing);但是从结果来讲,DXR绝对要好得多,因为Ray tracing本身是基于物理的,而VXGI的cone tracing是基于体积渲染积分模型的,它在光线步进的过程中,其遮挡关系是通过混合计算出来的,这跟透明度的处理原理类似,这种方式随着步进距离的增大,其误差也会增加增加,并且cone的半径过大也会导致误差。从下图就可以看出,观察点的发出的Cone上有两个物体各遮挡50%的光照,从实际上看观察点应该被完全遮挡而处于阴影当中,而实际上在VXGI中它的可见性为25%=50% x 50%。关于VXGI可以在《全局光照技术》中找到更多更详细的描述。

VXGI的Cone tracing使用的体积渲染模型

所以这也可以看到,目前实时渲染的方法,大都是近似,从这就可以看出上面所说的“由近似向物理正确”转变的意义所在。

VXGI可以集成进DXR中吗?

目前我们更愿意把DXR看做一个框架,而不是一种光线追踪算法,那新的问题是,VXGI可以集成进DXR吗,龚大的回答里也提到这个问题。据我所了解,不太容易,或者说效率很低。这主要有两个方面的原因。

DXR的光线追踪管线

首先是DXR所支持的基元类型的限制。DXR目前支持两种类型的基元类型,一种是三角形网格,一种是自定义的程序化基元(procedural geometry primitives),其中后者仅向DXR传输一个AABB的包围盒,然后具体的表面形状由application提供的一个intersection shader来实现,这个方面由于VXGI以体素的形式存在,显然只能选择后者。这个从表述上看问题不大,但是效率会有很大问题,首先是procedural primitives的性能本身并不如triangle primitive,其次是DXR是基于光线追踪,它会遍历所有体素结构,其光线与体素的相交顺序是不定的,因为DXR内部会针对光线与AABB包围盒的相交计算执行一定的调度,比如重新排序;而VXGI则是基于对阶层式结构的遍历,它依赖于由近向远或者说由前向后的步进顺序,这里直接就矛盾了,DXR并不保证这种顺序。

第二个问题更加严重,VXGI是基于光线步进(ray marching)算法的,这个步进的目的是为了能够根据步长来选择阶层式体素结构的分辨率层级,据我所知,DXR目前完全不提供ray marching的机制,它只有光线与几何体相交时才触发相关的shader调用。当然你可以说,如果我设置一个覆盖整个空间的几何体,然后在shader来做全部工作呢,那我说为什么不直接用compute shader呢,不然代码还要在DXR的管线里空跑一趟干什么呢?

以上关于VXGI的更多知识,《全局光照技术》中会有完整的一个章节的介绍;另外,关于DXR,我近期在发起一个全国的渲染技术线下巡讲活动,将在近几天开始报名,这个活动中会包含半个小时关于DXR的内容,敬请留意本公众号最近的动态。

在《硬影像》与罗登导演聊渲染技术

这周末,我参与录制了罗登导演(知乎: @Nordenbox)主持的《硬影像》播客节目,《硬影像》由 IPN 出品,由罗登主持,是一个关注影像之一切的播客。谈论影像背后的技术,历史和哲理。我们用比较通俗的方式讨论了渲染相关的许多话题和内容,大家可以访问以下链接进行收听。

收听地址:http://hardimage.pro/56

另外,由于实际说话的时候可能由于紧张,口误等原因,口述的内容可能没有文字的构句那么严谨,这里我也提供一个整理的文字版本,其中大部分内容是跟谈话内容相关的,但是注意这里不是访谈的文字版本,而是重新的描述。此外,这里可能并没有包含访谈的全部内容,而文字版本也可能稍微加了一点其它的内容。

什么是渲染?

渲染主要是指将一个用数字的方式描述的场景,转化为一副可视数字图像的过程。生成一副数字图像包括许多程序和步骤,例如物体的建模,场景的设置,游戏和影视中还包括物理模拟,动画控制,AI等等,其中渲染处于整个流程的最后一步,当前面所有流程结束之后,我们得到一个静态的场景描述,例如每个物体的3D位置,模型数据,贴图,摄像机位置和角度,光源设置等,然后渲染器执行渲染的过程将其生成一副2D的由像素组成的数字图像。由此也可以看出,渲染的流程相对比较独立于其它数字内容的制作流程,我们甚至可以很容易地针对不同(例如时间)需求对同样的场景使用或切换不同的渲染算法或渲染器。

形象的说就是,当每一时刻演员的动作完成之后,并且摄影师的镜头位置和方向确定后,摄像机要得到当前时刻整个可视场景的图像信息的过程。这个过程其实就是光照从光源发出,经过与场景的各个物体的反射或折射之后进入摄像机的传输过程,在术语上,渲染和光照传输其实就是等同的概念。当然这个例子有一点区别就是摄影的过程其实不是一个特定“时刻”而是一小段时间内接收光子的过程,也就是曝光时间,所以真实摄像机可以通过调节曝光时间来捕捉一些运动特征,如运动模糊(motion blur),然后数字摄像机则只能针对特定时刻进行计算,所以对于这种运动特征通常需要特别的方式来处理,例如在实时渲染中通过跟踪一个运动矢量(motion vector)来计算运动模糊效果,当然在离线渲染中我可以将光照传输函数加入进一个时间的维度,使得每个路径样本同时包含对时间的采样,来实现对所谓曝光时间参数的模拟。

渲染中最重要的技术要点是什么?

要回答这个问题,我们需要首先了解渲染器是怎样解决或者说计算上述的光照传输过程,传统解决光照传输最经典的方法是光线追踪,理解了光线追踪的思路,我们就可以很自然地看到光照传输的困难,进而明白渲染中最主要的一些技术要点。

首先什么是光线追踪?

为了在数字计算机中模拟光照传输,我们需要从光学中了解光的一些特征。我们看到的物体表面上每一个点的颜色,是来自于这个点所在的平面上空整个半球180度范围所有方向的光照的结果,因此当我们需要计算最终图像上特定一个像素的颜色时,它的过程类似这样:首先从摄像机沿这个像素的方向发射一条光线,然后光线会在半球空间发散成无数的光线,这些每条光线在空气中沿直线传播,直到遇到另一个物体时发生上述相似的发散过程,最后直到光线击中一个发光体而终止。同样的光照传输过程也可以反过来从光源向摄像机方向进行描述。

这个过程就称为光线追踪,其中每个由光源到摄像机(或者由摄像机到光源)的过程中所有直线的光线段连接起来就构成一条路径。因此为了模拟光照传输,显然每一个静态帧都需要产生大量的光线,这些光线的数量理论上是无穷的,实践中复杂的场景起码都是亿级别的。

那么实际上在程序算法上怎样解决这个问题呢?

在数学上,上述的光线追踪过程实际上是个高维积分,很难求解,一般使用的是称为蒙特卡洛(Monte Carlo method)的近似方法,该方法就是针对一定的概率密度函数每次产生一个随机的路径,这称为路径采样,然后计算这条路径的光照贡献值,最后把所有路径平均起来就得到每个像素的颜色值。这样的方法也称为路径追踪(Path tracing)。光线追踪算法的困难点其实有很多,例如焦散效果,体积渲染,间接漫反射光照等,以下挑选几个比较显著的。

首先是噪点比较严重

由于这些路径是随机产生的,因此有些路径产生的几率非常小,这就会导致比较大的噪点,所谓噪点就是由于这种随机性使得某些区域在早期得到更多的样本而使得这些区域内的颜色值过大,表现为那种比较白的亮点。在数学中,大数定律是能够保证在无穷的样本数量下,这些噪点最终是可以被完全消除的,但是这样的计算量和计算时间也是非常昂贵的;改善采样方法是可以减少噪点,所以当前离线渲染很多努力都是在开发一些更有效的采样方法,例如双向路径追踪,梅特波利斯算法,光子映射等。

光线追踪算法对处理器架构不友好

现代处理器使用的是一种多级缓存的架构,这些缓存的分级是根据访问速度来划分的,越快的缓存成本越昂贵,所以其容量非比较小,例如在一般的架构中,最靠近处理器的一级缓存,它的读取速度大约为1-3个时钟周期,但是其大小只有如32KB;二级缓存可以达到2MB,但是其读取速度却需要30个时钟周期,然后主存可以达到8GB,其读取速度为220多个时钟周期。这就好比说你在书桌上处理一件事情,你可能需要查询一些数据,让后你会在书桌上放一本或几本相关图书,需要的时候随时比较快的翻阅,但是可能有时候这几本书的内容是不够的,所以你需要起身到书房内的书架上查找另一些书籍,这就需要更多的时间,因为你需要起身行走的时间;然后如果你家里没有,你不得不去图书馆查询,这就需要更多时间;这里的书桌,书架和图书馆就好比一二三级缓存结构,书桌旁的书获取很快,但是只能放几本书,而图书馆的容量很大,但是需要花很多时间获取。而且除了容量,你每次携带的图书数量也是有限的,这称为带宽(bandwidth),也就是你每个时间只能携带多少数据。


因此,鉴于这种情况,理想的算法是,你的每个处理只涉及到同一本书,直到处理完同一本书才会需要其它书,也就是对书的需求不会出现交叉的情况。而缓存的情况也会自动获取相邻的内容数据,你在使用一级缓存的时候,二级缓存就会自动把这些数据附近的数据读取进来,这称为预取(pre-fetching)技术,如果你的数据访问是连续的,那么理论上你不需要更多时间等待。

然而在光线追踪中,光线在场景中随机穿行,因此对场景数据的访问完全是随机的,比如每次从内存中读取进来一个模型数据,可能只做一条光线的访问就没用了,然后下一条光线有需要访问另外的数据,这样整个场景的数据的大部分时间都停留在“运输”上,处理器大量时间处于等待状态。因此迪士尼自家渲染器Hyperion的最大特点就是对光线在执行相交计算之前按方向进行排序,这样使得每一束光线尽可能与相邻的物体相交,这些一次读取进缓存的数据可以被充分利用,减少运输成本。

什么是全局光照?

其实这是一个更主要是针对实时渲染的名词,由于离线的光线追踪算法的成本很高,所以实时渲染通常不计算完整的路径,而是只直接计算所谓的直接光照(direct lighting),即光线从光源出发,经过与场景中表面的一次交互之后,然后就进入摄像机,即是只计算摄像机直接能够看到的那些表面的光照,这样的直接光照能够被GPU的光栅化技术快速处理,实际上现代图形处理器最早就是为了加速对直接光照的处理而诞生,光栅化主要是对全部物体遍历一次,然后对每个点执行一次光照计算,其实也就是循环所有光源,看这个点能不能被光照照射,即有没有被其它物体遮挡,有照射则直接计算反射光照,没有就忽略。这样的直接光照又称为局部光照(local Illumination)。早期的游戏都是只有直接光照的,然而这样的光照结果显然不能满足要求,所以才引出全局光照(Global Illumination)这个名词,简称GI,由于多次反弹的光照计算成本很高,因此GI的实现很复杂,通常都是使用一些近似技术,我们后面再讨论。而对于离线渲染,它本身主要都是考虑完整路径的光照的,所以离线渲染中的光照传输其实天生就是全局光照。当然,早期的离线渲染器由于当期处理器的限制,其实算法跟现在的实时渲染差不多,所以在早期的离线渲染器中也有这样的区分。

什么是RenderMan RIS?

这是一个完全基于路径追踪的新版本,以取代基于Reyes的旧版本,Reyes是一种非常古老的近似方法,它还要起源于1987年Robert Cook提出的Reyes算法,它使用类似现代实时渲染的一些方法进行渲染,它不是基于物理的渲染,并且流程比较复杂,比如不同的效果需要使用不同的shader来实现,美术需要控制很多渲染相关的参数,修改起来非常麻烦,渲染器的修改往往需要美术人员学习新的技术。但是Reyes的架构还是非常稳健,高效的,所以直到去年的《魔兽世界》都还是使用基于Reyes的RenderMan版本。

也正是由于Reyes的稳健和高效,使Pixar放慢了对基于物理的更真实和高质量的路径追踪算法的开发和使用。基于路径追踪的渲染算法最早在1998年已经被蓝天工作室(Blue Sky Studios)使用于制作了短片《Bunny》,好像内地时光网上翻译为《棕兔夫人》,然后于2006年被用于制作第一步动画长片《怪兽屋》(Monster House),渲染器是Arnold。

使用RIS的流程则会更加简单,可以更集中于内容创作,编辑期的预览反馈更真实和实时。Pixar自家的《Finding Dory》及其后续Pixar自家电影都使用RIS,第三方电影更慢一些,例如《Tomorrowland》,《Doctor Strange》等都是基于Reyes的版本,《Warcraft》是工业光魔最后一部使用Reyes渲染的电影,《Rogue One》则是第一部工业光魔开始使用RIS版本的电影。RenderMan RIS比迪士尼自家的Hyperion都还晚,Hyperion的第一部电影是2014年的《超能陆战队》。

这是不是意味着RenderMan已经落于后于其它较早拥抱路径追踪的商业渲染器了?

这个问题当然不能简单地以拥抱路径追踪算法的早晚来定论,这是外行人的观点。我们以下从两个方面来说明,一个是RenderMan的技术架构,当然后面我们还会举例一些技术进行分析,其二是Pixar的技术团队的实力。

RenderMan RIS的技术架构

首先一句话描述,RenderMan RIS使用的几乎是目前世界上基于路径追踪渲染算法的最好的渲染器架构。路径追踪算法只是一种基本思路,实际每个渲染器的实现差异是非常大的,涉及的内容也非常多,很多渲染器都会针对自己已有的一些制作经验和流程对其中的某些部分进行特别优化,例如很多渲染器会将一些并行性比较高的计算转移到GPU去执行,或者对某些效果进行特别处理,例如将头发,布料,体积渲染,次表面散射等交给特别的渲染通道去执行,这些渲染通道可以使用一些(可能不是完全基于路径追踪的)近似方法。

上述这些改进和优化表面上看起来提高了渲染器的效率,然而却损害了路径追踪算法的整体架构,因为很多发表的论文都是针对一个特定的方面,而且大多都是在某种程度上的近似,这些方法跟路径追踪的思路反而是相悖的,因为路径追踪算法其实是一种很暴力(brute force)的方法,它保证最高的质量,但是却抵制近似,因此如果一个渲染器要加入某种近似,一定是需要对渲染器相应的方面进行特殊处理或对路径采样方法做出一些限制,例如Hyperion的光线排序虽然很厉害,但是它基本上只适用于单向路径追踪算法,而不能使用更高效的双向路径追踪算法以及其它更高级的如梅特波利斯算法,光子映射等,当然它们总是可以对渲染器进行修改以适应新的算法,但问题是这种改动量往往是非常大的,每次添加一个新功能都需要修改很多地方,甚至对美术制作流程做出影响。

RenderMan是怎样处理这个问题的呢?RenderMan更重视渲染器的底层系统架构,而将渲染器性能的优先级置于系统架构之后,RenderMan会很谨慎地随便加入一些上层局部的优化,它基本上只会考虑哪些最基础级别的重大的算法改进。它最初基于PBRT渲染器建立而来,PBRT是众所周知的非常好的路径追踪算法基本架构,拥有非常优秀和灵活的架构,它已经有十几年的历史,并且获得过2014年的奥斯卡科学与技术成就奖。RenderMan一直保持着这个基础架构,不会轻易加入影响这个架构的一些局部优化的内容,但是它在基础级别加入了最近几年比较重大的一些基础级别的新技术,例如VCM,UPBP(后面讨论)等,正是由于RenderMan维持比较稳固的基础架构,它才能以最小的改动成本加入这种基础级别的改进,反过来这种基础级别的算法改进对渲染器整体提升是非常重大的,而其它渲染器由于在上层做太多优化,使得要兼容新的基础算法不太容易,这不仅改动较大,可能影响整个美术制作流程,因此渲染器的发展反而会受到限制。

另一个方面是为什么RenderMan一直保持只使用CPU渲染,表面上看起来GPU能高效地做很多事情,但是其实路径追踪算法天然是对CPU更友好的,所谓的GPU渲染不过是需要花很多时间将渲染算法中可以并行的部分提取出来交给GPU处理的,但是这种提取工作非常繁琐,而且一旦基础算法改动,这些工作都要重来。当然RenderMan准备在22版本之后加入CPU+GPU的混合模式,称为XPU,这是因为现阶段基础算法发展已经比较完善了,这个时机开始做GPU的提取比较合

RenderMan的“技术团队”实力

放眼当今世界,在视效与动画领域,没有任何一家公司的研究实力能够超过迪士尼,迪士尼总共有5个比较主要的研究中心:皮克斯,工业光魔(ILM),迪士尼(瑞士)苏黎世(Zurich)研究中心,迪士尼动画以及卡耐基梅隆大学实验室。这五大研究中心的成果都是共享的,并且为了提高研究质量,这五个中心的研究工作甚至会交叉形成竞争,最后优胜出的技术被采用,而所有这些成果都是通过皮克斯的RenderMan这个出口进入到工业当中。所以可以看到几乎Hyperion具有的先进技术,都同时也被运用到RenderMan当中,例如发丝,布料,次表面散射,体积渲染等,同时由于前面说过RenderMan具有更稳健的基础架构,所以它甚至比Hyperion更容易采用最新具有重大意义的基础架构级别的成果,例如VCM技术,基于光束采样的UPBP体积渲染技术(后面会讨论)。

适应性采样

适应性采样在RenderMan中大量使用,例如一个1920 x 911 分辨率的静态帧有174 9210个像素,每个像素会发射上千条路径,传统的做法是对每个像素都发射固定数量的路径,然而根据图像的颜色分布不同,有些区域颜色变化比较小,因此随机路径出现的误差较小,这些区域可以使用更少的路径即可达到很好的效果,而另一些区域如物体的边缘或阴影边界,这些区域颜色变化比较大,随机数更容易产生更大的误差,因此可以对这些像素区域放置更多的路径样本,这种技术称为适应性采样(adaptive sampling),它能够根据图像分布自适应地调整每个区域路径样本的数量。

这样的适应性采样同样适用于巨量点光源场景中的光源选择,例如《寻梦环游记》电影当中的死亡之地(land of the dead)整个场景具有826 5557个点光源,也就是对于每条路径都需要遍历这800多万个光源,显然计算量非常高,如果我们在对光源的采样迭代过程中不断根据前面样本的误差分布对每个区域的采样分布进行适应性调整,即可以以比较少的光源样本选择达到比较好的光照结果。

降噪处理

对于路径追踪算法,当路径样本数量较少时,始终会有噪点,更多的路径样本数量可以减少噪点,增强图像的质量,但是这会花费更多的渲染时间,理论上需要无限的样本数量才能完全消除噪点。为了节省渲染时间,降噪技术(denoising)被引入渲染器中用于对使用较少路径样本渲染的图像结果进行降噪处理。降噪处理的思路类似而对图片进行滤镜处理,使图片变得更加平滑,但是离线渲染中的降噪还是要复杂得多,它使用的平滑的依据是局部区域内样本误差的大小,并根据误差分布来决定平滑的范围,其它一些像素信息如深度,法线等也被引入降噪技术以帮助更好地降噪。

降噪是近几年离线渲染领域的热点,也是光线追踪算法向实时渲染转换的关键技术之一,因为实时的光线追踪会使用更少的路径样本。

毛发渲染

毛发渲染是迪士尼和皮克斯的关键技术之一,2003年Marschner提出了渲染毛发的著名的Marschner模型,该模型将一根毛发描述为一个圆柱形的并在圆面上具有一定鳞片结构的线状结构,并描述了光在毛发内部的传播行为,遵循Marschner模型的毛发渲染能够呈现出比较真实的毛发效果,皮克斯在此基础上进一步发现使用椭圆形而不是圆截面的毛发丝更接近物理真实,因此提出改进的皮克斯Marschner毛发模型。

在Marschner模型中,一根毛发可以使用一个纹理当中的一条线段表述,该纹理被贴到一个曲面网格上,网格可以接受物理影响而使发丝跟随移动,而纹理上的每个线段只提供毛发的位置,它的尺寸和实际光照均由Marschner模型进行计算,该模型根据一个观察方向和入射光计算出毛发的真实光照颜色。

在很多渲染器中,毛发,次表面散射,布料等特殊效果都是使用独立于其它表面渲染的一个通道,也即是说在渲染完所有表面之后再对这些特殊效果使用单独的渲染流程进行特殊处理,这往往会使制作流程变得更加复杂,渲染算法架构也会更加复杂,而RenderMan现在可以将所有这些特殊效果融入到表面的着色计算当中,也就是说场景中所有渲染计算都是使用一个统一的路径追踪通道完成,这大大简化了制作流程,这也是得益于前面介绍的比较稳固的渲染架构。例如在渐进式的交互式阅览中,这些特殊效果能够跟其它表面渲染同步展现,而不需要等表面渲染完毕才开始渲染这些特殊效果,这大大节省了设计时间及提高了效率,在设计阶段预览的技术也称为live rendering。

体积渲染

体积渲染是RenderMan的另一个重要技术,所谓体积(Volume)是相对于表面(surface)的一个概念,比如在表面上光照只在每个表面位置处发射反射或折射,而在体积中,例如烟雾,云等环绕的环境中,由于空气中不再是真空,而是到处都充满着粒子,所以光在这样的环境传播时,会与分布于整个空间中的粒子发射碰撞而发射散射,因此体积中每个位置都需要计算光照交互,我们也称体积为参与介质(participate media),因为整个体积都是参与光照交互。

这样的计算量显然是非常大的,传统的方法就是对于一束穿过一个体积的光束,在该光束上执行光线步进(ray marching)算法,也就是随机选择该光束上的一些点执行光照计算,然后将所有采样点的光照累加起来,这样的技术也称为基于点采样(point sampling)的技术。

然而由于点采样满足不了体积内处处发生交互的这样一种连续的交互方式,所以渲染效果比较差,计算时需要使用大量密集的点采样,才能使光照效果看起来比较真实。于是,迪士尼苏黎世研究中心的Wojciech Jarosz(目前已经离开迪士尼任英国达特茅斯(Dartmouth)大学的助理教授)提出了具有革新意义的基于光束采样(beam sampling)的体积渲染技术,该技术使用一种特殊的方式直接计算体积中的一条光束(而不是一系列点)的光照,不仅大大提升了计算效率,而且提高了渲染质量,是离线渲染领域体积渲染的重要里程碑。

什么是实时渲染,它与离线渲染有哪些差别?

实时渲染是对渲染加了一个时间限制,即要求整个光照传输的过程在比如1/60秒之内完成,而在实时图像程序中,整个运行时的计算还要处理其它如动画,AI等其它工作,实际上留给渲染的时间更是只有几百毫秒。所以显然目前实时渲染不能使用上述离线渲染的光照传输方法,因为上述方法需要数分钟甚至数小时的时间来处理一帧的图像。

实时渲染算法与离线渲染算法的差异较大,主要表现为实时渲染通常将光照传输的过程分成两个方面,即直接光照和间接光照,直接光照是指光子从光源发射出后只与表面进行一次反弹即进入摄像机,而间接光照就是在所有需要经历2次及以上反弹的光照,后者又称为全局光照。

怎样计算直接光照,或者说渲染管线的基本流程

直接光照的处理通常是借用现代专用图形处理器(GPU)的光栅化流程来处理的,图形处理器的渲染管线循环遍历场景中的每个物体的每个顶点一次,并使用光栅化程序对这些顶点进行插值以计算表面上每个像素位置处的颜色,在计算每个像素的颜色时,我们直接计算来自光源的光照,即循环所有场景中的光源看是否每个光源对该像素形成光照,其可见性或者是否被遮挡由一个阴影贴图来判定,阴影贴图中存储的是每个光源所能看到的表面像素位置,它是通过向摄像机置于光源位置处,然后渲染一个全场景的图,并记录那些所有直接可见的表面像素位置。最后,像素之间的远近关系通过一个深度缓存来判断,深度缓存记录了当前已处理的图像上每个像素位置的深度值,在遍历后面的像素表面时,它将当前位置与深度缓存中已有的位置的深度值进行比较,如果当前位置更靠近摄像机,则丢掉深度缓存中之前存储的像素并用当前像素代替,同时存储当前像素的深度值至深度缓存中供后面比较使用。上述的流程是高度并行化的,得益于现代图形处理器的并行架构特征,所以能够被高效计算。

怎样计算间接光照,或者说常用的实时全局光照技术

间接光照的计算复杂度要远远高于直接光照,当前几乎没有任何方法能够实时完整的计算全部光照传输过程,所有方法都是基于一定的假设作出的一些近似处理。例如漫反射光照是与观察方向无关的,所以对于静态物体,其漫反射光照可以被预计算出来并存储在一个贴图中,然后在实时运行时就只有一个贴图操作而不需要执行光照计算;例如对于来自较远的环境的间接光照(如来自天空的光照),由于表面的位置相对于表面与这些环境的距离可以忽略不计,所以整个环境光只与方向相关,从而可以将整个环境的间接光照保存在一个环境贴图,在渲染的时候只需要计算出入射方向就可以从环境贴图中查询到一个光照值进行计算;对于动态物体,如人物角色,它的间接光照看起来无法预存,但是考虑到间接光照的变化频率是非常小的,所以我们可以在角色会经过的空间范围内存储一些比较稀疏的光照分布,类似于将间接光转换为一些“点”光源,然后当角色经过时可以使用附近的这些光源进行插值计算;几乎所有现代大型高质量游戏的渲染都涉及到很多这样的预处理计算。当然在实时渲染中还有很多对不同方面的一些近似方法。

现在实时渲染看起来非常逼真,那这样的实时渲染画质与离线渲染的差异到底在哪里?

上述的描述看起来实时渲染跟离线渲染的差异还是很大的,那为什么现代很多游戏的画质看起来感觉跟影视的画质差不多呢?其实我们之所以有这样的疑问,是因为我们的眼睛根本无法分辨精确的颜色,研究人眼识别周围环境光照的学科称为视觉感知(visual perception),所谓感知并不是一种精确度量,我们无法拥有对两个图像的真实差异进行分辨的能力,我们能分辨的误差具有一定的范围,例如人眼对于物体的边缘形状感知是非常明显的,如果没有阴影就没有立体的感觉,消除边缘部分的锯齿等措施就可以使眼睛的不适大大减小;例如对于任意一张图片,我们无法分辨这张图片中2%以下的误差,因此我们就可以忽略对这部分误差范围内计算。这些因素加上上述的一些高质量的预处理计算,所以我们会觉得一些实时渲染游戏作品的画质很高。

实时渲染有哪些应用场景?

现在人们开始越来越把目光投向实时渲染,例如很多动画短片都大量采用实时渲染来进行计算。另外,例如VR等应用场景对任意视角的渲染要求,也使得实时渲染的需求大大提升,可以预计实时渲染技术会对于很多需要对数字可视化的场景,例如医学成像,物理定律的可视化模拟,化学微观结构的可视化演示,军事化的模拟训练等等发挥较大的作用。

但是,目前实时渲染的结果只是对人眼是“正确的”,并不是对计算机是正确的,所以那些需要得到精密渲染结果而不是仅仅用于人眼观察的场景是不应该使用实时渲染技术的。

另外,在离线和实时的时间要求之间,还有一个交互式(interactive)的时间要求,例如很多3D软件中的需求,也就是在某种程序的编辑阶段,而不是最终的运行时阶段,我们可能不需要完全实时的程序,但是需要在几秒或者很短的时间内得到编辑结果的反馈,例如游戏和影视场景的编辑,在这种需求下,当前的实时渲染并不是一种很好的选择,因为他的最终结果需要依赖于大量时间的预计算;相反,基于光线追踪的技术,虽然得到最终高质量的渲染结果需要大量的时间,但是却可以在较短时间内使用少量的样本得到整个编辑的反馈,并且由于更多的时间花在后面对更小误差的处理上,实际上得到一个快速能够反馈编辑结果的时间是很快的,这方面一些离线渲染技术反而是更好的选择。

电影渲染是非实时渲染,以后会不会用到实时渲染中

毫无疑问,未来的实时渲染一定是光线追踪,这不仅是因为它的渲染结果是更物理真实的,还因为它简洁一致的光照传输模型,当前的实时渲染融入了太多繁杂的近似计算,这些近似处理并不是必须的,而是受限于硬件限制,但是这使得工程师要去了解非常多各种各样的近似技术。人类科技的发展是趋向于高度简洁和抽象化的,因为这也是人更易于理解的,光线追踪就符合这样的特征。

但另一方面,光线追踪的实时化并不仅仅是硬件发展的要求,路径采样基础算法架构的改进也是非常重要的,我们仍然还需要再算法层面做很多改进工作,甚至也有可能发现全新的光照算法。

怎么样,听/看完上述内容,是不是很想买一本《全局光照技术》来读一读呢?本书正在摩点网火爆众筹预购哦,已经超过12万的预定量,很多小伙伴已经在你前面踏上进军图形学的轨道上,此次众筹也是全宇宙最快最优先获取《全局光照技术》图书的途径,快去看看吧!

预购地址:https://zhongchou.modian.com/item/9055.html

https://www.fxguide.com/featured/pixar-deep-dive-on-sss-siggraph-preview/
https://renderman.pixar.com/news/presentations-renderman-art-and-science-fair-2017
https://www.fxguide.com/featured/rendermanris-and-the-start-of-next-25-years/
https://rmanwiki.pixar.com/display/REN/Sampling+Modes
https://rmanwiki.pixar.com/display/REN/PxrMarschnerHair
https://www.fxguide.com/featured/beam-rendering-extended-at-siggraph-2014/
Sorted Deferred Shading For Production Path Tracing
http://graphics.pixar.com/library/Reyes/
http://pbrt.org

反向路径采样在MLT算法中的运用

今年的SIGGRAPH还是蛮有趣的,以下介绍可能是有史以来SIGGRAPH同一年同时出现三篇思路非常类似的论文:

Reversible Jump Metropolis Light Transport using Inverse Mappings
Fusing State Spaces for Markov Chain Monte Carlo Rendering
Charted Metropolis Light Transport

故事要从PSSMLT和MMLT讲起。自从1997年Eric Veach的MLT(Metropolis Light Transport)算法发表以来,这个被称为影响20世纪科技发展最重要的马尔可夫蒙特卡洛方法(MCMC,Markov Chain Monte Carlo)算法被引入到渲染领域,与传统的蒙特卡洛方法(例如路径追踪)不同的是,它通过利用样本之间的相关性来更好地探索一个分布函数,使得一些非常困难的路径可以更轻易被采样到,然而MLT算法依赖于非常好的突变策略,原始的MLT算法依赖于完全的随机采样,根本无法了解场景的一些几何信息,突变路径的接受概率极低,使得MLT算法在相当一段时间并没有太大进展。

时间到了2002年,Csaba Kelemen提出了PSSMLT算法(Simple and Robust Mutation Strategy for Metropolis Light Transport Algorithm),如下图所示,考虑到路径采样其实就是以增量的方式从每个顶点的BSDF分布从采样得到一个方向,然后使用光线投射找到该方向与表面的交点,重复迭代直到一条路径连接光源和摄像机,这个采样的过程实际上是对多个[0,1]的随机数的采样过程,这些[0,1]随机数构成一个高维的单位超立方体(unit-hypercube),这称为原采样空间(Primary sample space),所以如果直接对该空间采样,也能够得到一条路径。于是PSSMLT(Primary sample space Metropolis light Transport)算法转而对该原采样空间进行突变,这带来一些好处,例如状态转移是对称的,另外最重要的是因为使用重要性采样,原采样空间的被积函数为f/p接近为一个常数,这使得原采样空间的被积函数更平坦,采样的方差更低,考虑传统的MLT算法并没有使用重要性采样。

然而PSSMLT也是有缺点的,其中最重要的一点是它将“路径采样”当做一个黑盒子:它直观给你一些随机数,不管你使用什么方法给我一条路径就可以,例如可以使用路径追踪或者光子映射来产生一条突变路径,这种原采样空间和原始路径空间的隔离关系使得原采样空间并不会估计路径空间的特征,例如原采样空间给定一个10个[0,1]随机数,路径采样器用到第2个时发现路径以及偏离种子路径很远了,如下图所示,这种结果称为涟漪效应( ripple e ects),因为基于出射方向采样的路径追踪无法预测后续顶点的分布,某个顶点一个微小的突变可能导致后续路径发生较大的变换,从而使种子路径和突变路径差异太大而丧失相关性,进而接受率变低。由此,PSSMLT算法在将近10年间并无太大进展。

MLT算法被提出来后最重大的一个进展要数2014年Toshiya Hachisuka提出的MMLT算法(Multiplexed Metropolis Light Transport),表面上看,MMLT只是将重要性采样引入到原采样空间,例如下图左边包含三个原采样空间,每个原采样空间对应一种特定的采样技术,技术路径采样的长度,这使得可以实现这样的功能:当有些路径突变长时间无法被接受时,我们有可能通过改变采样技术太快速找到突破的路径。在下图中,路径除了在每个原采样空间内部执行突变,还可以在不同采样技术之间执行突变。

但从知识理论角度来讲,MMLT的重要意义在于它将统计中的模拟回火(simulated tempering)的思路引入到了MLT算法中,特定地,这里使用的思路主要来自序列回火(serial tempering),回火的思路源自于模拟退火(simulated annealing),模拟退火本来用于解决最优质问题,由于物体加温之后分子状态之间的转移更活跃,因此状态更易于在全局转移,而随着温度逐渐降低,状态之间的转移就逐渐减弱。所以为了求最优值,如下图中的最大值,我们首先将温度升高,然后让其慢慢冷却,在其过程中不断寻找最大值,随着温度降低,最终将停留在最大值处。

模拟回火则是借鉴了模拟退火的思路,实际上它们并无太大联系(除了名字),模拟回火就是将模拟退火中的温度看成一个离散的函数,不同的离散温度值对应着整个状态空间的一种划分,这样状态可以在每个子状态内部转移,也可以在不同状态(即温度)之间转移。在MMLT算法中,温度即是采样技术,不同的采样技术将原采样空间划分为多个子空间。

至此,MMLT算法中路径空间和原采样空间仍然是相对隔离的,虽然MMLT算法中可以在原采样控制路径使用的采样技术,但是仅限于此。也由于这种隔离,另一个问题来了,即采样技术之间的突变也可能导致涟漪效果,如下图所示,当由摄像机向光源方向的单向路径采样转变为由光源向摄像机方向的路径采样时,由于桌子的遮挡,其突变路径将产生非常大的差异,从而很难被接受。

于是,我们本文的主角出现了。在上述情况中,当采样技术发生改变时,虽然所有的[0,1]随机数并没有发生变化,但是由于使用了不同的采样技术,这些随机数被使用的方式也完全不同了,从而到时路径发生了很大的变化。因此,理想情况下,我们希望在改变采样技术时,能够保持路径不变。因此, Benedikt Bitterli于今年提出的RJMCMC(Reversible Jump Metropolis Light Transport using Inverse Mappings)使用一个反向映射方法,当从采样技术1向采样技术2转移时,它将状态1对应的原采样空间的路径在对应路径空间中的形式,通过一个反向映射转换到采样技术2对应的原采样空间,这个过程是决定性(deterministic)计算的,不含任何采样的结果,由于它们在各自的原采样空间虽然具有不同的值,但是在路径空间它们的值是相同的,因此在计算MLT算法中的接受率时,所有项被约掉,接受率变为1。由此,我们通过一个确定性的方法产生了一个不同状态之间的转移,并且它完全被接受,这种采样技术之间的转移太高效了。

而今年的另一篇论文, Jacopo Pantaleon的CMLT(Charted Metropolis Light Transport)几乎也与上述思路类似,但是强调更泛化的概念,即将原采样空间按某种标准划分成多个不同的子空间,然后在不同子空间之间进行转移,在转移的过程中使用反射映射来保持路径不变。

HISANARI OTSU的Fusing State Spaces for Markov Chain Monte Carlo Rendering在算法上稍微不同于上述两篇论文,但是其使用的核心概念,即由路径空间向原采样空间的反向映射是一致的。HISANARI OTSU的核心思路在于组合路径空间和原采样空间的优势,例如对于路径空间的Manifold Exploration,其由于探索路径的局部流形空间的特征,因此突变路径的采样效率很高,然而它却不能有效考虑路径的全局特征,例如该路径使用的采样技术的权重。因此HISANARI OTSU将当前路径的状态保存在原采样空间,这包括路径使用采样技术的权重,但是它并不直接对原采样空间执行突变,而是使用流形探索对路径执行突变,但是与流行探索直接使用突变路径不同,HISANARI OTSU将突变的结果通过反向映射转换会原采样空间,然后提取其权重值,使得可以按全局对路径的采样结果给予评估,同时兼顾局部和全局特征。

今年这几篇论文质量还是可以的,并且更是有Wojciech Jarosz,Wenzel Jakob, Carsten Dachsbacher, Anton S. Kaplanyan等这些保驾护航。

确定性的路径采样 – 微分流形在MLT算法中的运用

介绍一篇路径采样的论文,作者Wenzel Jakob是PBRT的作者之一,他2016年获得Eurographics Young Researcher Award多半是因为这篇论文,该奖项每年仅有2个名额,用于奖励过去在相关领域做出重大贡献的人(敬礼)。

Manifold Exploration: A Markov Chain Monte Carlo Technique for Rendering Scenes with Difficult Specular Transport,以及后续的相关论文:The Natural-Constraint Representation of the Path Space for Efficient Light Transport Simulation

先总结一下,这两篇论文的本质是将传统的完全随机的路径采样转变为使用微分几何确定性地计算出一条“相似”路径,这种思路在路径采样中算是一种小小的变革吧,表现在两个方面:

  1. 从路径采样方法来讲,传统的无论是基于MC的(BD)PT还是基于MCMC的MLT,PSSMLT或MMLT等,本质上每条路径的采样都是使用Ray Tracing的方式从每个顶点的BRDF函数中对方向进行随机地(randomly)采样并连接起来形成一个路径,而Manifold Exploration是确定性地(deterministic)计算出一条路径。
  2. 从光照积分公式方面看,它从欧几里得空间转变到了流形上进行研究。

传统的路径采样是完全随机的,这里的随机可以理解为采样器不会考虑任何关于场景的几何特征而“盲目的”在路径空间行走;因此,对于那些存在于很小的区域,但是被积函数的贡献值非常大的“困难”路径,往往会由于采样概率非常低而使其估计不精确;虽然MLT算法引入了路径之间的相关性,但是本质上它只是通过限制一条突变路径各个顶点的取值在欧几里得空间的某个范围内,其使用的路径采样(例如双向路径采样)仍然是盲目的,其效率仍然非常低;然而MLT算法提供了一种绝对的优势,即一旦找到一条重要路径,我们可以更小心地探索该路径附近也可能具有同样重要性的路径。

很显然,要想有效地探索这些困难路径,我们必须了解并利用路径的一些局部几何信息,这是前面流形探索以及本节半矢量空间光照传输的核心内容。然而,要想让路径采样器(这里的路径采样器是指传统的根据光线追踪的路径采样,它几乎也是目前我们介绍的以及离线渲染中使用的唯一的路径采样器)直接能够感知整个场景中的几何信息显然是不可能的,要知道,光线追踪依赖于首先随机选择一个方向,然后对该方向使用光线投射来寻找其与表面的交点并取得几何数据,而不是先根据某种场景的几何特征选择一个方向。

这种不可能事先知道场景几何特征的采样方法,使得我们转向另一种思路:即首先通过传统的路径追踪得到一条随机的合法路径,然后提取出该路径的几何特征,进而利用这些几何特征来寻找一条该路径离开附近的路径。这种思路依赖于一条已知路径,显然它不能成为一种独立的路径采样方法,然而它却正好可以用在MLT算法中,因为MLT算法寻找一条相对于当前路径的突变路径。然而需要注意的是,局部特征的表述的精确性往往被限定在很小的局部范围(如前面镜面流形表述所描述的那样),因此这些算法必须很好地保证全局遍历性的要求。

那么,应该怎样提取一条合法路径的局部几何信息呢,费马定理提供了答案。1657年,费马提出著名的最小时间原理,即自然界的行为永远以路程最短为原则。按照这个原理,光永远是选这样一条路走,以使它在最短时间内抵达目的地,这就是费马定理(Fermat principle)。费马定理描述了光照传输的特征,如果已知一条合法的光线路径,它当然满足费马原理,因此可以从中提取与光照交互有关表面的几何信息。

然而费马原理是全局的,它用于描述一条完全的路径,直接推导出这种全路径与多个表面交互的关系是非常困难的。幸运的是,局部的反射定律和折射定理与费马定理是完全等效的,局部的反射和折射定理提供了路径顶点及方向关于这些顶点局部几何信息(如位置,法线以及这些量的导数)的关系,从而我们能够从一条已知路径推导出该路径的局部几何信息。

然后,已知了一条路径的局部几何信息了,该如何利用它们来产生一条“相似”路径呢,这时牛顿方法提供了答案。我们已知的顶点局部信息是关于对应表面在该顶点处的位置和法线关于局部坐标系的导数,导数能够被运用于一阶泰勒近似中用来表述局部的函数分布,然而这种近似不能直接用来作为采样值,我们需要精确值,而牛顿方法正式利用一阶导数用迭代的方式逼近某个设定的真实函数值。

于是我们能够通过一条已知路径获得一条“相似”或“近邻”路径,这条路径在MLT算法中具有较高的接受率,因为它探索了路径的局部几何特征。更为重要的是,上述的采样过程是确定性的:给定一条当前路径,我们没有依赖任何随机过程,而是使用微分几何相关的知识直接计算出一条“相似”路径,这种由随机向确定性的转变,提升了MLT算法的效率。

这里提到两篇论文Manifold Exploration和Half Vector Light Transport正式使用了上述思路,它们都是借助费马定理将一条已知路径和其对应的局部几何信息建立起了联系,然后利用微分几何以及牛顿迭代法确定性地计算一条”相似“路径,只不过这里Manifold Exploration通过降维的方式将路径空间转变到镜面流形上,而Half Vector Light Transport将其转换到半矢量空间。

其实就是什么意思呢,如上视频所示,给定一条初始路径,它能够不需要任何随机过程直接计算出所有满足初始路径类似的几何配置,并自动满足每个顶点处反射折射定理的相邻相似路径,而这正是MLT算法非常需要的。

聊聊最近几年的路径追踪技术的进展(一)

(注:本文是对《全局光照技术:从离线到实时渲染》一书中路径追踪技术相关内容的一些高度概括和总结,本文仅讨论概念和思路,详细的内容请参考原书相关章节内容,转载请注明源自:http://www.thegibook.com)

路径追踪技术(Path tracing,PT)已经是当下工业中离线渲染使用的主流技术,不管是商业渲染器如皮克斯的RenderMan,Solid Angle的Arnold等,还是迪士尼的in-house渲染器Hyperion以及Weta Digital的Manuka都是基于路径追踪技术。路径追踪算法非常简单,它首先将光照方程表述为面积积分的形式,然后一束光线从光源经过各个物体表面及内部多次交互(反射,折射,散射)后进入图像平面的贡献值(即辐射照度)被转换为这些表面交互点形成的路径的一个积分,其被积函数为这些表面的双向散射系数(BSDF),顶点之间的积分变量变化(change of variables)以及顶点之间可见性的乘积。在统计中,积分可以很简单地使用蒙特卡洛方法进行估计,因此光照传输的问题就转化为对场景进行路径采样,然后对每条路径的贡献值进行平均求和的蒙特卡洛积分计算。

尽管自基本的路径追踪算法被提出以来,各种增强改进的方法被整合进来,然而上述路径追踪技术的“基础架构”几乎没有多少实质性的变化。对于任何行业,工业中主流的技术一般不是当下最先进的技术,而是最成熟可工业化的方案,当前工业中的路径追踪技术优化主要集中在优化算法的执行效率,主要是针对处理器硬件架构进行优化,例如针对缓存系统的优化,增强数据局部性和指令局部性,以及改进光线连贯性(ray coherence)使其能够利用SIMD指令进行高效计算等,这方面比较突出的是迪士尼的Hyperion渲染器,一些渲染器的优化更是几乎能达到某些场景复杂度范围内实时渲染,例如Embree。

然而以上这些内容却不是本文关注的重点(上述内容会在thegibook中详细讨论),本文我们要讨论的是一些路径追踪算法基础架构层面的改进,这些算法还很少出现在当前工业解决方案中,但是确实未来的重要发展趋势。

传统的路径追踪算法是一个单纯的积分问题,因此可以使用蒙特卡洛方法来估计,然而蒙特卡洛方法的每个抽样是独立的,因此很难有效快速对一些比较困难的路径进行采样,一些很难被采样的路径需要巨量的采样数才能达到“令人满意”的结果,这导致非常缓慢的收敛速度。尽管开始的收敛速度非常快(4倍采样数量可以减少1/2的误差),但是越到后面会花费更多倍的时间。传统的方差缩减技术如重要性采样,分层采样,拟蒙特卡洛方法(Quasi-Monte Carlo)仍然不能改变这个收敛速度。

要提升蒙特卡洛估计的收敛速度,直观上,我们需要能够辨识每个图像的分布特征,然后在一些高频变化区域增加采样的密度。然而,传统的蒙特卡洛方法中每个抽样之间是独立的,它并不能有效辨识这种频率变化特征,尽管梅特波利斯光照传输(Metropolis light transport,MLT)通过采样点之间的相关性能够寻找一些困难路径,本质上它仍然并不善于处理和分析频率域特征。要想能够辨识图像的分布特征,我们需要了解每个路径的局部特征,即是我们需要对路径追踪算法引入微分运算。路径的微分涉及路径与附近局部范围内光线的差值,即图像的局部特征,因此它引入了光线之间的相关性,可以从多个层面改善路径追踪算法的效率(也正是如此,我们认为这是近几年路径追踪技术领域的重大进展)。

最近几年路径追踪领域的一些重大进展正是微分几何(differential geometry)的引入,由于微分反应的是流形(manifold)的局部变化,因此非常善于寻找图像分布中的高频部分,目前路径追踪算法中的微分运用主要包括:以通过计算纹理过滤函数实现反走样的光线/路径微分(ray/path differential)和协方差追踪技术(covariance tracing);以通过计算梯度图像用于利用筛选泊松方程(Screened Poisson equation)重建目标图像的梯度域渲染(gradient-domain rendering);以及通过将微分几何结合费马定理(Fermat principle)用来寻找镜面/光泽路径的流形探索(manifold exploration),半矢量空间光照传输(half vector space light transport)等技术;此外,微分还被用于适配性采样(adaptive sampling),成为重要的降噪技术(Denoising)。

以下我们就来从概念和思路上分析上述这些技术,当然我们可以提前知道的这些技术的一个重要共同点就是:这些微分计算通常不需要通过光线追踪引入新的采样点,否则那样的计算成本就很高,这些技术通常都是利用微分几何和某些假设进行单纯的微分计算,这里主要的工具是一阶泰勒展开式(first-order Taylor approximation)和顶点处的切线平面空间(tangent space),因此,这些新技术通常都可以很容易地集成于目前主流的路径追踪技术基础架构之上,更详细的内容请参考thegibook中相关章节。

接下来我们讨论的每一种微分的运用都涉及一个相对比较独立的层面,在阅读这些内容的时候,你首先需要非常清晰的了解的是它用来解决什么问题,因此我会在每一节的开头提出这个问题,然后读者可以围绕这个问题来阅读每一小节,即每一种技术。

光照传输的局部频率域分析

微分反应的是图像的局部特征,因此其在图像渲染中最直观的运用就是用于反走样(anti-aliasing)。光线追踪算法中由于采用不足导致的走样问题可以分为两大类:对路径空间(path space)的采样不足和对纹理空间(texture space)的采样不足,本质上这都是由于路径采样的不足导致的,但是它们通常使用不同的方法来解决。一个像素区域内的光线从屏幕空间发射出去之后,随着光线在表面的各种交互这个面积可能会无限扩散,所以单纯增加路径采样的数量可能也很难弥补纹理走样(texture aliasing)的问题。所以它们分别对应路径追踪算法中两个比较独立的反走样技术:路径空间采样不足主要对应于降噪技术,纹理空间采样不足对应于纹理过滤技术。

目前降噪技术主要的思路是针对图像的分布特征进行适配性采样以及适配性重建,前者对应于在图像的高频区域放置更高的路径采样密度;后者对应于根据图像特征对不同的区域使用不同的重建过滤器(reconstruction filter)。对路径进行适配性采样的方法可以分为两类:第一种直接对光照传输方程进行分析,称为先验方法(a priori method);而第二种只对屏幕空间的图像进行分析,称为后验方法(a posteriori method)即是说与路径采样的方法无关。

光照传输的局部频率域分析可以用于纹理过滤以及作为降噪技术中的先验方法。以下我们讨论局部频率域分析的方法和思路。

路径的局部频率域分析虽然不是源自光线微分(ray differential)技术,但是跟它有很大的联系。光线微分技术的核心思路是随着光线的传播跟踪该光线对应的频率区域一个像素的大小,这称为光线的足迹(footprint),如下图所示,在路径追踪算法中追踪每条路径的时候,同时沿屏幕空间x和y方向分别发射一条一个像素大小的偏移路径,然后对每条基础路径同时跟踪两条偏移路径。路径在每个顶点处的足迹大小则可以通过积分计算出来。当然光线微分技术并没有完全利用微分几何的知识,因为它假设偏移路径和基础路径在每个路径顶点处位于同于平面-即该顶点的正切平面(tangent space)上,所以光线微分的计算大大简化了。

由于假设偏移路径和基础路径和表面的交点位于同一平面,上述光线微分技术仅适用于镜面表面(specular surface),路径微分(path differential)在此基础上将光线微分扩展到了光泽面(glossy surface)和漫反射表面(diffuse surface),它虽然有比较理论的推导,但是实践上主要使用经验方法,即根据表面的粗糙度用来缩放足迹的大小以支持光泽面和漫反射表面。

上述的光线/路径微分技术实际上是光线的一种局部特征,传统的路径追踪算法中每条光线之间的独立的,所以不能够分辨这种局部特征。然而上述方法还是有很多缺点,例如光线经过多次传播之后可能形状非常不规则,而两条偏移路径计算的四边形无法表达这种形状;其次偏移路径可能被阻挡,而光线/路径微分是忽略这种阻挡的;为了更好的追踪光线的局部特征,我们需要更完整的对光线的传输过程进行分析。

目前对光线进行局部分析的方法的思路主要是将光线的局部特征表示为一个空间-方向分布(spatial-angular distribution)的局部光照场(local light field),如下图所示,黄色的中心光线表示基础光线,周围的一些具有不同位置和方法分布的光线是一些虚拟光线,它们共同构成一个局部的空间-方向分布。例如对于摄像机光线,它的局部光照场的分布就是一个像素范围大小的一个过滤器,该过滤器对于每个不同方向和位置处的光线都具有一个不同的权重值,这个过滤器就反映了摄像机路径的局部特征;对于光源路径,如果是面积光,则局部光照场的方向为固定值,而位置分布于面积光源的各个位置。

有了局部光照场的描述,剩下的事情就是计算该光照场随着中心光线的传输。早期的思路是将光线在传输过程中的各种交互过程看做一个操作函数,例如光线的直线传输(transfer),反射,折射,阴影遮挡等,如下图所示,然后在局部光照场函数的频率空间进行交互,这样就可以跟踪局部光照场随中心光线的传播过程。

上述的傅里叶分析过程计算成本相对较高,为了简化局部光照场的传输,协方差追踪(covariance tracing)技术考虑可以将一个4D的空间-方向分布近似为一个椭圆形高斯分布(elliptical Gaussian filter),如下图所示,然后该分布可以使用该4D光照场的协方差来表示,所以局部光照场可以用其协方差矩阵(covariance matrix)来表示。然后这些对局部光照场的传播操作数就转变为矩阵操作,最后在计算足迹的时候再从协方差计算出该4D局部光照场的尺寸,这就可以用来替代上述的光线/路径微分技术用来实现纹理过滤。

协方差追踪不仅用于纹理过滤中计算局部光照场足迹的大小,还被用于适配性采样,如果我们从光源路径方向追踪光源的空间-方向分布至屏幕空间,则我们可以在屏幕空间分析图像的频率分布,进而可以用于适配性采样,如下图所示。下图的局部光照场是一个5D空间,它还包含了时间维度,因此可以用于计算运动模糊(motion blur)效果,在该图中,首先从光源发出光线经过一次表面交互(即直接光)之后投射一个椭圆形分布到屏幕空间,然后根据这些分布就可以计算出图像的频率分布,这些分布特征被用于适配性采样。

除了协方差追踪,光照传输的局部频率域分析还包括其他一些方法,但是目前协方差追踪是更简单和高效的一种技术。当然协方差追踪的限制是它将局部光照场近似为一个椭圆形的分布,实际的局部光照场分布特征可能还需要更负责的形状表述,这也是未来的优化方向。

下一篇我们将讨论梯度域渲染和流形探索或者半矢量空间光照传输。

Robust Light Transport Simulation via Metropolized Bidirectional Estimators

今年SIGGRAPH Asia上最感兴趣的莫过于这篇Robust Light Transport Simulation via Metropolized Bidirectional Estimators,看标题就很牛逼:原本比较独立的光线追踪两大经典算法BPT和MLT合体了!这里简要描述下这篇论文的思路:

传统上我们认为光线追踪有三大基础算法:BPT,PM和MLT,它们都是相对比较独立的,因为它们各自采用不同形式的光照公式,例如BPT的路径积分形式,PM的范围估计,MLT则是将整个图像看成一个分布,这些看起来都是完全独立的。然而它们各自都有优缺点,好的想法是能不能把它们组合起来。

例如BPT的缺点是不能处理SDS,PM的缺点是处理diffuse表面不如BPT,MLT由于抽样点的相关性导致处理高光表面很低效,因为Markov chain始终在高频尖锐的部分徘徊,从整个图像上看stratification不够好;

2012年的VCM/UPS算法是一个很大的突破,它开始尝试将BPT和PM结合起来,使用PM对light subpath采样,并且将算法统一到BPT中,这样BPT就可以有效处理SDS。近几年中VCM/UPS几乎成了现在主流的离线渲染解决方案(参见The Path to Path-Traced Movies这篇论文);

然而VCM/UPS的缺点是,因为它仍然是BPT的思路,eye subpath并不知道light subpath的情况,所以尽管它能处理SDS,但是两个subpath连接的时候形成的很多full path由于可见性(尤其对于复杂visibility的场景)而对光照贡献率很低,而MLT则很擅长处理Visibility的问题,所以这篇论文就基于VCM/UPS来使用MLT对light subpath进行采样,这样保证了两个subpath之间的连接更符合最终图像分布。这篇论文也就同时把BPT,PM和MLT三大基础算法组合在了一起!

具体做法就是,首先使用传统MC在图像平面生成eye subpaths,这里不使用MCMC产生eye subpath的原因是MLT在图像平面(image plane)的stratification不好;然后从这些eye subpath的位置开始产生Markov chain来产生light subpath(所以MLT在这里是用来产生一个subpath分布而不是整个图像分布)。这样整个算法能处理高光和复杂Visibility这两大难题的场景。

论文下载:http://www.ci.i.u-tokyo.ac.jp/~hachisuka/

全局光照技术进化史1-光线追踪篇

本来计划是最近一年专心写书,不要花心思和精力写博客的,因为写一篇优质的博客文章其实也要花费不少的时间构思的:单篇博客虽然文字少但是你可能需要花费更多的精力在有限的篇幅内包括更多上下文信息,以及更精简地组织内容,在我看来它的创作付出不亚于图书内容写作(当然如果作者对自己要求没那么严谨的话可能也没那么严重)。

《游戏引擎全局光照技术》采取了一种新的出版形式,它从写作第一章开始,就积极和社区互动并开始宣传,其方式和游戏发行的思路一致:即在开发阶段不断推出测试版积极和玩家互动,并收集反馈信息进行持续改进。这样做的好处是:读者较早获得试读版的信息,了解和监督了书的写作质量,从而可以做出有效判断是否值得购买,糟糕的图书质量可能在这一阶段就直接被淘汰,甚至失去了出版意义,从而保障读者利益;同时对于作者,我能够持续吸收社区反馈意见以改进内容质量,使图书的质量可以不断地形成增益,好的内容能够被社区传播扩散;这对于读者和作者都是一件共赢的事情。

为此,我已经提供了该书1,2,3三章共计157页正文的试读内容供所有对该书感兴趣的朋友免费下载,如果您还不知道可以从这里下载。然而尽管如此,从目前社区讨论的信息来看,大部分读者还是不太明白这本书跟其它同类书籍会有什么不同,尽管我已经使用一个问答的形式来简要概述这本书的特点,然而我们都知道,这些文字跟你在技术大会上那些厂商递给你的一个介绍他们公司产品的小册子上的文字一样:在你使用它们的产品之前,那些文字通常跟屁没有什么差别。

所以我需要写一点更通俗篇幅相对长一点的文章来解释这本书的内容和特点,通俗使得您可以像读其它社交信息一样很轻松地进行阅读,不需要太多思考和理解,而篇幅需要长到足以介绍这本书覆盖的内容和特点。正巧在百度贴吧的“孤岛危机吧”看到一篇想要了解各种全局光照技术的特点及联系的帖子,他所提出的问题正是本书试图去讨论的内容,所以我就想回答了他的问题其实基本上能够说明这本书的内容和特点。

学习全局光照技术(Global Illumination,以下简称GI)比较头疼的一个因素是它的方法派别太多了,每个算法可能涉及到完全不同的数学方法,而如果我们没有对方法本身的思路具有一定的理解,在运用方面也不会很顺手,尤其涉及到要进行优化或修改以满足特定需求时,你必须要比较全面的理解该方法:它的起源,历史,数学模型,新方法的优缺点,它在计算性能和图像质量方面有着怎样的折中等等;并且,通常每种方法并不像一个软件模块那样比较独立很好理解,每种GI算法往往涉及CPU/GPU的数据结构表述,内存布局以及访问,和渲染管线其它阶段(如Deferred Shading,AA等)的协作,图形接口的运用,算法处理器级别的优化等,这些因素使得GI的学习并不那么轻松。

所以我在2015年初就萌生了写作一本围绕各种GI技术来进行内容组织的书籍,它不像《Real-time Rendering》这类书籍一样基本上以各个理论知识点为中心,它以方法为中心(尽管如此,本书还是包括了将近300页的基本理论知识的介绍),着重讨论各种GI方法背后的思路以及方法之间的联系,因此它较偏理论性的书籍拥有更强的实践性。这种写作思路其实类似于《Advanced Global Illumination》(简称AGI),但是AGI基本上主要围绕路径追踪和辐射度理论两种方法来讲述,其它一些如光子映射等有一定的介绍,但是篇幅极短;本书不但会介绍路径追踪和辐射度理论等这些离线全局光照技术,还会介绍时下比较流行的距离场,体素等实时的全局光照技术,并且本书结合Unreal Engine等游戏引擎来讲述,读者更够更好地理解这些引擎的功能特性。

这篇文章,我们就来看看全局光照技术的进化史。遵循通俗的原则,本文不会包含数学公式,全部内容是以文字和配图描述,当然这样的方式肯定不可能包含很多细节,它更注重的是思路描述,更具体的信息还请您参考《游戏引擎全局光照技术》图书内容。

我们从光线追踪算法开始。光线追踪算法的起源可以早至1968年,Arthur Appel在一篇名为《Ray-tracing and other Rendering Approaches》的论文中提出的Ray Casting的概念,我们称为光线投射,如下图所示,光线投射其实只是一根单一的从一个点向一个方向发射出光线,它与场景中的物体相交时停止,Appel的算法中使用了View Ray和Shadow Ray两条光线,这计算出来的其实就是光照方程中的直接光照部分。

Ray Casting

1979年,Turner Whitted在光线投射的基础上,加入光与物体表面的交互,是光线在物体表面沿着反射,折射以及散射方式上继续传播,直到与光源相交。如下图所示,这种算法形成了一个递归的光线穿梭,因此此时不再是一根单一的光线,而是形成了一个光传输的路径,此时的算法称为递归光线追踪(Recursive Ray Tracing,或者Whitted-style ray tracing);显然,光线在多个表面上反射或折射,间接光被考虑进来,光在经过每一个表面的时候,通过该表面的反射/折射率的“过滤”,它将物体的颜色渗透到邻近物体的表面上,这就是我们所说的Bleeding。

Recursive Ray Tracing

然而Whitted的模型是基于纯高光反射的,它假设物体表面绝对光滑,这显然和大自然中大部分物质的表面属性不相符。在计算机图形学中,一个像素的尺寸远远大于光的波长,在这个微观尺寸(Microfacet)下,物体表面是不光滑的,也就是说进入一个像素的多个光线可能分别被反射到不同的方向上,根据表面粗糙度的不同,这些散射的方向呈现不同的分布,非常粗糙的表面可能比较均匀地周围反射,而比较光滑的表面反射光则集中在光滑表面的反射方向附近。在现代渲染技术中,这些反射特性通常被使用Microfacet BRDF公式表述出来,它基本上使用一个简单的粗糙度方向就可以模拟出比较真实的光反射分布。结合金属性等一些参数,这就是目前流行的基于物理的渲染模型。

ray-optics-6

通常这些不同的分布被使用漫反射和高光反射两种分布来表述,如上图所示。1984年,Cook提出了分配光线追踪(Distribution ray tracing),他使得原来一束单一的反射光变为围绕一个空间中漫反射或高光反射范围内的积分计算,如下图所示。为了计算积分方程,蒙特卡洛方法被引入,所以Cook的方法又称为随机光线追踪(stochastic ray tracing)。

Stochastic ray tracing

Stochastic ray tracing

然而,Cook的模型计算代价非常高,每一条从摄像机发出的光线在表面点是被反射至多个不同的方向,分散成多束光线,以此递归,每条光线最终形成一个光线树(a tree of rays),尤其对于间接漫反射光,它几乎要反射至整个可见空间。

Cook的模型是由光照公式递归的特性决定的,光照公式中每个入射光的值来源于其它许多表面点反射的计算结果。1986年,Kajiya统一了光照公式,并推导出了光照公式的路径表述形式,使得光照公式由一个递归的结构,变成一个路径函数的积分,因此蒙特卡洛的每个随机数只要产生一条路径即可,这些路径不需要是递归的,因此每条路径可以随机生成,然后每个路径的值作为一个随机数用于计算最终的光照结果。这种新的形式称为路径追踪(Path tracing),如下图所示。在路径追踪算法中,首先在场景中物体的表面随机产生一些点,然后将这些点和光源以及摄像机链接起来形成一条路径,每个路径就是一个路径函数的随机值。这样的路径,根据场景的复杂度,每帧可能包括上亿条光线,因此传统的路径追踪算法很难运用到实时渲染领域。

path tracing

path tracing

上述这样的产生随机路径的方式有一个问题,有相当部分的路径组合由于表面间可能被遮挡而形成无效的路径,对最终光照没有任何贡献,因此大部分实现都是以增量的形式,在每个有效的反射或折射方向上进行随机采样,已形成更多有效的路径;

另一个问题是由于光源面积相对于整个场景很小,由摄像机出发的路径最终落在光源面积内的几率很小,因此双向路径追踪(Bidirectional path tracing)被提出,它分别从光源和摄像机两个方向出发,分别经过一定的路径之后,将该两条路径的终点链接起来形成一条完整的路径,这样大大增加了光源的有效贡献,可以从下图看出两者之间的区别。

untitled

当前大部分高质量的离线渲染器基本上都是基于路径追踪算法实现的,然而路径追踪的计算成本仍然非常高昂。现代路径追踪算法的发展主要有两大方向:其一是围绕提升上亿光线之间的连贯性(coherence)来提升处理器的利用率从而大幅提升计算效率,其二是微软Metropolis算法来使采样的随机路径更接近最终图像的真实颜色分布,后者称为MLT(Metropolis Light transfer)。

光线/路径追踪算法高昂的计算成本不仅来源于蒙特卡洛积分使用的大数定律要求的巨大的光线数量,另一方面重要的因素还在于路径追踪算法及其使用的数据结构不能适应现代CPU/GPU使用的执行模型。首先是内存执行模型,由于处理器计算单元的速度和内存数据存取的速度存在巨大差异,计算单元从内存中获取数据存在巨大的延迟(Latency),现代处理器非常严重地依赖于缓存技术,即将较大一块的内存数据缓存在具有更高读取速度的缓存中,如下图所示,缓存系统通常设计为多层机构,每一层比下一层具有更高的访问速度,但是更高速度的缓存硅片的成本更高,所以更高速度的缓存往往存储的数据量更小,这样顶层的一级缓存的速度跟寄存器的访问速度比较接近,通过缓存系统,计算单元到内存的数据访问延迟就被掩藏了。

path-14

缓存系统是根据传统应用程序的特点设计的,通常,相邻指令使用的数据在内存区域也是相邻的,所以相对寄存器更大一块的数据能够被多条指令使用。当指令从上一级缓存获取不到需要的数据时,就会从下一级缓存一次性获取另一块数据,并替换原来的数据,这种情况称为缓存失效。因此应用程序必须在数据上保持一定的连贯性,才能充分利用缓存特性,以提高计算性能。而路径追踪算法显然不符合这样的条件,每一条光线可能随机穿向任意一个方向,从而与环境中任意表面进行相交,所以相邻的指令使用的数据往往分散在内存中的各个区域,大大减少缓存命中的几率。

处理器架构的另一个特点是称为单指令多数据(SIMD)的计算模型,在SIMD中,寄存器一次性读取多个数据变量,这些数据被同一条指令执行,例如传统的CPU环境中SIMD寄存器可以读取128位数据,分别可以表示4个32位的数据,如下图所示,而在GPU环境下,每个GPU线程束可以一次性计算32个线程,当这32个线程所需要的数据在内存结构上相邻时,它们可以被一次性存储,大大减少每个线程获取线程带来的事务开销。

path-16-2

所以,基于连贯性(coherence)的路径追踪技术将这些数据分组成一些小的数据包,称为光线包(ray packet),这些数据包包含多个内存相邻的数据,并能能够被同一个指令执行。传统的基于光线包的技术主要是针对主要光线(Primary rays),即摄像机向场景发射出的光线,之后的光线可能向场景随处发射,并且对性能影响更大。

2013年,迪斯尼的Christian Eisenacher等在一篇名为《sorted deferred shading for production path tracing》的论文中提出了一种改进方法,这种方法的核心思想是在实际计算之前对光线进行排序,如下图所示。

path-10

在实际处理中,这主要分为三步(如上图左边的流程):首先,在每次增量计算光线与场景相交时,首先对光线进行排序,并将这些经过排序的光线按照方向以及数量大小分成多个包,然后以这些包为单位进行计算;其次,对场景建立一个BVH的加速结构,经过打包后的光线是连贯的,所以其相交计算涉及的场景表面在空间上也是连续的,因此能够比较友好地使用缓存和SIMD处理器特性;最后,由于来自各个方向光线可能与同一表面进行相交,所以在相交计算时直接计算光照反射并不是很高效,所以迪斯尼将着色分离出来,在相交计算的时候,所有相交点与纹理信息进行关联,纹理被划分成一些区域,然后着色计算以纹理区域为单位进行计算。通过以上这些优化,如下图所示,Disney新的路径追踪渲染器渲染性能得到极大提高,这些技术连同Disney的BSDF等技术一同被首次运用在《超能陆战队》以及后续的电影中。

path-12

基于连贯性的路径追踪算法的思想能够很好地利用现代处理器的架构特征,不管什么样的路径追踪算法基本上都可以在这方面进行改善,这也是传统路径追踪技术走向实时的方向。

基于Metropolis算法的MLT方法则着重于更准确地对路径进行采样,以计算更高品质的图像,毕竟传统的路径追踪算法很多路径采样的贡献率可能很低。Metropolis算法的核心思想是使用马尔可夫链(Markov Chain),它对当前随机数进行一个适当尺度的扰动(perturbation)以产生一个新的随机数,然后使用逼近真实分布函数的概率来对新的随机点进行取舍,这样使得新的采样点满足实际分布函数的分布。

qq20161106-02x

由于路径追踪算法每个随机数产生的是一个路径计算的光照结果,因此MLT中的每一个随机数是一个路径,这个新的路径根据一定的策略对前一路径的某些部分进行扰动,以产生一条新的路径,然后计算出的该路径的光照结果就是每个随机数计算出的光照数值。

由于MLT中的每个随机数是一个路径的结果,整个路径的分布就是整个图像的颜色分布,因此MLT计算出的是整个图像的结果,然后每个像素点需要使用过滤器对每个像素周围的颜色值按照一定的权重比例进行加权平均。

qq20161106-12x

原始的MLT算法直接在路径空间(Path space)对路径中的顶点进行扰动,这样新产生的路径可能存在被遮挡的可能,因此产生非常多的无效的被舍弃的随机数,Csaba Kelemen等于2012年的论文《A Simple and Robust Mutation Strategy for the Metropolis Light Transport Algorithm》中提出在一个超立方体(hypercube)作用域内,即所谓的Primary space对路径进行扰动,超立方体内的每个随机数是[0,1]范围内的均匀分布产生的随机数,这个随机数使用BRDF等分布的逆向变换算法求出实际的方向或者点灯随机数,这些随机数用于产生新的路径,这样的基于Primary space产生的随机路径具有较高的接受率。

qq20161106-22x

更新的基于MLT的算法基于路径求导来产生更好的符合表面光照分布的扰动,例如对于高光,它能够在高光方向上选择更多的方向,以使MLT计算的结果更接近于真实图像的分布,如上图所示。关于路径求导,以及其它如基于梯度的MLT算法等这种使马尔可夫链产生的随机数分布更加接近图像真实分布的思路,是路径追踪技术方向目前比较热门的主题。