Skip to content

Latest commit

 

History

History
417 lines (303 loc) · 36.9 KB

14 - PBR:基于物理的渲染.md

File metadata and controls

417 lines (303 loc) · 36.9 KB

14 - PBR:基于物理的渲染

虽然所有的渲染在某种程度上都是“基于物理的”,但“基于物理的”一词意味着,在实践中,我们将严格遵循物理模型,而不是“现象学的”(经验之谈)。 “现象学的”(经验之谈),是一种启发式地捕捉主观感知特征的方法,比如在“正确”的地方放高光的经验公式。

本章涵盖了基于物理的高级渲染,定义了专用于本章的单位和术语,并提供了一种蛮力求解“路径跟踪”的算法,可以非常缓慢地生成非常精确的图像。 我们没有深入研究许多渲染算法的细节,但几乎所有这些算法都可以被视为对蛮力算法的改进。

注意,效率的提高是我们在电影和游戏中拥有逼真图像的原因,这是不容小觑的。我们不涉及这些细节,想看的话找 Pfarr 等人的 PBRT 书籍和代码库。

14.1 光子

在本章中,我们用大量光子集合的形式来描述辐射度量。请注意,在图形学中,“光子”并不一定准确地和它在物理学中表现得一样,许多物理学家在阅读图形学人员写的关于“光子追踪”之类的讨论时感到困惑。 对我们来说,光子通常只是一个携带能量得包裹,它的行为方式服从几何光学(光沿直线传播,但不具有波动特性)。

更准确地说,对我们而言,光子是一束光,它有位置、传播方向和波长 λ。 奇怪的是,波长的国际单位制单位是纳米(nm)。这主要是由于历史原因,1 nm = 10−9 m。有时使用另一个单位埃,一纳米等于十埃。 光子还有一项属性——速度 c 只取决于它所经过介质的折射率 n。有时频率 f = c/λ 也用于光。f 很方便,与 λ 和 c 不同,当光子折射到具有新折射率 n 的介质中时,f 不会改变。 另一个不变的度量是光子携带的能量 q,由下式给出: $$q=hf=\frac{hc}{\lambda}$$ 其中 h 是普朗克常数。虽然这些量可以在任何单位制中测量,但我们将尽可能使用国际单位制。

14.2 光滑金属

对于光滑的金属,光要么像 4.5.4 节中描述的那样反射,要么被折射到表面,然后迅速吸收(薄涂层金属得表现有时和玻璃相近,你可以看到光一路穿过,金属实际上不是不透明的)。 反射光的量由菲涅耳方程决定。方程很简单,但很麻烦。此外,它们的值随光的偏振而变化,这是图形学中通常忽略的一个特性。菲涅耳方程的主要视觉效果是反射率随着入射角的增加而增加,特别是在接近掠角的地方,它达到 100%。

几乎所有的图形程序都使用由 Schlick(1994)开发的菲涅耳方程作为简单近似。 对于金属,我们通常指定正入射时的反射率 R0(λ)。反射率应根据菲涅耳方程而变化,Schlick(1994)给出了一个很好的近似。 $$R(\theta,\lambda)=R_0(\lambda)+(1-R_0(\lambda))(1-\cos{\theta})^5$$ 式中 θ 为光传播方向与表面法线之间的夹角。 这里,这个近似值允许我们通过数据或肉眼来设置金属的法向反射率。

14.3 光滑电介质(绝缘体)

电介质是一种能折射光线的材料。有一种很好的启发式的记忆方法——如果材料不是金属,那它就是电介质。 因此,皮肤、牛奶、头发、布料和几乎所有日常材料都是电介质,尽管它们往往是不透明的,因为它们是不同折射率和吸光杂质的混合物。但是光滑均匀的电介质(匀质)是透明的,例如玻璃、水和眼睛里的晶状体。

对于光滑的电介质,只有三个重要的性质:

  1. 在每个入射角和波长反射多少光。
  2. 当光以给定的距离和波长穿过材料时,有多少部分被吸收。
  3. 反射光和折射光的方向是什么?

反射:Reflection 折射:Refraction

14.3.1 电介质的反射率

光的弯曲方式以及反射/透射的比例取决于材料的折射率 n(λ)。 对于电介质,其反射性能也可以用 Schlick 方程来描述。然而,当其中一种材料是空气时,我们可以用 n(λ)表示 R0(λ) $$R_o(\lambda)=\Big( \frac{n(\lambda)-1}{n(\lambda)+1} \Big)^2$$ 在方程两边的折射率不为 1.0 的情况下(如空气或真空),则适用此公式: $$R_o(\lambda)=\Big( \frac{n_t(\lambda)-n_i(\lambda)}{n_t(\lambda)+n_i(\lambda)} \Big)^2$$ 通常,n 不随波长变化,但对于需要表现色散的程序(不同波长相互分散,得到彩虹),n 是可以变化的。 通常有用的折射率包括水(n = 1.33),玻璃(n = 1.4 至 n = 1.7)和钻石(n = 2.4)。

