UnityShader快速入门(3)标准光照模型-理论篇

UnityShader快速入门(3)标准光照模型-理论篇

1. 简介

虽然光照模型有很多种类,但在早期的游戏引擎中往往只使用一个光照模型,这个模型被称为标准光照模型。

在1975年,著名学者裴祥风(Bui Tuong Phong) 提出了标准光照模型背后的基本理念。

标准光照模型只关心直接光照(directlight),也就是那些直接从光源发射出来照射到物体表面后,经过物体表面的一次反射直接进入摄像机的光线。

它的基本方法是,把进入到摄像机内的光线分为4个部分,每个部分使用一种方法来计算它的贡献度。

这4个部分是:

  • 自发光 (emissive)
    这个部分用于描述当给定一个方向时,一个表面本身会向该方向发射多少辐射量。
    需要注意的是:
    如果没有使用全局光照(globalillumination)技术,这些自发光的表面并不会真的照亮周围的物体,而是它本身看起来更亮了而已。

  • 高光反射(specular)
    这个部分用于描述当光线从光源照射到模型表面时,该表面会在完全镜面反射方向散射多少辐射量。

  • 漫反射(diffuse)
    这个部分用于描述,当光线从光源照射到模型表面时,该表面会向每个方向散射多少辐射量。

  • 环境光 (ambient)
    它用于描述其他所有的间接光照。

标准光照模型仅仅是一个经验模型,它并不完全符合真实世界中的光照现象。
但由于它的易用性、计算速度和得到的效果都比较好,因此仍然被广泛使用。

但这种模型有很多局限性。

  • 有很多重要的物理现象无法用Blinn-Phong模型表现出来,
    例如菲涅耳反射(Fresnel reflection)。
  • Blinn-Phong 模型是各项同性(isotropic) 的
    当我们固定视角和光源方向旋转这个表面时,反射不会发生任何改变。
    但有些表面是具有各向异性(anisotropic)反射性质的例如拉丝金属、毛发等。
    所以它看起来不够真实

2. 环境光

虽然标准光照模型的重点在于描述直接光照,但在真实的世界中,物体也可以被间接光照(indirect light)所照亮。

间接光照指:光线通常会在多个物体之间反射,最后进入摄像机。
也就是说,在光线进入摄像机之前,经过了不止一次的物体反射。
例如:
在红地毯上放置一个浅灰色的沙发,那么沙发底部也会有红色,这些红色是由红地毯反射了一部分光线,再反弹到沙发上的。

在标准光照模型中,我们使用了一种被称为环境光的部分来近似模拟间接光照。
环境光的计算非常简单,它通常是一个 全局变量,即场景中的所有物体都使用这个环境光。

环境光计算公式:
c a m b i e n t = g a m b i e n t c_{ambient}=g_{ambient} cambient=gambient
物体环境光=全局环境光

3. 自发光

光线也可以直接由光源发射进入摄像机,而不需要经过任何物体的反射。

标准光照模型使用自发光来计算这个部分的贡献度。
它的计算也很简单,就是直接使用了该材质的自发光颜色:

自发光计算公式:
c e m i s s i v e = m e m i s s i v e c_{emissive}=m_{emissive} cemissive=memissive
物体自发光=该物体材质自发光

通常在实时渲染中,自发光的表面往往并不会照亮周围的表面
也就是说,这个物体并不会被当成一个光源。
Unity5引入的全新的全局光照系统则可以模拟这类自发光物体对周围物体的影响

4. 漫反射

漫反射光照是用于对那些被物体表面随机散射到各个方向的辐射度进行建模的。

在漫反射中,视角的位置是不重要的,因为反射是完全随机的,因此可以认为在任何反射方向上的分布都是一样的。但是,入射光线的角度很重要。

漫反射光照符合兰伯特定律(Lambert’s law):
反射光线的强度与表面法线和光源方向之间夹角的余弦值成正比。

漫反射计算公式:
c d i f f u s e = ( c l i g h t ⋅ m d i f f u s e ) m a x ( 0 , n ⋅ I ) c_{diffuse}=(c_{light}·m_{diffuse})max(0,n·I) cdiffuse=(clightmdiffuse)max(0,nI)
物体漫反射光=(光源颜色·物体材质漫反射颜色)·取大值(0,法线方向矢量·光源方向矢量)
其中:

  • n是表面法线

  • I是指向光源的单位矢量

  • m d i f f u s e m_{diffuse} mdiffuse是材质的漫反射颜色

  • c l i g h t c_{light} clight 是光源颜色。

需要注意的是:
我们需要防止法线和光源方向点乘的结果为负值,
为此,我们使用取最大值的函数来将其截取到0,
这可以防止物体被从后面来的光源照亮。

5. 高光反射

5.1 Phong模型

这里的高光反射是一种经验模型, 也就是说,它并不完全符合真实世界中的高光反射现象。

它可用于计算那些沿着完全镜面反射方向被反射的光线,这可以让物体看起来是有光泽的,例如金属材质。

