AdvancedTopics

Advanced Topics in Rendering

高级光线传播方式

  • 有偏和无偏
    样本得到的期望值与总体的期望值相等,那么这种估计就被称为无偏的,反之则有偏
    有偏估计存在系统差,但是方差较小;无偏估计不存在系统差,但是在某些情况下方差较大
    有效性和一致性
    样本统计量的期望收敛于总体统计量的期望,则称这种估计是一致的

无偏光线传播方法

双向路径追踪(BDPT)

路径追踪利用了光路可逆性,通过形成相机到光源的单向路径来计算光照结果
双向路径追踪,就是从光源和相机分别打出一些半路径,最后连接两条半路径的端点,形成整条路径
BDPT的原理看起来简单,但实现起来非常困难 适用于光线传播在光源一侧比较好计算的情况 在光源由漫反射形成的场景中效果较好
BDPT

整个场景的光源只有左上角的聚光灯和右侧打向左侧的聚光灯,其余部分都由环境光照照亮,意味着使用传统路径追踪打出的路径的第一个弹射点大概率是漫反射表面,反射路径弹向光源的概率小,没弹几次就被俄罗斯轮盘终止了,很难计算到光源的信息,从而形成大量噪点。为了解决这个问题,从光源采样是一个优化方法,而BDPT则是另一个更高级的解决方案,从图中可以看出,双向路径追踪的效果是非常好

Metropolis Light Transport (MLT)

利用马尔科夫链做蒙特卡洛估计 主要区别在于采样方式 在对像素多重采样的时候,之前的蒙特卡洛估计都是均匀采样,而马尔科夫链通俗来讲就是在已采样样本附近生成一个新样本继续做后续估计,每个样本之间不再独立,每次对当前像素的采样都基于上次对该像素的采样,这种采样方法得到的pdf可以与被积函数形状保持基本一致,采样的效果也就比均匀采样更好
MLT

如上在已有路径(蓝)基础上加以扰动,得到新光路(橙)注意这里是对像素采样,而不是在解渲染方程

pros: 适用于复杂的光线传播情况,如半掩着门的房间,或者发生焦散的水体(SDS路径,specular→diffuse→specular)等,因为这些复杂的光线传播一旦找到一条路径,就可以不断在周围找到更多的路径,从而达到以更快速度获得更高质量渲染结果的目的

cons: 对于每个像素来说,其渲染时间是很难从理论上计算出来的,也就很难用来去渲染动画,并且因为所有的操作过程都是局部的,每个像素渲染时收敛所需的时间都不一样,这就导致图片看上去比较脏

有偏光线传播方法

Photon Mapping 光子映射