透射的光量就是没有被反射的光量(能量守恒)。所以我们不需要显式地计算传递分数的公式。

14.3.2 反射与 Beer 法则

电介质也会过滤和折射光,有些玻璃滤除的红光和蓝光比绿光多,所以玻璃呈现出绿色色调。 当光线从折射率为 n 的介质传播到折射率为 nt 的介质时($n_t\gt n$),如下图所示 斯涅尔定律告诉我们: $$n\sin{\theta}=n_t\sin{\phi}$$ 计算两个向量之间正弦通常不像计算余弦那么方便,余弦是单位向量的简单点积。 使用三角恒等式 sin + cos = 1。我们可以推导余弦的分数关系: $$\cos^2{\phi}=1- \frac{n^2(1-\cos^2{\theta})}{n_t^2}$$ 为了将$sin\phi$和$cos\phi$转换为 3D 向量,我们可以在曲面法线和光线方向的平面上建立 2D 正交基。 n 和 b 形成了折射平面的一个正交基。通过定义,我们可以用这个基来描述变换后的光线的方向: $$t=\sin{\phi},b-\cos{\phi},n$$ 因为我们可以用相同的基来描述 d,并且 d 是已知的,我们可以解出 b(直接用 n 和 d 解出 b,而不使用叉乘的技术): 接下来直接解出 t(只用 b 和 n): 注意,不管 n 和 nt 哪个更大,这个方程都成立。一个直接的问题是,“如果平方根下的数字是负的,你应该怎么做?” 在这种情况下,没有折射光线,所有的能量都被反射了。这就是所谓的全内反射,它是玻璃物体丰富外观的主要原因。

对于均匀的杂质,例如有色玻璃,根据比尔定律,携带光线的强度会衰减。 当射线穿过介质时,它的强度损失按$dI=-CI,dx$计算,其中 x 是距离。因此,$dI / dx=-CI$。我们可以解这个方程得到指数$I=k\cdot \exp{-Cx}$衰减程度用 RGB 衰减常数 a 来描述,它是经过单位距离后的衰减量。 引入边界条件,我们知道$I(0)=I_0\space and \space I(1)=aI(0)$。因此,最终公式: $$I(s)=I_0,e^{\ln{(a)}s}$$ 式中 I(s)为光束在距离界面 s 处的强度。我们也可以把它写成: $$I(s)=I_0,a^s$$ Beer 定律的影响可以在图 14.3 中看到,玻璃呈现出绿色。 这种效应也适用于透射光。请注意,光被反复反射和折射。通常,只有一个或两个反射图像是容易看到的。

14.4 拥有次表面散射的电介质

只需使用光滑的电介质,我们就可以渲染一系列令人惊讶的材料。许多看起来无光泽和不透明的表面可以模拟为多个电介质。 考虑一个完美的冰块。它看起来像一块玻璃,只是其折射时扭曲光线的程度较小(冰的折射率比玻璃低)。现在在冰块内部放置许多小球形气穴,随着添加更多气泡,冰块将变得越来越不透明。

散射也许是我们所观察到的不透明现象的重要原因。 使冰块看起来不透明的另一种方法是使表面变得粗糙。这可以在模型上通过细分表面然后对每个三角形顶点的位置进行小的扰动来完成。它的效果很像磨砂玻璃(本质上是那种粗糙的表面),扰动越粗糙,就会出现不透明度。

通过插入具有颜色的粒子可以实现进一步的复杂性,从而激活比尔定律。这是一个相当简单的模拟涂料的极其精确的方法。

我们能找到一大批材料,这些材料的复杂度可以通过显式建模它的微观结构来模拟。例如,人类皮肤可以建模为粗糙的表面和折射率略有不同的颜料颗粒层和血液(都遵守比尔定律)

14.5 暴力求解的光子追踪器

假设我们将场景建模为具有微观结构的电介质,然后用一盏灯照亮物体。我们怎样才能最简单地渲染它并生成图像呢? 在本节中,我们讨论如何蛮力模拟光子,然后如何从传感器反向发送伴随(向后)光子。这实际上可以产生一些最好的图形,用很少的代码,但会非常慢。

14.5.1 传感器

