首页 理论教育虚拟现实应用中的辐射度算法及其改进方法

虚拟现实应用中的辐射度算法及其改进方法

【摘要】:辐射度的算法分为三个步骤[26]。两个patch之间的形式因子表示了一个patch出射的光有多少比例会被另一个patch接收。辐射度算法会非常的慢,而且如果不考虑额外的复杂度,辐射度算法很难计算镜面反射,改进的辐射度算法可以缓解这一问题。很多研究者都试图结合光线追踪和辐射度这两种方法,以期达到各自的优势。对于,我们收集来自caustics map中的光子信息。即使是photon map算法,对于普通硬件,暂时也只能用于静态渲染。

辐射度的算法分为三个步骤[26]

(1)先把场景中的面划分为一个个小的(patch),然后计算两个patch之间的形式因子。两个patch之间的形式因子表示了一个patch出射的光有多少比例会被另一个patch接收。对于任意一个有n个patch的场景来说,总有n·(n-1)个形式因子。

(2)通过迭代法来找到一个光能传递的平衡状态。

(3)把第二步所产生的亮度值作为顶点色渲染。

辐射度算法会非常的慢,而且如果不考虑额外的复杂度,辐射度算法很难计算镜面反射,改进的辐射度算法可以缓解这一问题。很多研究者都试图结合光线追踪和辐射度这两种方法,以期达到各自的优势。

前面谈到,正向光线追踪才是最自然的光能传递的描述,由此,在1994年,有人提出了photonmaping算法。photonmaping是一个两步的算法,第一步通过正向光线跟踪来构建光子图,第二步通过光子图中的信息来渲染整个场景。它的核心思想是从光源开始追踪光能的传递,把每一个传递中间过程都记录下来,最后按照投影或者逆向光线追踪来收集这些信息,以达到渲染的目的。由于中间每一个光线和场景的相交都被记录下来,所以它很自然地避免了逆向光线追踪中重复计算的问题。

具体的,这两步算法又可以分为如下四个步骤[27]

(1)从光源发射出N根采样光线。光线的方向和光源的类型有关。采样光线的数目选择与光源自身的亮度有关,越亮的光源应该选择越多的采样。

(2)光子打到场景中,一步步传递,把光能传递的过程记录下来,结果放在k-d tree中。

(3)用逆向光线追踪或者反投影的方法找到可视点。

(4)使用逆向光线追踪和半球积分(如最终聚集)方法收集光子图中的信息,从而计算可视点的光亮度。

首先要选择一个光源,然后才能发射一个光子。对于场景中的多个光源,每次做发射一个光子采样的时候,不能完全地随机选择光源,一个光源被选中的概率要正相关于它的在该场景中的能量。

典型的光源一般被分为三种。

(1)点光源。点光源的数据结构仅仅是三维空间中的一个坐标。对点光源所发出的光线进行采样时,可以在包围该点的单位球上任选一点,然后以球心到该点的射线作为采样光线。也有人建议用单位立方体包围盒采样来代替单位球。

(2)方形面光源。方形面光源上的每一个点都可以看作一个只能从靠近面法向量一侧发射光线的点光源。

(3)其他光源。任意空间形状和物理特性的光源,只能具体问题具体分析。一旦选好了初始要追踪的光子向量的位置和方向,我们就可以开始一次正向追踪。

一般的,光子与场景中景物的相交情况可以分为如下。

(1)如果光子打到了镜面反射表面或者规则折射表面,不用做任何记录,继续追踪。

(2)如果光子打到了漫反射表面,则把光子所携带的能量和入射方向记录下来。如果入射光是折射或者反射光,则把光子记入caustics map,否则就记入全局map;其实,对于每一次相交,我们既可以记录入射光子,也可以记录出射光子。但是我们选择了记录入射光子。(www.chuimin.cn)

我们记录镜面反射与规则折射的光子信息是没有意义的,因为不可能把所有的镜面反射和规则折射过程都记录下来,所以这一类亮度还是要通过逆向光线追踪或其他方法来计算。但是记录漫反射过程中的采样信息是有用的。因为可以通过某一点的部分入射采样光子来近似地模拟该点的全部入射光子。然后可以计算该点任意方向上的出射光子。这也决定了只能记录入射光子信息而不是出射光子信息。记录入射光子还可以通过选择不同的brdf甚至不同的简化模型来重构每一次反射过程,这样就可以随心所欲的计算。

那么我们后面如何通过一点的入射光子来计算该点的出射光子呢,选择一个包围该点的范围很小的球空间,把这个空间里所有的入射光子按照半球积分模型计算,就可以算出该点的出射光子。

(3)如果光子打到的表面既有一定的镜面反射属性,又有一定的漫反射属性,则依据两种属性各自所占的百分比,使用俄罗斯轮盘赌原则来决定该次的反射属性。

(4)光子在决定了反射属性之后,还要依据反射属性再随机一次,以判定其是被表面吸收还是发射出去。

构造好光子贴图之后,我们就可以在第二步收集这些信息来计算顶点亮度。我们首先来看一个对光能半球积分简化过了的公式:

公式(3-1)中,L表示入射光的集合;f表示该点的表面反射属性集合;L(l)表示直接光照;L(c)表示纯粹的反射折射光;L(d)表示至少经历了一次漫反射的入射光;f(s)表示镜面反射或者规则透射brdf;f(d)表示漫反射brdf。L·f的结果就是出射光的亮度,我们要做的就是如何快速的计算L·f。

把上面的等式分化一下:

如果直接采用半球积分方程进行计算,需要大量的采样,这种分化把半球积分分化为四部分,对不同的部分采用不同的办法计算,这样每一种都不会产生大量的采样,合起来的计算复杂度远远低于原来不分开计算的。

(1)直接光源照射,反射属性为所有。

(2)入射光源为镜面反射或者规则透射或者漫反射,反射属性为镜面反射或者规则透射。

(3)入射光源为纯反射或透射,反射属性为漫反射。

(4)入射光源为至少经过一次漫反射的,反射属性为漫反射。

对于(1),我们采用shadow ray的方法计算直接光照。

对于(2),我们采用经典的蒙特卡罗光线追踪来计算。

对于(3),我们收集来自caustics map中的光子信息。

对于(4),我们收集来自全局map中的光子信息。

这样,一次典型的正向光线追踪的计算就完成了。即使是photon map算法,对于普通硬件,暂时也只能用于静态渲染。但是我们依然可以把它用在游戏中,比如在地图编辑器中对静态光源和大型静态场景进行预渲染,如果光源是变化的,那么对光源变化的过程采样,渲染后再通过插值计算来模拟光源变化。通过基于光线追踪计算出的图像,具有很高的光真实感,可以令用户产生赏心悦目的感受。