文章

RTR 4th Ch09 Physically Based Shading

3 The BRDF

最终,PBR可以归纳为沿着一组观察射线,计算进入相机的radiance。我们将此要计算的radiance记为$L_i(c, -v)$。其中,$c$表示相机的位置,$-v$表示沿着观察射线的方向。负号的使用基于两点PBR中的符号约定:

  • $L_i()$中的方向向量始终指向远离给定点的方向,在这里即远离相机的方向
  • 观察向量$v$始终指向相机

在渲染中,我们默认场景中没有参与介质的存在,因此进入相机的radiance等于观察方向上离开最近物体表面的radiance,即:

\[L_i(c, -v)=L_o(p, v)\]

其中,$p$是观察射线与最近物体的交点。

所以,我们当前的目标是计算$L_o(p, v)$。某些情况下,物体的表面会直接发出radiance,但多数情况下,离开物体表面的radiance来自于其他地方,并最终反射到相机中。在本章中,我们只考虑表面反射与局部次表面散射,而忽略透明物体与全局次表面散射。也就是说,我们目前所关注的反射现象中,只依赖于入射光方向$l$与指向外部的观察方向$v$。我们通过双向反射分布函数BRDF来描述并量化这一现象,记为$f(l, v)$。

在最初的BRDF推导中,我们假设只存在均一的表面。换句话说,BRDF对于表面上任意位置的计算结果都是一致的。然而在现实世界中,物体的表面上几乎不存在完全相同的材质属性,从而导致不同着色点上会具有不同的视觉效果。由此,我们默认BRDF与物体的表面位置相关。

入射方向与出射方向各有两个自由度。一种常用的参数化方式包含了两个角度:

  • 关于表面法线的仰角$\theta$
  • 关于表面法线的方位角$\phi$

一般情况下,BRDF是一个关于四个标量变量的函数,如上图所示。但各向同性的BRDF是一个例外,它只包含三个标量变量,当观察向量与入射方向围绕法线旋转时,各向异性的BRDF将保持不变

由于我们忽略了荧光、磷光等自发光现象,我们可以假定,给定波长的光线会以相同的波长被反射被反射的光量则取决于波长本身。我们可以使用以下两种方式对其进行建模:第一种是将波长视为BRDF的额外输入变量,第二种是认为BRDF所返回的是光谱分布值。在实时渲染中,我们通常选择第二种方式,并且我们之前已经讨论过,实时渲染器将光谱分布表示为RGB三元组,这意味着BRDF最终会返回一个RGB值

在前面我们提到,PBR渲染中,我们最终要计算的是$L_o(p, v)$。而计算这个值的方式是使用反射方程,该方程也将BRDF包含在内:

\[L_o(p, v)=\int_{l\in \Omega}f(l, v)L_i(p, l)(n\cdot l)dl\]

其中,积分的下标$l\in \Omega$表示我们对于以着色点为中心的单位半球上的所有入射光方向$l$进行积分。该积分背后的核心思想在于:来自半球上任何入射方向的光线都会为着色点带来radiance贡献值。$dl$则表示对入射方向周围的单位立体角的微分。

总而言之,反射方程表明,观察方向上的radiance等于半球上所有的入射radiance乘以BRDF项再乘以法线与入射方向的余弦值。为了简化,在本章节的后续内容中,我们将忽略掉表达式中的点$p$,则新的反射方程表达式为

\[L_o(v)=\int_{l\in \Omega}f(l, v)L_i(l)(n\cdot l)dl\]

在计算反射方程时,我们通常使用球坐标$\phi$与$\theta$对半球进行参数化。在此前提下,微分立体角$dl$就等于$sin\theta_i d\theta_i d\phi_i$。这样的话,我们就可以推导出反射方程的二重积分形式:

\[L_o(\theta_0, \phi_o)=\int^{2\pi}_{\phi_i=0}\int^{\pi / 2}_{\theta_i=0}f(\theta_i, \phi_i, \theta_o, \phi_o)L(\theta_i, \phi_i)cos\theta_i sin\theta_id\theta_i d\phi_i\]

物理定律对于任何BRDF都有两个约束:互易性与能量守恒

互易性指的是交换入射角与出射角后,函数值不变。不过在实践中,用于实时渲染的BRDF通常会违反互易性,但能够满足特定的美术需求。

能量守恒则意味着出射能量不能大于入射能量。同样的,在实时渲染中,我们无需保证严格的能量守恒。

directional-hemispherical reflectance $R(l)$是一个与BRDF相关的函数,它可以用于衡量BRDF能量守恒的程度。实际上, $R(l)$是一个并不复杂的概念:对于一个给定方向的入射光线, $R(l)$计算该光线被反射到半球所有方向上的能量。从本质上来说,它计算了给定入射方向上的能量损失。数学表达式如下:

\[R(l)=\int_{v\in \Omega}f(l, v)(n \cdot v) dv\]

此外,还有一个与 $R(l)$在理念上相反的函数, $R(v)$,它的定义 与$R(l)$类似:

\[R(v)=\int_{l\in \Omega}f(l, v)(n \cdot v) dl\]

如果我们所使用的BRDF满足互易性,则有$R(l) = R(v)$。

最简单的BRDF是Lambertian BRDF,它对应了我们之前所讨论的兰伯特着色模型。在实时渲染中,我们通常使用Lambertian BRDF来表示局部的次表面散射。但需要注意的是,Lambertian着色模型中所使用的著名的$(n \cdot l)$项并非Lambertian BRDF的一部分,而是反射方程的一部分。

Lambertian BRDF本身是一个常数,而Lambertian材质表面的定向半球反射率同样是一个常数。也就是说,如果我们将$f(l, v)$视为一个常数,那么我们可以$R(l)$表达式中的积分部分,得到:

\[R(l)=\pi f(l, v)\]

进而推导出Lambertian BRDF为$R(l)/\pi$


4 Illumination

反射方程中的入射radiance,$L_i(l)$项,表示的是从场景中的其他部分照射到着色点表面上的光照。在全局光照算法中,会通过模拟光线在场景中的传播与反射来计算$L_i(l)$。这些算法使用到了渲染方程,而我们前面所提到的反射方程就是渲染方程中的一个特例。在本章节中,我们暂时不关注全局光照,而是专注于局部光照,也就是使用反射方程来计算每个着色点的局部着色情况。在局部光照中,$L_i(l)$默认是已知的,不需要我们进行计算。

在现实场景中,$L_i(l)$包含了来自所有方向的非零radiance,无论是光源直接发出的,还是经其他表面反射而来的。与引擎中所使用平行光或精准光源不同,现实世界中的光源通常是覆盖了非零立体角的面光源。只不过在本章节中,我们暂时只考虑有限形式的$L_i(l)$,仅由平行光与精准光源组成。

虽然平行光与精准光源是非物理的抽象光源,但是我们可以将其作为对于物理光源的近似,从而能够将这些光源整合到一个基于物理的渲染框架中。

我们可以回顾一下平行光源的推导过程。我们取一个很小且无限远的面光源,取向量$l_c$指向该光源的中心。同时,我们将面光源的颜色,$c_{\text{light}}$,定义为正对该光源的白色Lambertian表面所反射的radiance。在这样的假设下,我们可以推导出方向光的一种极限情况:即在保持光源颜色$c_{\text{light}}$不变的情况下,将面光源的大小缩小到零。这样,反射方程中的积分就可以得到简化,并最终得到以下形式:

\[L_o(v)=\pi f(l_c, b)c_{\text{light}}(n \cdot l_c)^{+}\]

精准光源的推导是类似的,唯一的区别在于,推导过程中的面光源无需距离着色点很小,并且$c_{\text{light}}$会随着着色点到光源的距离发生平方反比衰减。

此外,方程中的积分结果$\pi$通常会与BRDF中的$1 / \pi$相抵消。这样可以让反射方程更加已读,同时减少着色器中的除法运算。


5 Fresnel Reflectance

物体表面是指周围介质(通常是空气)与物体内部物质之间的分界面。而光与两种物质之间的平面分界面的相互作用,遵循菲涅尔方程

如上图所示,照射到平坦表面的光线会分为两部分:反射折射。其中,反射角度与入射角度相等,反射向量可以通过法线向量与入射向量计算得到

\[r_i=2(n\cdot l)n-l\]

我们将反射的光量记作,Fresnel reflectance $F$。在计算$F$时,我们需要考虑一下三个变量:

  • 入射角度$\theta_i$
  • 表面上方物质的折射率$n_1$
  • 表面下方物质的折射率$n_2$

菲涅尔方程本身有一些复杂,所以接下来,我们将描述一些菲涅尔反射的重要特征,而非直接给出其数学表达式。

5.1 External Reflection

外反射是指$n_1 < n_2$的情况,换句话说,光线是从反射率较低的那一侧发出来的。在大多数情况下,这一侧都是大气,其折射率为$1.003$,我们取近似值$n_1 = 1$。

对于给定的物质,菲涅尔方程可以被解释为一个只依赖于入射角度的反射函数,记为$F(\theta_i)$。原则上来说,$F(\theta_i)$的值在可见光谱上连续变化,但是在渲染领域中,我们将其视作一个RGB向量