为了生成图像,我们必须对图像捕获设备有一些概念。 一个简单的组成是:一个简单的传感器阵列(像 CCD)和一个有一个小孔的盒子,就像一个针孔相机。阵列中的每个传感器本质上都充当光子计数器(某些波长比其他波长引起更多的响应)。 在用光子轰击它之后,传感器阵列将具有可以作为图像写出来的值。接收到少量光子的传感器将被写入黑色,而接收到大量光子的传感器将被写入白色,在两者之间有不同的灰度。

为了生成彩色图像,我们可以在传感器前以某种模式放置红、绿、蓝滤光片。 最简单的滤波器是带通滤波器:

  1. [400,500 nm] 蓝色
  2. [500,600 nm] 绿色
  3. [600,700 nm] 红色

如果将所有的传感器初始化为零,那么全响应意味着当光子击中传感器时增加传感器中值的大小。

14.5.2 光子追踪器

为了跟踪光子,在光源上随机选择一个点,随机选择一个方向和 400 到 700 nm 之间的随机波长(其他波长不会影响传感器阵列,因此不需要计算)。 当它碰到一个表面时,计算它的反射率并决定是反射还是折射。这个决定是通过计算波长和入射角的 Schlick 方程近似得出的,我们称它为 R,现在生成一个均匀随机数 ξ∈[0,1]。 如果表面是金属的,那么光子在折射的情况下被吸收,我们在光源处生成一个新的光子。

如果光子进入电介质,而比尔定律系数不是 1(意味着它像绿色玻璃一样吸收光),那么光子可能被吸收(从而死亡)。我们使用与决定反射和折射相同的基本技术来决定:

比尔定律的系数是 a:$I(s)=I_0,a^s$

14.5.3 运动和散焦模糊

上面的针孔相机将产生非常清晰的图像,就像一个真正的针孔相机。但这需要长时间的曝光,因为很少有光子能够幸运地在被吸收之前穿过针孔。

我们可以解决这个问题,在相机上增加一个镜头——把针孔变大,把镜头放在针孔里。我们可以模拟一套真正的复合玻璃透镜,或者我们可以插入一个理想的薄透镜。

我们可以把最简单的玻璃透镜建模成两个球体的重叠部分(“双凸球面透镜”)。 这有不错的成像特性(虽然不如大多数真实相机中的复合镜头好),并且很容易写出光线求交的代码。

薄透镜是一种理想的透镜,它是无限薄的(光线跟踪程序中的圆盘也是如此),只指定半径(透镜的物理尺寸)和焦距 f。薄透镜可以通过确定以下三个属性来实现:

  1. 离开三维点 p 到达透镜中心的光线不会弯曲(我们称这条线从该点穿过 p 的中心线)。
  2. 所有离开点 p 到达透镜的线都会在透镜之后汇聚在中心线上的点 q。
  3. 点 p 沿透镜光轴的距离 a 和点 q 沿透镜光轴的距离 b,符合薄透镜规律:$1 / a+1 / b=1 / f$

请注意,使用真实或理想的镜头会自动产生真实照片中出现的那种模糊,通常称为散焦模糊(失焦)或景深。

为了解释运动模糊,移动的物体在照片中被模糊,或者移动的相机模糊了不以与相机相同速度移动的物体(例如,从火车上拍摄的照片,火车内部很清晰,风景很模糊)。 为了使用运动会模糊:

  1. 光子是在相机记录(或相机快门打开)的时间间隔内以随机时间从光源发射出来的。
  2. 光线追踪器支持将时间作为变量纳入程序的计算。

一个简单的运动物体的例子是一个球体,它的中心沿着一条基于时间的直线运动: $$c(time)=g+time*(h-g)$$

14.5.4 反转时间

上面的光子追踪器可以工作并且工作得很好,只是会很慢,因为即使在你插入一个镜头之后,大多数光子也不会击中镜头。

通常在图形程序中做的事情是反转时间,从相机发出射线,并在射线击中光源时记录下来。这在我们制造的光子追踪器中非常容易。 相反,我们从每个像素发出光子 (技术上说是伴随光子),看看它们在哪里碰到光源。 这些光子的波长是通过将彩色滤光片作为彩色光线发射器处理的,当我们碰到光源时,我们用发射光的权重记录光子 (在像素传感器阵列上)。

14.6 辐射度量学

实际上,上一节的暴力求解渲染器对于应用程序是不可行的。所以我们不是模拟微观几何,而是模拟整体行为。这是使用测量光量的实际问题的工具来完成的,通常称为辐射度量学。 辐射度量学中出现的术语乍一看可能很奇怪,它们的术语和符号可能很难理解。这部分最重要的物理量是辐射 Radiance,大多数图形师会把它映射到亮度/颜色/强度这些直观概念上,在实践中,这在 99%的情况下是有效的。

