文章目录
渲染包含了两大部分:决定一个像素的可见性,决定这个像素上的光照计算。
光照模型就用于决定在一个像素上进行怎样的光照计算。
基础概念
光源
在实时渲染中,我们通常把光源当成一个没有体积的点,用l来表示它的方向。
在光学里,我们使用**辐照度(irradiance)**来量化光。
对于平行光来说,它的辐照度可通过计算在垂直于 l 的单位面积上单位时间内穿过的能量来得到。
在计算光照模型时,我们需要知道一个物体表面的辐照度,而物体表面往往是和l不垂直的,这时我们可以使用光源方向 l 和表面法线 n 之间的夹角的余弦值来得到。
吸收和散射
光线由光源发射出来后,就会与一些物体相交,结果通常有两个:散射(scattering) 和 吸收(absorption)。
散射只改变光线的方向,但不改变光线的密度和颜色。
吸收只改变光线的密度和颜色,但不改变光线的方向。
光线在物体表面经过散射后,有两种方向:
一种将会散射到物体内部,这种现象被称为折射(refraction)或透射(transmission);另一种将会散射到外部,这种现象被称为反射(reflection)。
对于不透明物体,折射进入物体内部的光线还会继续与内部的颗粒进行相交,其中一些光线最后会重新发射出物体表面,而另一些则被物体吸收。那些从物体表面重新发射出的光线将具有和入射光线不同的方向分布和颜色。
为了区分这两种不同的散射方向,我们在光照模型中使用了不同的部分来计算它们:
高光反射(specular)部分表示物体表面是如何反射光线的
漫反射(diffuse)部分则表示有多少光线会被折射、吸收和散射出表面
根据入射光线的数量和方向,我们可以计算出射光线的数量和方向,我们通常使用出射度(exitance)来描述它。
辐照度和出射度之间是满足线性关系的,而它们之间的比值就是材质的漫反射和高光反射属性。
着色
着色(shading)是根据材质属性(如漫反射属性等)、光源信息(如光源方向、辐照度等),使用一个等式去计算沿某个观察方向的出射度的过程。
我们也把这个等式称为光照模型(Lighting Model)。
不同的光照模型有不同的目的。例如,一些用于描述粗糙的物体表面,一些用于描述金属表面等。
BRDF光照模型
当给定模型表面上的一个点时,BRDF(Bidirectional Reflectance Distribution Function)包含了对该点外观的完整的描述。
在图形学中,BRDF大多使用一个数学公式来表示,并且提供了一些参数来调整材质属性。
当给定入射光线的方向和辐照度后,BRDF可以给出在某个出射方向上的光照能量分布。
本章涉及的BRDF都是对真实场景进行理想化和简化后的模型,它们并不能真实地反映物体和光线之间的交互,这些光照模型被称为是经验模型。
标准光照模型
虽然光照模型有很多种类,但在早期的游戏引擎中往往只使用一个光照模型,这个模型被称为标准光照模型。
标准光照模型只关心直接光照(direct light),也就是那些直接从光源发射出来照射到物体表面后,经过物体表面的一次反射直接进入摄像机的光线。
标准光照模型把进入到摄像机内的光线分为4个部分,每个部分使用一种方法来计算它的贡献度:
-
自发光(emissive)部分:当给定一个方向时,一个表面本身会向该方向发射多少辐射量。
需要注意的是,如果没有使用全局光照(global illumination)技术,这些自发光的表面并不会真的照亮周围的物体,而是它本身看起来更亮了而已。 - 高光反射(specular)部分:当光线从光源照射到模型表面时,该表面会在完全镜面反射方向散射多少辐射量。
- 漫反射(diffuse)部分:当光线从光源照射到模型表面时,该表面会向每个方向散射多少辐射量。
- 环境光(ambient)部分:描述其他所有的间接光照。
自发光
光线可以直接由光源发射进入摄像机,而不需要经过任何物体的反射。
标准光照模型使用自发光来计算这个部分的贡献度。它的计算也很简单,就是直接使用了该材质的自发光颜色:
通常在实时渲染中,自发光的表面往往并不会照亮周围的表面,也就是说,这个物体并不会被当成一个光源。
Unity 5引入的全新的全局光照系统则可以模拟这类自发光物体对周围物体的影响。
高光反射
这里的高光反射是一种经验模型,并不完全符合真实世界中的高光反射现象。
它可用于计算那些沿着完全镜面反射方向被反射的光线,这可以让物体看起来是有光泽的,例如金属材质。
计算高光反射需要知道的信息比较多,如表面法线、视角方向、光源方向、反射方向等。
漫反射
漫反射光照是用于对那些被物体表面随机散射到各个方向的辐射度进行建模的。
在漫反射中,视角的位置是不重要的,因为反射是完全随机的,因此可以认为在任何反射方向上的分布都是一样的。
但是,入射光线的角度很重要。漫反射光照符合兰伯特定律(Lambert’s law):反射光线的强度与表面法线和光源方向之间夹角的余弦值成正比。
漫反射部分的计算:
环境光
虽然标准光照模型的重点在于描述直接光照,但在真实的世界中,物体也可以被间接光照(indirect light)所照亮。
间接光照指的是,光线通常会在多个物体之间反射,最后进入摄像机,也就是说,在光线进入摄像机之前,经过了不止一次的物体反射。
例如,在红地毯上放置一个浅灰色的沙发,那么沙发底部也会有红色,这些红色是由红地毯反射了一部分光线,再反弹到沙发上的。
在标准光照模型中,我们使用了一种被称为环境光的部分来近似模拟间接光照。环境光的计算非常简单,它通常是一个全局变量,即场景中的所有物体都使用这个环境光。
环境光的计算:
逐像素 / 逐顶点
我们有两种方法计算光照模型:
- 在片元着色器中计算,也被称为逐像素光照(per-pixel lighting)
- 在顶点着色器中计算,也被称为逐顶点光照(per-vertex lighting)
在逐像素光照中,我们会以每个像素为基础,得到它的法线(可以是对顶点法线插值得到的,也可以是从法线纹理中采样得到的),然后进行光照模型的计算。
这种在面片之间对顶点法线进行插值的技术被称为Phong着色(Phongshading),也被称为Phong插值或法线插值着色技术。这不同于我们之前讲到的Phong光照模型。
与之相对的是逐顶点光照,也被称为高洛德着色(Gouraud shading)。
在逐顶点光照中,我们在每个顶点上计算光照,然后会在渲染图元内部进行线性插值,最后输出成像素颜色。
由于顶点数目往往远小于像素数目,因此逐顶点光照的计算量往往要小于逐像素光照。但是,由于逐顶点光照依赖于线性插值来得到像素光照,因此,当光照模型中有非线性的计算(例如计算高光反射时)时,逐顶点光照就会出问题。
而且,由于逐顶点光照会在渲染图元内部对顶点颜色进行插值,这会导致渲染图元内部的颜色总是暗于顶点处的最高颜色值,这在某些情况下会产生明显的棱角现象。