$F(\theta_i)$具有下列属性:

  • 当$\theta_i = 0^\circ$时,也就是光线垂直入射时,$F(\theta_i)$反映了物体自身的属性。此时,我们将$F(\theta_i)$的值记作$F_0$,并将其视为物质特有的镜面颜色
  • 当$\theta_i$增大时,$F(\theta_i)$的值随之增加。
  • 当$\theta_i = 90^\circ$时,对于任何频率的入射光,都有$F(\theta_i) = 1$,也就是白色。

在镜面反射(mirror reflectance)的情况下,入射角度与观察角度相等。这意味着与表面呈掠射角度的入射光线,其出射角度也与表面成掠射角度,并最终到达相机,因此反射率的增加主要会出现在物体的边缘位置上(此处$\theta_i$更大)。此外,从相机的视角出发,表面反射率增加最剧烈的部分会因透视效果而缩短(foreshortened),因此这部分在画面中所占据的像素也更少。透视缩短与按照视角方向与表面法线之间的夹角的正弦值来对表面点进行投影的效果是一致的,所以在计算菲涅尔反射率时,可以使用$sin(\theta_i)$,而非$\theta_i$作为参数是更合适的。这段内容可以结合下图来理解:

从现在开始,我们使用符号$F(n, l)$来取代$F(\theta_i)$以表示菲涅尔函数。

菲涅尔方程不仅有一些复杂,还存在一些难以应用于实时渲染中的特性,所以,我们使用Schlick给出的菲涅尔反射率的近似值

\[F(n, l)\approx F_0+(1-F_0)(1-(n\cdot l)^+)^5\]

本质上,Schlick近似是在白色与$F_0$之间进行插值。并且,从数学表达式上可知,$F_0$是控制菲涅尔反射的唯一参数。这点对于美术来说是很方便的,因为$F_0$在$[0, 1]$的范围上表现良好。当然我们也可以通过折射率来计算$F_0$:假设空气折射率$n_1=1$,物质自身的折射率$n_2$记作$n$,则$F_0$的计算公式为:

\[F_0=\bigg(\frac{n-1}{n+1}\bigg)^2\]

一些渲染引擎使用了Schlick近似的更一般形式:

\[F(n, l) \approx F_0+(F_{90}-F_0)(1-(n\cdot l)^+)^{\frac{1}{p}}\]

使用此表达式可以让我们控制菲涅尔曲线在$90^\circ$时所过渡到的颜色,以及过渡的速度,从而使得近似更加精准

5.2 Typical Fresnel Reflectance Values

根据物质的光学特性,我们可以将其分为三大类别:电介质金属以及半导体

Dielectrics

常见电介质包括玻璃、皮肤、木材、混凝土等。电介质的$F_0$值较低,通常为$0.06$甚至更低,这种性质使得菲涅尔效应对于电介质来说更为明显。

电介质的光学属性在可见光谱上变化很小,其结果就是电介质通常具有无色的$F_0$值。下表包含了一些常见电介质的$F_0$值,可以注意到,我们使用了标量值而非RGB值,这是因为电介质的$F_0$值在RGB通道中的差异几乎可以忽略。表中同样包含了非线性编码的8bit值以及对应的色板。

在渲染引擎的金属工作流中,我们通常选择$0.04$作为默认的电介质的$F_0$值。这与常见的电介质$F_0$值相差不大。

一旦光线进入了电介质内部,就有可能进一步发生散射或吸收。我们会在后面的小节中讨论这一过程。

Metals

金属的$F_0$值通常较高,基于都大于等于$0.5$。同时,金属的光学属性在可见光谱上变化很大,其结果就是金属通常具有彩色的$F_0$值。

金属会立即吸收任何透射颜色,因此不会表现出次表面散射的特性。所以,金属的所有可见颜色都来自于$F_0$值。

Parameterizing Fresnel Values

对于电介质与金属,我们可以归纳出这样一个结论:金属材质没有漫反射颜色,而电介质材质的$F_0$值是一个有限的集合。基于此结论,我们通常会构建一种将镜面颜色$F_0$(specular color)与漫反射颜色$\rho_{ss}$(diffuse color)结合在一起的参数化方式。该参数化包含了一个RGB表面颜色$c_{surf}$一个金属度$m$。当$m=1$时,说明材质是金属,则将$c_{surf}$设置为$F_0$,$\rho_{ss}$设置为$1$。当$m=0$时,则将$c_{surf}$设置为$\rho_{ss}$。

5.3 Internal Reflectance

[TODO]


6 Microgeometry

本文由作者按照 CC BY 4.0 进行授权