辐射强度(Radiant Intensity):单位立体角(solid angle)由点光源发出的功率(power)。 辐射照度(Irradiance):在单位面积 dA 上的总辐射通量。 辐射(Radiance):在单位面积 dA、单位方向 dw 上的辐射通量。

虽然我们可以在许多系统中定义辐射单位,但我们使用 SI(国际单位制)单位。熟悉的 SI 单位包括米(m)和克(g)的公制单位。 光基本上是一种能量的传播形式,因此定义能量的 SI 单位是有用的,即焦耳(J)。

14.6.1 光谱能量

如果我们有一个大的光子集合,它们的总能量 Q 可以通过将每个光子的能量 qi 相加来计算。 一个合理的问题是“能量在波长上的分布如何?”。回答这个问题的一个简单方法是将光子划分到箱子中,本质上是对它们做直方图。然后我们有了一个与区间相关的能量。

例如,我们可以计算 λ = 500 nm 和 λ = 600 nm 之间的所有能量,结果是 10.2 J,这可以记作 q[500, 600] = 10.2。如果我们把波长间隔分成两个 50nm 的间隔,我们可能会发现 q[500,550] = 5.2 和 q[550,600] = 5.0。这告诉我们,在间隔[500,600]的短波长中有更多的能量。如果我们分成 25 nm 的箱子,我们可能会发现 q[500,525] = 2.5,以此类推。 这个系统的好处是它很简单。它的缺点是间隔大小的选择决定了能量的大小。

更常用的方法是将能量除以间隔的大小。所以不是 q[500,600] = 10.2,而是 这种方法很好,因为间隔对数字的总体大小的影响要小得多。 一个直接的想法是让间隔大小 Δλ 趋向零。这可能会很尴尬,因为对于一个足够小的 Δλ, $Q_{\lambda}$要么是零,要么是巨大的,这取决于在间隔中是否有一个光子。 有两种观点可以解决这个难题。

  1. 第一种假设是 Δλ 很小,但又没有小到光的量子特性可以发挥它的作用。
  2. 第二种是假设光是连续的而不是单个光子,所以导数 dQ/dλ 是可用的。

考虑它的两种方式都是合适的,并导致相同的计算机制。 在实践中,大多数测量光的人似乎更喜欢小的,但有限的间隔,因为这是他们在实验室可以测量的。大多数从事理论或计算的人更喜欢无穷小的区间,因为这使微积分的机制变得可用。

$Q_{\lambda}$被称为光谱能量,它是一个强度量,而不是一个广度量(如能量、长度或质量)。强度量可以被认为是密度函数,它告诉我们在一个无限小的点上一个广度量的密度。 例如,在特定波长处的能量 Q 可能为零,但这个位置上的光谱能量(能量密度) $Q_{\lambda}$是一个有意义的量。 一个可能更熟悉的例子是,一个国家的人口可能是 2500 万,但这个国家的人口在某一点上是无意义的。然而,如果在足够大的区域内测量,以每平方米人口为单位的人口密度是有意义的。 就像光子一样,如果我们假装我们可以将人口视为一个连续体,即使面积很小,人口密度也不会变得颗粒状,那么人口密度就会达到最佳效果。

我们将遵循图形学的惯例——几乎总是使用光谱能量,而很少使用能量。 如果使用“正确”的表示法,这会导致 λ 下标的激增(每个波长都对应一个$Q_{\lambda}$,让人看着很混乱)。 相反,我们将去掉下标并使用 Q 来表示光谱能量。 当领域外的人阅读图形学论文时,这可能会导致一些混乱,因此请注意这个标准问题。

想象一个带有测量光能 Δq 的传感器的测量设备可能会有助于您对光谱能量的理解。 如果在传感器前面放置一个彩色滤光片,仅允许 [λ − Δλ/2, λ + Δλ/2] 区间内的光通过,则 λ 处的光谱能量为 Q = Δq/Δλ。

14.6.2 功率(辐射通量 Radiant Flux)

估计光源的能量产生量是有用的。这个速率被称为功率,它的测量单位是瓦特,也就是焦耳每秒。这在稳定状态下是最容易理解的,但由于功率是一个强度量(密度除以时间),所以即使当能量生产随时间变化时,它也是很好定义的物理量。 功率单位可能比较熟悉,例如 100 瓦的灯泡。这种灯泡每秒钟消耗大约 100 焦耳的能量。由于热损失等原因,产生的光的功率实际上将小于 100 瓦,但我们仍然可以使用这个例子来帮助更多地了解光子的行为。 例如,我们可以感受到 100 瓦的光在一秒钟内产生多少光子。假设产生的平均光子的能量为 λ = 500 nm 光子。这种光子的频率是: 这个光子的能量是$hf\approx 4\times 10^{-19}J$。 这意味着即使灯泡效率不高,每秒也能产生惊人的$10^{20}$个光子。这就解释了为什么用快速的快门速度和直接模拟光子来模拟相机是产生图像的低效选择。