PM利用光源打出光线的过程可以被理解为不断打出光子的过程的想法
特别适合渲染水中焦散Caustics的现象

  1. 先从光源出发打出光子,让其在空间内传播散射,直到打到漫反射表面为止
  2. 然后再从摄像机打出路径,进行着色计算,着色点的亮度取决于光子的密度
  3. 着色计算: 对每个着色点,取其附近的N个光子,做密度估计(树状结构实现算法),$\rho = \frac{N}{A}$ (A可以由球形包围盒与表面求交得到(方法不唯一

cons: 在做密度估计的时候,N小了噪声会非常大,N大了图像又会变得模糊
光子映射本身就是一个有偏的方法,算密度应该用$\frac{N}{dA}$ ,而我们的密度估计时用的是 $\Delta A$, 只有$\Delta A$ 足够小才能做到正确估计,否则多少会有点糊
sol: 在一开始发射光子的时候就多发射点,提高采样数,那么同样多的N对应的 就会相对小,这种方法虽然有偏但一致(只要有一点模糊就是有偏的 一致性==对于无限多个样本不模糊)

Vertex connection and merging (VCM) 顶点连接/合并

把双向路径追踪和光子映射结合
双向路径追踪会发生两条子路径端点非常接近的情况(在同一个局部面积内),这时候BDPT就认为这种路径无效,就是一种浪费
对于这种情况,VCM就认为其中一条路径打过来的不是光线而是光子,用光子映射的方法把两条路径的贡献结合起来,避免了这种浪费

Instant Radiosity/ VPL / many light method 实时辐射度(IR)

将每个被照亮的表面都作为虚拟的点光源来看待,把光源打出的光线所打到的地方作为二级光源,计算着色时遍历这些二级光源叠加计算
pros:速度快,在漫反射场景中效果很好
cons:当虚拟光源离着色点特别近的时候,会出现反常亮点,类似漏光的现象,这和之前路径追踪对光源采样的距离平方项有关;另外,这种方法无法处理光泽材质

高级外观建模方法

非表面模型

散射介质

光线进入散射介质(雾、云)会发生两件事——被吸收或者散射
光线走多远被吸收,由介质的吸收能力决定;光线以何种方式散射,由介质的相位函数决定
渲染方法:直线传播 -> 散射 -> 直线传播 -> 散射 -> 直线传播 -> … -> 吸收
对每个发生散射的着色点,与光源连接,计算路径的贡献

头发/毛发

  • 人类毛发:
    Kajiya-Kay
    将头发丝看做一个可弯曲的圆柱 光线打到头发上会呈圆锥状散射(类似specular),同时又会被散射到四面八方(类似diffuse)diffuse+specular的模拟效果并不尽如人意

    Marschner
    将头发丝进一步认为“圆柱”由“角质层”和“皮质层”组成 光线的作用过程也更加复杂,总共分为三类:T:直接反射 TT:穿进“皮质层”,再从“角质层”穿出 TRT:穿进“皮质层”,在内部反射,再从“角质层”穿出

  • 动物毛发:
    除了角质和皮质,毛发还具有髓质结构,并且动物毛发的髓质明显比人类毛发的髓质粗
    DoubleCylinder
    在Marschner模型的T,TT,TRT基础上又加了两个计算项:TTs和TRTs
    TTs:TT传进“皮质层”时打到髓质发生散射,再从“角质层”穿出
    TRTs:TRT进入“皮质层”时发生发射,来回打到两次髓质,最后从“角质层”穿出

详情: https://zhuanlan.zhihu.com/p/330259306

颗粒材质

砂砾,谷物,粉末这些材质都属于颗粒材质,这些材质渲染的计算量非常大,但可以做一些简化,用百分比来表示单个渲染单元的组成成分,不过即使如此,颗粒材质至今仍然没有得到有效的优化

表面模型

导体(金属)与绝缘体(塑料)BRDF

https://zhuanlan.zhihu.com/p/21961722

半透明材质 Translucent

Translucent: 不仅仅是半透明,光线在内部还会有折射,比如玉石,水母
半透明是光线在材质内发生散射,最后从另一个点出来,对应到物理,这种现象被称为次表面散射
通常使用BSSRDF方程来描述次表面散射,它可以被认为是BSDF的拓展,BSDF计算贡献时只会计算当前着色点,而BSSRDF还需要考虑其他渲染单元射入的光线,因为这些光线在材质内发生散射后,同样有可能对当前着色点的能量造成影响
BSSRDF
也可以用Dipole方法做近似,即在表面上下各假设一个虚拟光源,来模拟次表面散射的光照效果

布料模拟

布料的微观组成:纤维 -> 纱线 -> 布料 (其中编制方法还分woven和knitted两种

  • 直接根据不同布料给出BRDF,Render as Surface, 简单粗暴 但无法渲染天鹅绒等材质(天鹅绒本身就不能归为表面模型)
  • 把布料看做是空间中的微小体积的集合,当做散射介质就像渲染云雾那样去渲染布料, Render as Participating Media, 计算量大
  • Render as Actual Fibers 将每一根纤维为单位进行渲染,计算量巨大

细节模型

带有瑕疵(划痕, 老化, 磨损…)
微表面模型使用法线分布来描述微观表面的起伏,但法线分布大部分是正态分布之类的简单分布
在计算镜面反射时,如果法线分布比较复杂,就很难建立有效的,从光源到微表面再到摄像机的光线通路
让每个像素打出路径时都对应一个范围,把整块范围内的法线分布整合起来得到P-NDF,从而简化计算
考虑微表面上光的波粒二象性

程序化生成材质

程序化生成并没有真正的生成材质,而是将这个材质信息定义为空间中的一些噪声函数,在后续生成时动态的查询它(存储三维的纹理会耗费很多内存)
噪声函数的应用非常广泛,比如可以二值化定义车锈 现在应用最广泛的噪声函数是柏林噪声(Perlin Noise),有了这些噪声函数,不仅可以程序化生成材质,还可以程序化生成地形,程序化生成水面等,另外,由于这个噪声函数是定义在空间中的,所以如果我们在空间里切割一块木头(或其他材质),是能看到里面的纹理的,这是二维材质做不到的
Houdini是目前工业上用来程序化生成材质的工具,它并非如上所述定义了函数供后续查询,而是直接生成了材质拿去用 这个工具也渐渐的成为了目前游戏TA必备的工具技能之一

×

喜欢就点赞,疼爱就打赏