April 22, 2019

PBR 基于物理渲染介绍

PBR全称Physical Based Rendering,基于物理的渲染。现在已经被广泛的应用到高质量的游戏渲染中。现在加深自己的理解,也作为一个记录留下来。

回顾一下标准光照模型的组成部分:

  • 自发光(emissive)
  • 高光反射(specular)
  • 漫反射(diffuse)
  • 环境光(ambient)

自发光(emissive)是物体自己发出的颜色,直接进入摄像机的光线,在全局光照计算下,会把周围照亮,而没有全局光照计算下,模型只是更加亮了一些。

高光反射(specular)是物体都会多少反射光,产生高光的亮斑,亮斑大小和亮度取决于物体的属性。

漫反射(diffuse)是模拟物体表面随机散射到各个方向光线的模拟。

在真实世界中,物体也会被间接光照照亮,为了简化,环境光(ambient)是来近似模拟间接光照。

Blinn-Phong光照模型关注的是漫反射和高光反射两个部分:

$$ L = C_{diff} \vec{n} \cdot \vec{l} + C_{spec}(\vec{n} \cdot \vec{h})^{m} $$

其中 $$ \vec{h} = \frac{\vec{l} + \vec{v}}{||\vec{l}+\vec{v}||} $$ $\vec{n}$ 是法线方向向量
$\vec{l}$ 是光线方向向量
$\vec{v}$ 是视角方向向量

这是一个经验模型,它的优点是计算快,易于使用,但是它并不完全符合真实世界的光照,所以基于非常多物理理论研究的基础,PBR诞生出来,为了建立更加真实的对光和材质之间的模型。

BRDF

BRDF的全称是Bidirectional Reflectance Distribution Function,双向反射分布函数。对于初学者来说非常难以理解。我们看一个改进后的Blinn-Phong光照模型:

$$ \begin{align} L &= \frac{c_{diff}}{\pi}\vec{n}\cdot\vec{l} + \frac{m+2}{8\pi}(\vec{n}\cdot\vec{h})^{m}\vec{n}\cdot\vec{l} \\ &= (\frac{c_{diff}}{\pi} + \frac{m+2}{8\pi}(\vec{n}\cdot\vec{h})^{m})\vec{n}\cdot\vec{l} \end{align} $$

括号内的东西,就是BRDF。

简单理解,BRDF就是计算颜色的一个公式系数,在大多数情况下可以用$f(\vec{l},\vec{v})$表示。直观的理解是给定光线入射方向和观察方向,BRDF计算出此处的光照幅度。

BRDF不是一个函数,而是一族函数,不同的论文,不同的模型提出的公式都不太一样,表现效果也不太一样,各有优劣。

在基于次表面散射、菲涅尔现象、能量守恒和微表面理论等的物理研究基础上,BRDF通常被分为漫反射项和高光反射项两个部分进行讨论。

漫反射项

在上述改进的Blinn-Phong光照模型中,漫反射项是一个常量$ \frac{c_{diff}}{\pi} $

Unity参照迪士尼的实现使用了更复杂的漫反射项:

$$ f_{diff}(\vec{l},\vec{v})=\frac{c}{\pi}(1+(F_{D90}-1)(1-\vec{n}\cdot\vec{l})^{5})(1+(F_{D90}-1)(1-\vec{n}\cdot\vec{v})^{5}) $$

其中,
$ c $ 通常是采样纹理得到的颜色
$ F_{D90} = 0.5 + 2roughness(\vec{h}\cdot\vec{l})^{2} $

$ roughness $ 实际意义表示了粗糙程度。这个漫反射项考虑了在掠射角漫反射项的能量变化。

这个漫反射项主要考虑次表面散射理论

次级表面散射

高光反射项

现实生活中,所有物体都或多或少有高光反射现象,但是并不是所有物体都是镜面反射,这里有一个微表面理论。

微表面理论

微表面理论中,只有部分微表面能接受到入射光,只有部分微表面会将光线反射到观察方向,这些反射过来的光线又有部分会被其他表面遮挡。所以物体会呈现出非镜面反射凹凸不平的感觉。

$$ f_{spec}(\vec{l},\vec{v}) = \frac{G(\vec{l},\vec{v},\vec{h})D(\vec{h})F(\vec{l},\vec{h})}{4(\vec{n}\cdot\vec{l})(\vec{n}\cdot\vec{v})} $$

$G(\vec{l},\vec{v},\vec{h})$ 阴影遮掩函数,描述光线在入射出射的过程中有多少比例被表面自身的凹凸不平给遮挡了。

$D(\vec{h})$ 法线分布函数,根据半角向量和平均法线的夹角,计算出指向半角向量方向的微表面法线的比例。

阴影遮掩函数在各种常见的PBR模型中最常见广泛使用的是Smith-Schlick函数:

$$ G(\vec{l},\vec{v},\vec{h}) = \frac{1}{((\vec{n}\cdot\vec{l})(1-k)+k)((\vec{n}\cdot\vec{v})(1-k)+k)} $$

其中,$ k = \frac{roughness^{2}}{2} $

法线分布函数,最常见的是Trowbridge-Reitz GGX函数

$$ D(\vec{h}) = \frac{\alpha^{2}}{\pi((\alpha^{2}-1)(\vec{n}\cdot\vec{h})^{2}+1)^{2}} $$

其中,$ \alpha = roughtness^{2} $

其次,根据菲涅尔反射原理,视角不同,反射光强度也不同。

于是高光反射项就由三个部分组成:

$F(\vec{l},\vec{h})$ 描述菲涅尔反射

$$ F = F_{0} + (1 - F_{0})(1- \vec{l}\cdot\vec{h})^{5} $$

其中,$F0$表示是物体的“反射率”,表示的是光线在垂直射向表面时,物体的反射率,这个反射率是由物质本身的原子结构决定的。在实际实验中发现,金属的$F0$通常都比较大,而非金属的$F0$都很小,所以在实际应用中,则是使用“金属度”来线性差值,计算出F0的值,如Unity中把$F0$的最小值规定成0.04

$$ F_{0} = Metalic \cdot Albedo + (1 - Metalic)\begin{bmatrix} 0.04 \\ 0.04 \\ 0.04 \end{bmatrix} $$

能量守恒

光线射到物体表面时,有部分发生折射被材料吸收,有部分反射出表面,总的来说,无论光线和物体表面如何交互,能量是守恒的。金属几乎吸收全部的折射光线,非金属几乎不吸收。在BRDF中,使用差值和对漫反射项和高光反射项进行差值:

$$ f_{BRDF}=k_{diff}f_{diff}+k_{spec}f_{spec} $$

高光项系数就是F0,其次漫反射项系数就是与高光系数的差值并且扣除被吸收的部分(使用金属度来进行模拟):

$$ k_{spec} = F_{0} $$ $$ k_{diff} = (1-k_{spec})(1 - Metalic) $$

至此,PBR的所有有关公式和内容都已经介绍完毕,在实际使用的过程中,各大引擎和厂商会根据性能、表现等等进行优化和公式改造,这里给出的只是比较常见的几组公式。

参考

Note

PBR提出,不仅仅是物体的表现效果更加真实,它还将渲染物体表面的工作流进行了标准化,把材质的变化限制在几个参数之中,根据工作流可以较为直接的得到想要的材质。