与能量一样,我们真正感兴趣的是用 W (nm)−1 测量的光谱功率。同样,虽然谱功率的正式标准符号是$\Phi_{\lambda}$,但为了方便和与大多数图形学文献的一致性,我们将使用 Φ 而不带下标。

需要注意的一点是,光源的光谱功率通常比功率小。 例如,在 400 ~ 800nm 波长上均匀分布的 100w 光,则光谱功率为 100w / 400nm = 0.25 W(nm)−1。如果您手动设置光源的光谱功率以进行调试,请记住这一点。

上一节中的光谱能量测量装置可以通过使用以时间 t 为中心的快门打开一段时间间隔 Δt 进行读数来进行修改。则光谱功率为: $$\Phi=\triangle q/(\triangle t\triangle \lambda)$$

14.6.2 辐射照度 Irradiance

如果你问“有多少光照射到这一点?”这个问题, 辐射照度 Irradiance 这个物理量就会自然的引申出来。 当然,答案是“无”,而且我们必须使用密度函数。 如果该点位于曲面上,则很自然地使用面积来定义我们的密度函数。 我们修改了上一节的公式,使其具有小于被测量光场的有限 ΔA 面积传感器。 光谱辐照度 H 就是单位面积的功率 ΔΦ/ΔA: $$Irradiance\space H=\frac{\triangle q}{\triangle A \triangle t \triangle \lambda}$$ 因此,辐照度的完整单位为$Jm^{-2}s^{-1}(nm)^{-1}$。 请注意,辐射的国际标准单位包括面积的平方的反比和波长的纳米的反比。这种表面上的不一致(同时使用纳米和米)是因为面积和可见光波长的自然单位。

同时使用 m 和 nm 两个单位的原因:因为包含了面积和波长

当光线从表面离开时(例如反射),与辐照度相同的物理量称为辐射出射度 E。用不同的物理量表示入射和出射光是有用的,因为同一点具有潜在不同的辐照度和辐射出射度。

14.6.3 辐射 Radiance

虽然辐照度 Irradiance 告诉我们有多少光到达一个点,但它很少告诉我们关于光方向的信息。我们需要能够将多少光与一个特定的方向联系起来。 我们可以想象一个简单的装置来测量这样的量。我们使用一个小的辐照度计,并添加一个锥形挡板,将照射到计数器的光限制在一个立体角的角度范围内。探测器的响应如下: $$response=\frac{\triangle H}{\triangle \sigma}=\frac{\triangle q}{\triangle A\triangle \sigma\triangle t\triangle \lambda}$$ 这被称为光的光谱辐射在空间中穿梭。再次声明,我们不会显式地声明“光谱”,并假设它的意义隐含在“辐射”这个词当中。

辐射是我们在图形程序中经常用来做计算的物理量。辐射的一个重要特性是——沿着空间中的一条线上,辐射不会变化。 要了解为什么会这样。检查两个辐射检测器,它们都观察一个表面。假设检测器的“视线”足够接近,以至于表面上两个区域发射/反射的光都相同。 因为被采样表面的面积与距离的平方成正比,并且由于到达检测器的光与距离的平方成反比,所以两个检测器应该具有相同的读数。

测量照射到表面的辐射很有用。 我们可以考虑将辐射检测器的锥体挡板放置在表面上的一点,并测量表面上源自锥体内方向的辐照度 H。注意表面探测器没有与圆锥体对齐。因此,我们需要在辐射率的定义中添加余弦校正项 $$response=\frac{\triangle H}{\triangle \sigma \cos{\theta}}=\frac{\triangle q}{\triangle A\cos{\theta}\triangle \sigma\triangle t\triangle \lambda}$$

$\triangle A\cos{\theta}$是投影面积

与辐照度和辐射出射度一样,区分入射到表面上一点的辐射度和从该点出射的辐射度是有用的。 有时在图形学文献中使用的术语是表面辐射 Ls,表示(离开)表面的辐射,和场辐射率 Lf,表示入射在表面的辐射率。两者都需要余弦项:

其他辐射量

