计算机图形学基础-05-表面着色

《Fundamentals of Computer Graphics》5th(计算机图形学基础/虎书),中文翻译。

第 5 章 Surface Shading 表面着色

当我们渲染三维场景的图像时,无论是使用光线追踪还是光栅化,在实时或批处理中,对于产生三维视觉效果的关键因素之一就是基于物体形状和它与场景中其他物体的关系来给物体表面上色或着色。在物理世界中,我们看到的大部分光都是反射光,并且光反射的物理学受几何形状影响很大,这会产生各种线索,人类视觉系统非常有效地利用这些线索来理解形状。

在计算机图形学中,着色的目的是为了向视觉系统提供这些线索,但对应到具体场景,所期望实现的最终结果也会有所不同。在计算机辅助设计 (computer-aided design) 或科学可视化 (scientific visualization) 方面,则侧重于清晰度:着色应该被设计成提供最清晰、最准确的 3D 形状印象。而在视觉特效或广告方面,则旨在最大程度地使渲染结果与真实对象外貌相似。在动画、虚拟环境或游戏方面,则目标介于两者之间:着色旨在达到艺术性目标,包括描绘形状和材质等内容,但可能并不一定要完全模仿现实。

用于计算着色的方程式称为着色模型 (shading model),针对不同应用程序已经开发出了许多不同类型的 shading model。通常情况下这些模型都从一个模拟光反射规律的简单模型开始,以此为起点添加一些其他的功能使得渲染更逼真;或者是修改模型中的一些部分甚至去掉一些部分以制作更符合需求的模型。

一个 shading model 应当完全独立于其余的渲染系统,并且这个模型应当可以同时运行于光线追踪 (ray tracing) 和光栅化 (rasterization) 系统上 。本章描述了一个基本的着色模型,适用于一个由点光源照明的不透明表面的环境。对简单应用而言,这个模型足够了,而且我们会以此为跳板,在第 14 章讲述 shading 方面的进阶内容。

5.1 点光源

在现实世界中,光线会从各个方向照射到物体的表面上。但是对于建模照明来说,最简单的情况是:光只来自于一个方向;这是一种理想化的模型,但当光源比较小(例如 LED 手电筒)或者距离物体表面非常遥远(例如太阳)时是可行的。所以点光源有两种类型:一种是光源足够小且距离场景很近(手电筒),对于不同类型的物体表面有不同的表现;另一种是光源小且远(太阳),这种情况下物体表面的光反射表现都是类似的,只需要考虑光的方向即可。

5.1.1 Point source illumination 点光源照明

点光源由其位置(即三维空间中的一个点)和强度描述。点光源可以是各向同性的,意思就是光在所有方向上的强度相同;通常情况下这是默认设置,但许多系统提供“聚光灯”,只会将光线发送到某些方向,这对于控制虚拟场景中的灯光与实际舞台上使用聚光灯来控制灯光是一样的。

当不确定时,请使发出的颜色为中性颜色,并具有相等的红、绿和蓝色强度。

光照强度:对于各向同性的点光源,我们可以轻松地推断出一定距离处的表面上的光照强度。假设我们有一个以等向辐射方式发射 1 瓦辐射功率的点光源,并将该光源放置在半径为 1 米的空心球体中心(图 5.1)。所有来自光源的能量都落在球体内部表面上,并均匀分布在 4π m24π\space\bold m^2 的整个表面积上,因此单位面积的辐射功率为每平方米 1/(4π)1/(4π) 瓦特。我们称它为 Irradiance,用来描述单位面积上的光照强度。

fig5_1.jpg

图 5.1。从点源辐射度随距离平方减少。

对于具有功率 PP 和接收半径 rr 的通用情况,我们发现 Irradiance EE

E=P4π1r2=Ir2(5.1)E = {P \over 4π} {1 \over r^2} = {I \over r^2} \tag {5.1}

其中 I=P4πI = {P \over 4π} 是光源的强度;它是与所照明表面无关且仅取决于光源本身。r2r^{-2} 常被称作平方反比项,描述了如何根据距离 rr 计算出光照强度。

入射角:计算 Irradiance 时另一个重要考虑因素是入射角——即表面法线与光线行进方向之间的夹角。考虑一个面积特别小的表面被远离其的点光源发出的光照亮,此时落在该表面上的光可以看做是大致平行的。如果我们将该表面倾斜 60°60° 如图 5.2 所示,则该表面截获的光仅为其朝向源时截获量的一半。通常情况下,在旋转 θθ 角时它拦截到与 cosθcos θ 成比例的辐射能量,并且由于区域保持不变,Irradiance(请记住,这是每单位区域内辐射功率)也按同样比例成正比增加。这个规则称为 Lambert 余弦定律,由 Johann Heinrich Lambert 在他 1760 年出版的《Photometria》中首次提出。

