06 - 高级话题

这篇文章会说说高级光线传播和复杂外观建模相关的话题。

高级光线传播(Advanced Light Transport)

无偏的光线传播方法(Unbiased)

无偏:如果无论样本多少,算出来的期望值永远是对的。例如蒙特卡洛积分,它没有系统误差。

双向路径追踪(BDPT)

之前的路径追踪是单向的,利用光路可逆,从摄像机到光源。而使用BDPT (Bidirectional Path Tracing),光源和摄像机都会发出一系列半路径,BDPT会将半路径的末端点连接起来,就成了一条光路。

特点:

  • 当光源侧发出的半路径很好算时,选择BDPT
  • 难实现,很慢

Metropolis光线传播(MLT)

用马尔科夫链去做蒙特卡洛积分(MCMC,Markov Chain Monte Carlo)。

马尔可夫链就是在当前样本附近利用一些PDF(用任意函数的形状)生成下一个样本的方法,而当p(x)和f(x)形状一致时,使用蒙特卡洛方法效果最好。

例如下图,MLT的核心思想就是先找到一条光路(蓝色的),然后进行 局部干扰,生成一条新的光路(红色的),这一过程可以用MCMC解决。

特点:

  • 适合做 局部且复杂 的光路传播
  • 不清楚具体渲染时间;所有操作都是局部的,没有整体性,导致“脏”数据产生;不用来渲染动画

有偏的光线传播方法(Biased)

有偏:算出的期望值有一定误差的。

光子映射(Photon mapping)

通常用于渲染SDS路径(Specular-Diffuse-Specular)和Caustics现象。

通常的做法有两步:

统计好光子后,要进行 局部密度估计(Local Density Estimation)。对于每个着色点,找到周围最近的N个光子,看看它们的密度,越密就越亮。

而这个N的数量也有讲究,太少了会很noisy,太多了会很糊:

这是因为光子映射是 有偏一致 的:

  • 有偏(Biased):光子映射使用局部密度估计,正常的算法是dN / dA,而这里使用的是ΔN / ΔA,和期望的准确值有一定误差。
  • 一致(Consistent):对于极限情况,足够多的光子意味着相同光子会覆盖更小的ΔA,当ΔA趋近于dA时,结果和准确值一致。当然不可能打出无限的光子。

顶点连接和合并(VCM)

VCM结合了BDPT光子映射,它的核心思想如下:

  • 不浪费BDPT中半路径的端点。例如两个端点在一个平面上,此时这两个点不能被连接,但可以被合并
  • 使用光子映射将这两个“光子”的贡献结合起来

实时辐射度算法(IR)

IR(Instant Radiosity),也被称作许多光的算法。

主要思想就是 认为被照亮的面也是光源

方法:从光源发出许多半路径,认为半路径的终点就是虚拟点光源(VPL,Virtual Point Light)。然后再用这些新光源去渲染整个场景。

特点:速度快,漫反射场景应用好;接近着色点时,VPL会出现峰值(很亮);无法处理glossy材质。

高级外观模型

怎样描述材质就是怎样描述它和光线的作用。

非表面模型

散射介质

又称参与介质(Participating Media),例如云,雾。

在光线穿过这种介质后,会被随机吸收一点/散射到各个方向,例如光射到云里,被里边的小冰晶散射。

使用相位函数(Phase Function)来描述散射介质中任一点x处的光散射角分布:

渲染散射介质的主要思想如下:

  • 随机选择一个方向弹射
  • 随机选择一段距离直走,直到能量被吸收完
  • 在每个“着色点”,连接到灯光并计算一条路径的贡献。

由于是在介质里边渲染,渲染方程不再适用,由其他的方程代替。

头发与动物毛发(BCSDF)

头发也是一种特殊的材质,例如上图中,头发丝有两种高光:无色高光(发白发亮的部分)和有色高光(和发色相似但亮一点)。

对于这两种高光的显示,有许多人进行了分析:

Kajiya-Kay 模型

该模型指出,把一根根头发都看成是一个小圆柱体,光线打到圆柱体上后会散射出一个锥体。它的效果如下,显然不怎么好:

Marschner 模型

这个模型看起来更加真实,并被广泛应用。该模型把发丝看成一个内部有色素会吸收能量的玻璃圆柱,光线打进去后,会根据发生折射T和反射R的情况产生不同的传播方式(直接穿透TT,直接反射R,穿透一次并反射出去TRT)。