如果我们有一个表面,它的场辐射是 Lf,那么我们可以从它推导出所有其他辐射度量值。这就是为什么辐射度被认为是基本辐射量的原因之一。例如辐射照度可以这么表示: $$Irradiance \space H=\int_{all\space k},L_f(k),\cos{\theta},d\sigma$$ 这个公式有几个在图形中常见的符号约定,使得不熟悉它们的读者不能理解这些公式。首先,k 是入射方向,一个相对于表面法线的$(\theta,\phi)$球坐标对。这个方向有一个与之相关的微分立体角 dσ。场辐射在每个方向上很可能是不同的,所以我们把它写成函数 L(k)。

作为一个例子,在所有方向上具有相同场辐射 Lf 的表面上,我们可以计算辐射照度 H。为了积分,我们使用经典的球坐标系,并回忆微分立体角是 $$Recall:\space r^2\sin{\phi}drd\theta d\phi$$ $$d\sigma=\sin{\phi}d\theta d\phi$$ $$Irradiance \space H=\int_{\phi=0}^{\pi/2}\int_{\theta=0}^{2\pi},L_f\cos{\phi}\sin{\phi}d\theta d\phi=\pi L_f$$ 这个关系式向我们展示了第一个可能令人惊讶的常数 π。π 的这些因子在辐射测量中经常出现,是我们如何选择测量立体角的人工产物。也就是说,单位球的面积是 π 的倍数而不是 1 的倍数。

类似地,我们可以通过对整个表面的辐照度积分来求照射在表面上的辐射能量(辐射通量): $$\Phi=\int_{all\space x},H(x),dA$$ 其中 x 是曲面上的一个点,dA 是与该点相关的微分面积。

14.7 散射的辐射度量

第 14.5 节的光子跟踪器假设在所有光线相交的表面上都是光滑的,并且我们假设模型具有非常精细几何细节。 实作上,一个区域的宏观属性被平均,使一个区域表现得很精致,但不实际存储它。 本节最重要的概念是,对于粗糙的表面(例如,拉丝钢),我们不是用实际的几何形状来表示所有微小的划痕,而是统计性地表征划痕,使用光滑的表面在多个方向上随机反射光线,就好像表面上有看不见的小细节一样。这个函数被称为双向反射分布函数(BRDF)。

第二个重要的概念与光如何在一个体积中散射非常相似(例如,冰块中的气泡或云中的水滴)。与其显式的表示体积中的所有小颗粒/气泡/液滴,相反,我们只是建立一个统计模型,说明光在任何给定的 3D 位置中散射的可能性有多大,被吸收的可能性有多大。以及散射光的方向分布是什么。 该方向分布只是一个概率密度函数 PDF,称为体积的相位函数。 我们不会进一步讨论相位函数或体积传播:有关这些主题的更多信息,请参阅章节注释。

14.7.1 BRDF(双向反射分布函数)

因为我们对表面外观感兴趣,所以我们想表征表面如何反射光线。 直观来说,对于来自 ki 方向的任何入射光;在出射方向 ko 附近的小立体角上存在一小部分散射光。 我们可以通过多种方式形式化这样的概念,毫不奇怪的是:标准方法的灵感来自于构建一个简单的测量设备。其中一个小光源位于 ki 方向;从表面上的一点看,探测器位于 ko 方向。 对于每个方向对 $(k_i,k_o)$ ,我们用探测器读取读数。 现在我们只需要决定如何测量表面上光源的强度并使我们的反射函数独立于该强度。例如,如果我们用更亮的光替换原来的光(表面变得更亮了),我们不会想要以不同的方式来考虑光线的反射。 我们可以在被照射的点放置一个辐射计来测量光。但是,为了获得准确且不依赖于探测器 Δσ 的读数,我们需要光的角度大于 Δσ。不幸的是,我们在 ko 方向上的辐射探测器也将计算来自表面辐射探测器锥以外的光。所以这似乎不是一个实用的解决方案。

或者,我们可以在被测量表面的点上放置一个辐照度测量计。它读取的示数并不强烈地依赖于光源几何的微妙变化。这项想法将反射率表征为一个比值: $$\rho=\frac{L_s}{H}$$ 其中 ρ 随入射和出射光线方向 ki 和 ko 而变化,H 是光线在位置 ki 的辐照度,Ls 是在 ko 方向上测量的表面辐射。 如果我们对所有方向对进行这样的测量,我们最终得到一个四维函数$\rho(k_i,k_o)$。这个函数被称为双向反射分布函数(BRDF)。BRDF 是我们所需要知道的表征表面如何反射光的方向特性的全部。

定向半球面反射率