fig5_2.jpg

图 5.2。(a):一束光线照射在一个表面上,照亮了立方体的整个顶部。(b):立方体倾斜 60 度,现在只有一半的光线落在立方体顶部表面上;面积保持不变,因此单位面积功率或 Irradiance 减半。

将这个定律与我们刚刚推导出的 Irradiance 公式结合起来,就可以得到点光源 Irradiance 的通用公式。

E=Icosθr2(5.2)E = I {cosθ \over r^2} \tag {5.2}

术语 cosθ/r2cos θ / r^2 可以称为点源的几何系数 (geometry factor);它取决于光源和接收表面之间的几何关系,但不取决于任一特定属性。

在实践中,通常不会计算角度 θθ,因为给定一个垂直于表面的单位向量 n\bold n 和指向光线的单位向量 l\bold l(图 5.3),余弦系数可以使用向量点乘的方式计算得出,这比使用三角函数计算更简单、更高效。

cosθ=nlcos θ = \bold n · \bold l

5.1.2 Directional illumination 方向照明

方向光源是非常亮的远距离点光源的极限情况。随着光源越来越远,公式 5.2 中的 I/r2I/r^2 比值在整个场景中变化越来越小,对于一个方向性光源,我们用一个常数 HH 来代替:

E=H cosθE = H \space cos θ

请注意,此公式仅适用于这两个向量具有单位长度时!

由于该常数几乎等于当灯光位于表面法线方向上时的辐射度,因此可以将其称为法线辐照度 (normal irradiance)。方向性光源以指向光源(而不是位置)和法线辐照度 HH(而不是强度)为特征。来自方向性光源的照明均匀,并且不像点光源照明那样随着距离增加而衰减。

5.2 基本反射模型

现在我们有了计算辐照度的能力,它描述了多少光线落在一个物体上,接下来的问题是这个物体如何反射这些光线。这取决于物体所制成的材料,在本章中,我们将讨论一种基本模型来描述带有可选闪亮表面的彩色材料 (material)。该模型背后的思想如图 5.4 所示:材料可以具有确定对象整体颜色的基础层,并且可以具有提供闪亮 (shiny)、镜面反射效果的表面,我们将分别讨论每个最简单的模型。

fig5_4.jpg

图 5.4。高光反射(a)发生在顶部表面并朝着镜像方向反射;漫反射(b)发生在表面以下材料中并以所有方向出现。

5.2.1 Lambert 反射(漫反射)

最简单的反射类型是一种表面,它将光线均匀地反射到所有方向,无论光线来自哪个方向,因此观察者看到的反射光 LrL_r 只是辐照度的一个常数倍数:

Lr=kE(5.3)L_r = k E \tag{5.3}

这种行为方式被称为理想漫反射 (ideal diffuse) 表面,并且从所有方向看起来都具有相同的亮度;其颜色与视角无关,并且完全由其反射率 RR 描述,该值表示它所反射出的辐照度占总入射辐照度的比例。将发生在入射和反射之间系数记作 R/πR/πππ 的原因会在第 14 章说明):

Lr=RπEL_r = {R \over π} E

不同颜色光线对应不同的反射率。对于简单建模颜色而言,只需保留三个不同波长下吸收和散播能力分别代表红、绿、蓝三种基本颜色通道即可。

理想漫反射 ,通常称为 Lambertian shading,因为 Lambert 定律是其主要效果模型,这种着色方式提供了平坦、粉笔般的外观。在物理学的角度,这个模型也解释了光在材料内部弹跳并随机以吸收或散发形式呈现出来。这是一种有效模型,常用于纸张、平涂料、污垢、树皮、岩石等粗糙材料,这些材质表面粗糙,不需要渲染闪亮效果。

准确预测颜色会更加复杂,请参见第 18 章。

5.2.2 Specular reflection(镜面反射)

许多材料都具有一定的光泽度,例如金属、塑料、光泽或半光泽油漆或许多植物叶子。当观察这些材料时,我们会看到,当我们移动观察的视角时,反射的区域在也会随之移动;与 Lambertian 表面的“颜色和视角无关”不同,镜面反射的物体表面颜色与视角相关。且反射的部分通常发生在材料的顶部表面,称为镜面反射。