计算高光反射需要知道的信息比较多,如表面法线、视角方向、光源方向、反射方向等。
我们假设这些矢量都是单位矢量。如下图所示:
在这里插入图片描述

在这四个矢量中,我们实际上只需要知道其中3个矢量即可,而反射方向可以通过其他信息计算得到:
r ^ = 2 ( n ^ ⋅ I ) n ^ − I \hat r=2(\hat n·I)\hat n-I r^=2(n^I)n^I

这样,我们就可以利用Phong 模型来计算高光反射的部分:
高光反射计算公式(Phong模型):
c s p s c u l a r = ( c l i g h t ⋅ m s p e c u l a r ) m a x ( 0 , v ^ ⋅ r ^ ) m g l o s s c_{spscular}=(c_{light}·m_{specular})max(0,\hat v·\hat r)^{m_{gloss}} cspscular=(clightmspecular)max(0,v^r^)mgloss
物体高光反射=(光源颜色·物体材质高光反射颜色)·取大值(0,视角向量方向·反射向量方向)物体光泽度次幕
其中:

  • m s p e c u l a r m_{specular} mspecular是材质的光泽度(gloss), 也被称为反光度(shininess)。
    它用于控制高光区域的亮点”有多宽,mgloss越大,亮点就越小。

  • m s p e c u l a r m_{specular} mspecular是材质的高光反射颜色,
    它用于控制该材质对于高光反射的强度和颜色。

  • c l i g h t c_{light} clight 则是光源的颜色和强度。

同样,这里也需要防止 v ^ ⋅ r ^ \hat v·\hat r v^r^的结果为负数。

5.2 Blinn模型

和上述的Phong 模型相比,Blinn 提出了一个简单的修改方法来得到类似的效果。
它的基本思想是,避免计算反射方向 r ^ \hat r r^
为此,Blin 模型引入了一个新的矢量 h ^ \hat h h^,它是通过对 v ^ \hat v v^ I ^ \hat I I^的取平均后再归一化得到的。

即:
h ^ = v ^ + I ∣ v ^ + I ∣ \hat h=\frac {\hat v+I}{|\hat v+I|} h^=v^+Iv^+I
然后,使用 h ^ \hat h h^ n ^ \hat n n^之间的夹角进行计算,而非 v ^ \hat v v^ r ^ \hat r r^之间的夹角如下图所示:
在这里插入图片描述

高光反射计算公式(Blinn模型):
$c_{spscular}=(c_{light}·m_{specular})max(0,\hat n·\hat h)^{m_{gloss}} $
物体高光反射=(光源颜色·物体材质高光反射颜色)·取大值(0,法线方向·向量h方向)物体光泽度次幕

h ^ = v ^ + I ∣ v ^ + I ∣ \hat h=\frac {\hat v+I}{|\hat v+I|} h^=v^+Iv^+I
向 量 h 方 向 = 视 角 方 向 向 量 + 光 源 方 向 向 量 ∣ 视 角 方 向 向 量 + 光 源 方 向 向 量 ∣ 向量h方向=\frac {视角方向向量+光源方向向量}{|视角方向向量+光源方向向量|} h=++

在硬件实现时:

  • 若摄像机和光源距离模型足够远
    Blinn 模型会快于Phong模型
    因为此时可以认为 v ^ \hat v v^ I ^ \hat I I^都是定值,因此 h ^ \hat h h^将是一个常量。
  • v ^ \hat v v^ I ^ \hat I I^不是定值时,Phong 模型可能反而更快一些。

注意:
这两种光照模型都是经验模型
也就是说,我们不应该认为Blinn 模型是对“正确的”Phong模型的近似。
实际上,在一些情况下,Blinn 模型更符合实验结果。

2.6 标准光照模型的两种着色

计算光照模型通有两种选择:

  • 在片元着色器中计算——逐像素光照(per-pixel lighting)
    也被称为Phong着色(Phong shading)Phong插值法线插值着色技术
    在逐像素光照中,我们会以每个像素为基础,得到它的法线
    (可以是对顶点法线插值得到的,也可以是从法线纹理中采样得到的),然后进行光照模型的计算。

    这不同于我们之前讲到的Phong光照模型。

  • 在顶点着色器中计算——逐顶点光照(per-vertex lighting)
    也被称为高洛德着色(Gouraud shading)
    我们在每个顶点上计算光照,然后会在渲染图元内部进行线性插值,最后输出成像素颜色。
    由于顶点数目往往远小于像素数目,因此逐顶点光照的计算量往往要小于逐像素光照。

    注意:
    由于逐顶点光照依赖于线性插值来得到像素光照
    因此,当光照模型中有非线性的计算( 例如计算高光反射时)时,逐顶点光照就会出问题。
    而且,由于逐顶点光照会在渲染图元内部对顶点颜色进行插值,
    这会导致渲染图元内部的颜色总是暗于顶点处的最高颜色值,这在某些情况下会产生明显的棱角现象。

猜你喜欢

转载自blog.csdn.net/qq_44705559/article/details/118104785