首页 > 技术文章 > 经验光照模型整理

Li-F 2021-09-29 20:44 原文

经验光照模型

在光照计算科学化、基于物理的理论被应用到光照计算之前,为了降低计算复杂度,让求解的时间落到可行的范围内,人们提出了许多基于观察的或基于物理近似的经验模型。本篇梳理一些常见的经验模型。

光照模型直接影响光照的计算和品质,观察下图即可看出明显区别。从左到右依次为PBR、Lambert、Blinn-Phong模型的渲染结果 (图源),模型出自Unity《亚当》。

PBRvsLAMBERTvsBLINNPHONG

约定

本篇公式中出现的字符含义:

  • \(L\):(被观察点到光源的)光线向量 (入射光的反方向)
  • \(R\):反射向量
  • \(N\):法线向量
  • \(V\):(被观察点到观察点的)视线向量
  • \(T\):切线向量
  • \(H\):半角向量

其中

\[\begin{aligned} R&=2(N\cdot L)N-L \\ H&={V+L\over\|V+L\|} \end{aligned} \]

且涉及的向量如无说明,均为单位向量。

Lambert

基于Lambert余弦定律提出的一种模型,该模型假设观察位置与反射计算无关,表面最终颜色只与法线和光线方向的夹角、光源颜色、表面颜色有关,即

\[C_{Lambert}=Albedo\times LightColor\times(N\cdot L) \]

在视觉效果上,它接近我们所观察到的漫反射现象。而点积的结果可能为负,但反射计算的结果最低只能是零向量 (即纯黑),因此对于超出部分直接进行Clamp处理,也就有

\[C_{Lambert}'=Albedo\times LightColor\times\max(0,N\cdot L) \]

Half-Lambert

这是由Valve提出并应于于Half Life的一种基于Lambert的改进模型。在Lambert模型中,背光面都将出现纯黑,因此这个模型对点积部分做了一个简单的Map操作:

\[C_{HalfLambert}=Albedo\times LightColor\times(0.5\times N\cdot L+0.5)^2 \]

即把原本位于 \([-1,1]\) 的结果线性映射到 \([0,1]\)​ 区间并做平方处理,以达到提亮的目的,显然这只是一种映射方式。

Phong

Phong模型假设物体的最终着色表现由四部分组成

\[C_{Phong}=C_{emission}+C_{ambient}+C_{specular}+C_{diffuse} \]

其中,diffuse部分采用Lambert系列模型进行计算:

\[C_{diffuse}=Albedo_{diffuse}\times LightColor\times(N\cdot L) \]

emission为物体的自发光部分,这部分贡献直接来自物体的自发光颜色,在这里,自发光物体并不会被当做光源参与其他计算:

\[G_{emission}=M_{emission} \]

ambient为环境光部分,这也是历史上首次涉及全局光的一个模型 (虽然只是简单的一项加法),这个模型假设当前场景存在一个环境颜色,并在所有着色计算中都会加上这一项:

\[C_{ambient}=G_{ambient} \]

specular为高光部分,这是基于对金属类材质的高光表现而添加一部分贡献,根据经验,我们的视线越接近反射方向,我们看到的高光反射就越明显,因此也就有:

\[C_{specular}=Albedo_{specular}\times LightColor\times \max(0,V\cdot R)^{Gloss} \]

其中, \(Gloss\) 是材质的光泽度参数,用于控制高光的光斑大小。

Blinn-Phong

Blinn-Phong模型是针对Phong模型中高光计算部分提出的另一种实现。它基于另一个观察:当视线越接近反射方向时,半角向量也越接近法线,因此也就有:

\[C_{specular}=Albedo_{specular}\times LightColor\times \max(0,N\cdot H)^{Gloss} \]

提出这个模型是为了避免计算反射向量,这是因为当观察点和光源两者都离模型较远时,可以假设 \(V\)​ 和 \(L\)​ 都是定值,即 \(H\) 是一个常量。

Gouraud

Gouraud严格来说并不是一种模型,它只是把光照计算从Fragment Shader移到了Vertex Shader,即逐顶点光照。计算结果为顶点颜色,并在图元内部进行线性插值形成最终结果。在模型精度较低的情况下,生成的着色结果通常会出现扩散现象,尤其是某些实现下高光部分会向四周蔓延 (如Phong高光,这是因为其包含了一个平方计算)。

Flat

Flat Shading则更进一步,它做的是逐图元光照 (通常是逐三角形),即为每个图元都计算一个颜色,且不做插值处理,图元覆盖的每个像素都使用该颜色。通常用于low poly风格的渲染中。

Banded

这也是一种风格化的处理,核心思想是采用分段函数对计算结果进行映射,常见于实现卡通效果。

推荐阅读