最简单种类的镜面反射发生在完全平滑的表面上,如镜子或水的表面:光可以像照射在镜子上一样反射,使得来自点源的光线只朝一个方向走。这被称为理想镜面反射 (ideal specular reflection),在图形学中这通常需要作为特殊情况处理。许多物体的表面并不是完全平滑的,它们的表面展示出来的闪亮效果 (glossy reflection) 才是图形学中更常见的。有许多模型用于闪亮效果,在第 14 章中进行了完整的介绍,现在最常用的一种模型是由 Phong(1975) 最初提出并由 Blinn (1976) 和其他人改进并使用至今的一种模型 —— Modified Blinn-Phong 模型。

由于镜面反射与视角相关,所以其表现取决于从着色点指向查看者的视线向量 v\bold v 以及法向量 n\bold n 和 入射方向 l\bold l。其思路是当 v\bold vl\bold l 在对称位置跨越曲面法线时反射最明亮,这是当发生纯镜面反射时的情况;然后随着向量移动一个“mirror configuration”,则该反射平缓减弱。

我们可以通过半向量 (half vector) 的概念来判断我们离“mirror configuration”有多近,半向量即位于查看和入射方向之间并垂直于曲面正好在 l\bold lv\bold v 处于 “mirror reflection”配置 (Figure 5.5) 。如果半向量接近曲面法线,则应该明显显示出高光成分;如果移动较远,则应该变暗。我们通过计算 h\bold hn\bold n 之间点积 (dot product),就能够衡量 h\bold hn\bold n 之间距离是否接近(请记住它们都是单位向量,因此当两个向量相等时,nh\bold n·\bold h 达到 1),紧接着再将结果带入幂 p>1p>1 中使其减速下降:

(nh)p(\bold n·\bold h)^p

fig5_5.jpg

图 5.5。 Blinn-Phong 着色模型几何示意图

公式中的指数 pp 控制表面的光泽度:更高的值使得反射光线远离镜面方向衰减得更快,从而呈现出更加闪亮的外观。半向量本身很容易计算:由于 v\bold vl\bold l 具有相同长度,它们的总和是一个将它们之间角度二等分的向量,只需要归一化即可产生 h\bold h

p 的典型值:

  • 10 - “蛋壳”;
  • 100 - 微微发亮;
  • 1000 - 非常光滑;
  • 10,000 - 几乎像镜子一样。

h=l+vl+vh = {\bold l + \bold v \over ||\bold l + \bold v||}

为了将 Blinn-Phong 思想纳入着色计算中,我们在 Lambertian 着色中添加了一个镜面反射部分,Lambertian 部分仍然负责漫反射。我们只需将从公式 (5.3) 推导出的系数 kk 进行概括,该系数将反射光与入射辐照度相关联,不仅包括漫反射的贡献,还包括一个单独的项,用于添加镜面反射:

Lr=(Rπ+ksmax(0,nh)p)EL_r = ({R \over π} + k_s \bold {max}(0, \bold n·\bold h)^p) E

其中比例系数 ksk_s 是镜面反射系数(红色、绿色和蓝色分别),控制镜面成分的亮度,并添加了夹紧操作以避免在 n\bold n 朝向 h\bold h 的角落情况下出现意外。

如果对于也具有漫反射颜色的表面存在疑问,请使镜面系数颜色中性,红、绿、蓝值相等。

泛化系数 k\bold k 的表达式称为双向反射分布函数或 BRDF,因为它描述了反射率如何随两个方向 l\bold lv\bold v 变化而变化。Lambertian 表面的 BRDF 是恒定的,但具有镜面反射特性的表面的 BRDF 不是。然后阴影计算归结为计算辐照度(描述可用于反射多少光线)和 BRDF(描述表面如何反射它),然后将它们相乘。 第 14 章中我们将更全面地讨论 BRDF。

5.2.3 Calculating shading 计算阴影

在实现表面着色时,代码需要访问有关光源、表面和观察方向的信息。编写支持点光源和定向光源的干净代码最容易通过将辐照度计算与反射光计算分开来完成。辐照度仅取决于光源和表面几何形状,一旦知道了它,计算反射光只取决于表面属性和视角几何。

基本着色计算可以在射线跟踪和栅格化系统中以完全相同的方式进行;真正变化的只是输入如何被计算。为了计算辐照度,我们需要

  1. 着色点 x\bold x,在表面上的三维点。
  2. 表面法线 n\bold n 垂直于 x\bold x 处的表面。
  3. 点灯 p\bold p 或其方向 l\bold l 对于一个点灯。
  4. 点灯强度 I\bold I 或其法线辐射 H\bold H 对于一个定向灯(这些都是 RGB 颜色)。

对于一个点灯,我们需要计算距离和光线方向,这两个值都可以从向量 px\bold p-\bold x 得到:

r=px,l=pxrr=||\bold p−\bold x||, \bold l={\bold p−\bold x \over r}

而且对于两种类型的灯来说,余弦系数最好使用点积来计算;只要 n\bold nl\bold l 是单位向量,

cosθ=nlcos θ= \bold n · \bold l

在实践中,当计算辐照度时,将点积夹紧到零是一个好主意,以确保即使在某些情况下,您发现光线方向朝着表面法线的反方向,也不会得到负阴影。以下我们认为用于计算辐照度的官方公式:

E=\frac{\max (0, \mathbf{n} \cdot \mathbf{l})}{r^{2}} I(\text { point }) \quad \text \\ \\ { or } \\ \\ \quad \max (0, \mathbf{n} \cdot \mathbf{l}) H \text { (directional) }

这可能会出现插值法线(第 9.2.4 节)

一旦知道了辐照度,就需要将其乘以 BDRF 值,并计算该值所需的成分

  • 光线方向 l\bold l 是从 x\bold x 指向光源的单位向量(已作为辐射率计算的一部分进行了计算)
  • 观察方向 v\bold v 是从 x\bold x 指向观察者的单位向量
  • 描述表面材料属性的参数。对于本章模型而言,包括 RRksk_spp

如何获得这些数量在光线追踪和栅格化系统之间有很大差异,但实际着色计算本身相同。不要忘记 v、l 和 n 都必须是单位向量;未能归一化这些向量是着色计算中非常常见的错误。

5.3 Ambient illumination 环境照明

点光源是非常局部化的光源模型,可以在一个方向附近产生大量光线。其他类型的光源不那么局部化,例如天空或房间墙壁反射的光线。虽然这种扩展源可以进行详细建模,但对于基本着色,我们需要一个非常简单的近似值,因此我们假设环境光在场景中所有位置和所有方向上完全相同(图 5.6)。我们进一步假设环境光只能以漫反射方式反射(因为没有灯光方向,因此无法计算镜面着色)。这使得环境着色非常简单:它是一个恒定值!

fig5_6.jpg

图 5.6。环境照明添加了一些从所有方向均等到达的光线。

通常情况下,该恒定值被分解为与材料相关联的环境反射系数 (material-related ambient reflection coefficient) kak_a 和一个与灯光相关联的环境强度 (light-related ambient intensity) IaI_a 的乘积:

Lr=ka IaL_r = k_a \space I_a

实际上,ka 应该称为反射率,而 Ia 应该称为辐亮度,但这不是通常使用的术语。

这两个量都是有颜色的,因此它们被逐分量相乘(红色环境系数缩放红色环境强度)。这种安排使得方便地调整每个对象和整个场景的环境遮蔽。

环境遮蔽有点像黑客技术,因为来自大型扩展光源的照明仍然会变化:在角落和其他凹陷区域通常会更暗。但它是简单阴影设置中重要的一部分,因为它可以防止阴影完全变黑,并且提供了一种轻松调整整体场景对比度的方法。

如果不确定,请将环境颜色设置为与漫反射颜色相同,并将环境强度设置为中性颜色。

许多系统将环境光视为出现在列表中的一种灯光类型,其中包括点光源和定向光源;其他系统使得环境强度成为场景参数,以便没有显式灯光用于照明,这等同于假设始终存在一个恰好符合条件的全局灯。

常见问题

Phong 着色似乎是一个巨大的 hack。这是真的吗?

是的。如果您试图匹配实际表面的测量结果,它不是一个非常好的模型。然而,它很简单,并且已经被证明在实践中产生非常有用的阴影效果。寻求逼真阴影效果的应用程序正在从 Phong 着色转向基于微平面理论(Walter、Marschner、Li 和 Torrance,2007)更复杂但更准确的模型。但逼真也绝对需要超越点光源。所有这些都在第 14 章中讨论。

我讨厌调用 pow() 函数。是否有一种方法可以避免使用它进行 Phong 照明?

一种简单方法是只使用自身为 2,4,8,162,4,8,16 等幂次方数值作为指数,即 24816...2、4、8、16... 在实践中,对于大多数应用程序来说,这并不会造成问题。许多专门设计快速图形计算系统具有比标准 math 库中找到的 pow()pow() 函数更快且略低精度的库函数。

练习题

  1. 月球既不能通过漫反射着色也不能通过 Phong 着色得到良好近似值。哪些观察结果告诉你这是正确的?
  2. 天鹅绒既不能通过漫反射着色也不能通过 Phong 着色得到良好近似值?哪些观察结果告诉你这是正确地?
  3. 为什么塑料物体上大多数高光看起来白色,而金属上看起来金黄呢?