取发丝的局部,可见它分为两层:角质层(Cuticle)皮质层(Cortex)。该模型考虑了上边的三种传播方式,并取得了不错的效果:

渲染头发会产生多次散射,计算量大,渲染困难。

用人头发的Marschner 模型去渲染动物毛发,发现不对,说明动物毛发的渲染还需另一种模型。

从生物学角度,人的头发/动物的毛发由角质皮质髓质(Medulla)组成,而髓质很复杂,会散射光线。并且相对于人,动物的髓质会很大,更有可能产生光的散射。

而事实也是如此,模拟髓质是十分重要的

因此Yan提出了双层圆柱模型,重点模拟髓质:

光线通过髓质会发生散射,在头发模型的基础上,又多了两个传播方式:

最终效果如下:

颗粒材质

颗粒材质(Granular Material),就是类似于糖、盐等一粒一粒的材质。

对于一堆颗粒,没必要对所有颗粒进行显式建模,可以通过一些程序化的定义来简化模型:

表面模型

透光材质(BSSRDF)

透光材质(Translucent),应用到玉石、水母、牛奶,耳朵等。光线进入这种材质的物体后,会发生次表面散射(Subsurface Scattering),即在表面下发生散射,后从其他地方射出:

次表面散射BSSRDF和BRDF差不多,BRDF是一个点入射一个点射出,而BSSRDF则是一个点入射不同点射出:

将渲染方程的BRDF替换为BSSRDF时要注意,除了要对各个方向进行积分外,还要对表面面积进行积分:

当然,要是真那么算就会很麻烦,因此可以用两个光源来模拟次表面散射BSSRDF:

用BSSRDF去模拟人的皮肤,获得的效果更真实:

布料材质

首先先了解布料的结构:

纤维(FIbers)扭在一起可以形成一个股(Ply),三个股可以形成一个线(Yarn),而一堆线可以被加工成不同的布料。

当布料可以被看成是一个平面时,将其当成表面材质,根据不同的织法给出不同的BRDF:

但这样做就没法渲染类似天鹅绒的材质了,也能将布料看成是一个散射介质,通过单根纤维的特性和多根纤维的分布给出一个散射参数,进行渲染,但计算量很大:

还有最暴力的做法,把每一根纤维都渲染出来,得到的结果最真实,但计算量超级超级大:

细节材质

在之前的渲染中,渲染结果太完美了,反而有股不真实感(例如在现实中,用强光照射汽车,会发现车身上有和灰尘摩擦的划痕),因此引入了细节材质(Detail Material)。

在之前的微表面材质中,D(h)项描述微表面法线的分布情况,为了简便计算,用的都是正态分布,高斯分布等简单分布。如果为了真实感(基本符合统计规律,且附带更多细节),使用真实的分布,会得到更好的结果:

如果直接进行路径追踪渲染,会很耗时,因为路径追踪在微表面的镜面反射(法线分布很复杂)的情况下,很难建立有效的光通路以着色。

因此,为了简化计算,可以将一块区域(可以是摄像机一个像素所覆盖的区域,简称p-NDF)内微表面的法线分布提取为BRDF,把原来复杂的分布替换掉:

p-NDF在微表面上覆盖的大小不同,产生的效果也不同,越小越“独特”,越大越符合统计规律:

p-NDF在不同类型的法线贴图上产生的效果也不同:

之前都是用几何来解释这些细节,但这是不对的,因为当物体小到跟光线的波长差不多时,光就不是沿着直线传播了,必须假设光是一个波,因此要引入 波动光学

如图,这是几何和波动光学角度计算出的BRDF,可以发现两者相似,但波动光学的BRDF是 不连续 的 ,因为光有干涉现象。使用波动光学渲染出来的Macbook的C面细节如下:

可以看到不再是一层简单的金属材质,十分真实。

程序化生成外观

程序化生成外观(Procedural Appearance),可以利用3D噪声函数去生成一些3D材质,能进行实时查询,随用随取,不保存。

例如车锈效果,程序化地形生成(有名的柏林噪声函数),水面材质,木头纹理等。

参考资料

  • GAMES101-现代计算机图形学入门

  • 18 高级光线传播与复杂外观建模 (yuque.com)