给定 BRDF,很容易问:“入射光的反射比例是多少?”然而,答案并不那么容易。反射的部分取决于入射光的方向分布。 因此,我们通常只设置固定入射方向 ki 的反射分数。这个分数被称为定向半球面反射率。这个分数 R(ki)的定义是: 由于能量守恒的原因,这个量在 0 到 1 之间。 如果我们允许入射功率 Φi 击中一个小区域 ΔA,那么辐照度为 Φi/ΔA。同样,入射功率的比值就是辐射出射度与辐照度的比值: $$R(k_i)=\frac{E}{H}$$ 由该辐射功率产生的特定方向上的辐射是由 BRDF 定义的: $$L(k_o)=H\rho(k_i,k_o)$$ 根据辐射的定义,我们也有: $$L(k_o)=\frac{\triangle E}{\triangle \sigma_o \cos{\theta_o}}$$ E 是在一个小方向 ko 上的辐射出射度,然后连接两个等式得到: 然而$\triangle E/H$只是$E /H$在方向 ko 上的一小部分贡献,为了找到完整的$R(k_i)$,我们对所有的出射方向积分,得到: $$R(k_i)=\int_{all\space k_o},\rho(k_i,k_o) \cos{\theta_o},d\sigma_o$$

理想漫射 BRDF

理想的漫射曲面称为朗伯曲面。由于热力学原因,这样的表面在自然界是不可能存在的,但从数学上讲,它们确实能保证能量守恒。 朗伯 BRDF 的 ρ(反射率)对于所有角度都是常数。这意味着表面在所有视角下都具有相同的亮度,并且该亮度将与辐照度成正比。

如果我们计算 ρ = C 的朗伯曲面的 R(ki)我们得到: 因此,对于一个完美反射的朗伯曲面(R = 1)我们有 ρ = 1/π,对于一个 R(ki) = r 的朗伯曲面,我们有 $$\rho(k_i,k_o)=\frac{r}{\pi}$$

[!note] 立体角微分 立体角定义为面积微元与半径的平方之商 $$d\omega=\frac{dA}{r^2}=\frac{rd\theta\cdot rsin\theta d\phi}{r^2}=sin\theta d\theta d\phi$$

14.8 传递方程

根据 BRDF 的定义,我们可以用来自所有不同方向的入射辐射率来描述表面的辐射率。 因为在计算机图形学中,我们可以使用在实验室中实例化可能不切实际的理想化数学机制,我们也可以仅根据辐射度来编写 BRDF。 如果我们取一小部分具有立体角$\triangle \sigma_i$、辐射度 Li 的光,并且 测量 ko 方向上的反射辐射。由于这一小部分光而产生的辐照度为 $H=L_i\cos{\theta_i}\triangle\sigma_i$。因此 BRDF 是 $$\rho=\frac{L_o}{L_i\cos{\theta_i}\triangle\sigma_i}$$ 这个形式在某些情形下可能会很有用。整理一下公式,$\triangle L_o$是被入射辐射所贡献的那部分出射辐射: $$\triangle L_o=\rho(k_i,k_o)L_i\cos{\theta_i}\triangle\sigma_i$$ 如果光线来自各个不同的方向,我们把他们整合起来,写成积分的形式,使用表面辐射和场辐射的符号: $$L_s(k_o)=\int_{all\space k_i},\rho(k_i,k_o)L_f(k_i)\cos{\theta_i},d\sigma_i$$ 上式通常被称为渲染方程。

有时,将传递方程写成只有辐射的形式是很有用的。 注意,在一个封闭环境中,来自其他表面的场辐射与自身的表面辐射有:$L_s(-k_i)=L_f(k_i)$,单位角在 x‘处的微分可以写成: $$\triangle \sigma_i=\frac{\triangle A'\cos{\theta'}}{\Vert x-x' \Vert^2}$$ 其中$\triangle A'$与 x'处相关,将上式替换渲染方程,我们得到:

请注意,我们使用非标准化向量 x - x '来表示从 x '到 x 的方向。 还请注意,我们将 Ls 写成位置和方向的函数。

这个新传递方程的唯一问题是——积分域很棘手。如果我们引入一个可见性函数,我们可以用被积函数的复杂度来权衡定义域的复杂度:

14.9 实际中的材质

许多真实的材料在正常的观看距离下具有可见的结构。例如,大多数地毯都有很容易看到的绒毛,这有助于美观。 就我们的目的而言,这种结构不是材质属性的一部分,而是几何模型的一部分。结构的细节在正常的观察距离下是看不见的,但它确实决定了材料的宏观外观,是材料特性的一部分。 例如,纸上的纤维在放大时具有复杂的外观,但在一臂距离外观察时,它们会模糊在一起,形成均匀的外观。 将微观结构之间的区别全部包含进 BRDF 有些武断,取决于人们对“正常”观看距离和视觉敏锐度的定义,但这种区别在实践中被证明是非常有用的。

在文献中有许多 BRDF 模型,并在行业中使用。有许多领域使用 BRDF 模型,包括遥感、传热、材料科学,当然还有计算机图形学。不幸的是,在这些领域没有一个标准的分类集,甚至在图形领域也没有。然而,这些是大多数人同意的一些分类标准,如下图。 在行业中将材质分为这些类别,并为每个材质类型使用不同的 BRDF 模型。然后将这些材质类型与常数或由菲涅耳系数确定的简单权重结合起来。 一个关键的问题是该使用什么材质类型。越来越多的实践已经确定了 Burley/Disney 模型的变体,用于计算机生成动画,但它现在也被广泛应用于游戏和产品设计中。包含大部分分类的材质,包括 sheen 材质。

matte(哑光), sheen(光泽), shiny(闪亮):三种关于光泽的材质,闪亮程度逐渐加大。

上图中的分类没有包括“sheen”,因为它还不是一个在图形学内部广泛使用的术语,也不作为图形之外的技术术语使用。sheen 用于计算掠入射角效应(入射角极大),如边缘照明,特别是在皮肤和织物上。 逆向反射(retro-reflective)在某些情况下非常重要。但在图形学中并不常用。

在实际应用中,BRDF 模型中使用的两个最普遍的材质是漫射和 glossy。在漫反射中常常使用常量表示,然而,也有其他变化的数值表示,在那些模型中,掠入角度上会变得更暗并且 glossy 材质开始起作用。

目前最主要的光泽 gloosy 形式是 GGX 微面。微面与我们蛮力表示的粗糙表面密切相关,然而只需找到微面表面法线的统计分布。请注意,微面方法是对具有微面的实际表面的近似。

14.10 蒙特卡洛光线追踪

一旦我们将光线表示成一个积分,我们可以利用蒙特卡洛积分来求解他。回顾之前蒙特卡洛积分的知识,对一个函数 f 的积分正是许多随机采样的平均值(重要性采样): 其中 p 是域 s 上的概率密度函数,如果我们将其应用于渲染方程,那么对于一个随机样本方向 q,我们得到:

为了得到噪声较小的图像,我们将对许多噪声样本进行平均。 首先,我们需要一种根据给定概率密度函数 p 生成随机方向的方法。记住 p 可以是任意有效的 PDF,所以我们使用半球面上的均匀分布:$p=1 / 2\pi$。 这个值是因为积分是在“表面以上所有方向的立体角”上,而立体角是单位球面上投影的面积,而“表面以上”的方向是球面的一半,面积为 2π。

在代码中,对于入射光线方向 a:

但是来自 q 方向的颜色 Lf 是什么? 事实上,我们可以递归地应用蒙特卡罗积分(这并不明显,但可以使用随机变量的属性来显示,即使总和的项不独立,预期值也会相加)(???)。 如果我们写一个函数 L(o, d),它返回 p 点来自 d 方向上的颜色,加上自身发射的光,这样就有东西可以看到了,然后我们可以写一个递归函数: 请注意,如果环境是封闭的,则该函数永远不会终止,因此应该为封闭环境添加一些终止条件。背景函数可以返回一个常量,也可以查找环境贴图上的值,或者查找其他随方向变化的函数。 最后,除了背景之外不需要其他灯光来获得好的照片。

你可能会注意到,这与本章前面开发的伴随光子追踪器非常相似。但推导方法不同,采用显式辐射积分法,可以得出相似的结论。

在实践中,当灯光很小时,该算法的结果将会有大量噪声,因为 emitted()函数的值可能很大,然而小灯光的数量很少。 相反,人们经常通过单独计算发光物体的贡献来分解出直接照明。例如: 这里,directLightAt(p)计算直接照明,即光子从光源出发直接到达表面而没有与任何其他几何体互动。该代码可能会出现光源是黑色的情况(光源不会照亮自己,directLightAt 返回 0),因此在实际代码中需要以某种方式处理此问题。

直接照明通常也使用蒙特卡罗计算,但通常在光源上按照面积采样(面积大的光源采样数多),从而评估公式 14.5。

请注意,只要材料不是完全光滑(例如脉冲),上述方法就可以很好地工作。 从技术上讲,对于这些材料(脉冲材质),BRDF 是一个在某一个方向上具有无限值的函数,所以它可以正常的工作,但不能用浮点数的机制来运算。这里我们需要一个“if”来处理这些材料,就像在第 4 章中处理光线一样。