光照是3D游戏中一个必不可少的部分,场景氛围的渲染需要光照来表现:
上面是巫师3中的夜景,如果没有光的画整个表现力将会降低很大的一个层次,这一节我们将了解光照的形成过程以及各个光照模型。
一、光源:
1.光形成图像的过程
先来了解一下光线从产生到形成我们眼中图像的过程:
这当中涉及到光的反射、折射,最后光进入人眼,形成了图像,这就是光形成图像的过程。
2.光源的相关要素
1.矢量:
光源是一个矢量,他具体位置和方向,例如Unity中的方向光、点光源,都具备矢量的性质。
2.量化:
下面是维基百科中关于光强的介绍
辐照度:辐照度表示各种频率辐射的总量。物理学者时常也会分开检验辐射频谱的每一单独频率。假设对于入射于曲面的辐射做这动作,则称这辐射为光谱辐照度(spectral irradiance),国际单位制的单位为W/m2。在光学和激光物理学中,辐照度也被叫做光强。
地面上一块平面的总辐照度等于“直接辐照度”与“漫辐照度”的代数和,光强与光和物体表面的夹角有关,具体会在下面介绍。
3.光的吸收与散射
光线发射出来与物体相交后,会有两个结果,一个是散射
另一个是吸收
。
- 散射:只改变光线方向,而不改变光线密度和颜色。散射根据光线改变后的方向分为两种,若光线散射到物体内部的现象则称为折射,而散射到物体外部的现象则称为反射。
- 吸收:只改变光线的密度和颜色,而不改变光线方向。
从上图中我们可以看到光从发射到与物体表面相交后的各种情况,光线有的被吸收有的被反射有的发生了折射。其中的蓝色光线表示漫反射,而黄色光线表示高光反射。在光照模型中我们会使用不同部分来表示光线的这几种情况:
- 高光反射(Specular):表示物体表现是如何直接反射光线的
- 漫反射(Diffuse):表示光线如何被折射及吸收后反射的
通常用出射度表示出射光线的数量和方向,出射度与辐照度之间是存在线性关系的。
4.着色
着色指的是根据材质属性、光源属性,使用一个公式去计算沿某个观察方向的光线出射度的过程,这个公式我们也将之称为光照模型。
5.各向异性与各向同性
各向异性 (anisotropy ) 与 均向性 相反,是指在不同方向具有不同行为的性质,也就是其行为与方向有关。如在物理学上,沿着材料做不同方向的量测,若会出现不同行为,通常称该材料具有某种“ 各向异性 ” ,这样的材料表面称为各向异性表面( anisotropic surface )。
光照模型中也存在着各向同性和各向异性的区别,例如Lambert漫反射模型是各向同性的,无论我们从哪个方向进行观察,物体表面的光照表现都是不变的,而Phong光照模型中的高光反射则是各向异性的,物体表面的光照表现会随着观察角度的变化而变化。
二、光照模型
现实世界的光照是非常复杂的,若要准确的模拟,整体计算量会非常的大,这在游戏渲染中是不现实的,而光照模型则提供了一种性价比较高的方案,它是一种经验模型,是对真实场景进行理想化和简化后的模型,可以模拟光从发射到与物体相交再到人眼中的效果。
计算机图形学第一定律:如果它看来是对的,那么它就是对的
现实世界中的光照,分为两种直接光照和间接光照:
直接光照:表示直接从光源发射出来照射到物体表面后,光线经过物体表面的一次反射后直接进入摄像机
间接光照:表示光线从光源发射出来后,经过不止一次的物体反射后进入摄像机
标准光照模型
光照模型有不同种类,而游戏引擎中往往只使用一个光照模型,我们称之为标准光照模型。一般光照模型会包含以下几个要素:
- 自发光(Emission):用于描述当给定一个方向时,一个表面本身会向该方向发射多少辐射量。
- 环境光(Ambient):在现实世界中无论多么黑暗,世界都会有一些光亮(月光、远处的光)在照亮物体,环境光就是用于模拟无论什么情况都会给物体颜色的这种情况。
- 漫反射(Diffuse):模拟一个发光物体对物体的方向性影响,面向光的一面会比另一面更亮。
- 高光(Specular):模拟有光泽物体表面上的亮点,其颜色更倾向于光的颜色而不是物体表面的颜色。
标准光照模型只关心直接光照,下面说一下标准光照模型的历史。
1.Lambert模型
Lambert是理想的漫反射模型,他表现的材质较为均匀,不能反映粗糙度带来的变化。
同等数量的光照射的面积越小,单位表面积收到的光的能量越多,这个原则也构成了Lambert定律:
Lambert定律:反射光照的强度与表面法线和光源方向夹角的余弦值成正比
因此Lambert对应的公式为:
C(result) = n · i · (C(light)·C(diffuse))
其中n向量表示表面法线,i向量表示光与表面交点指向光源的向量,C(light)表示光的颜色,C(diffuse)表示漫反射的系数。
2.Phong(冯氏光照模型)(1975)
冯氏光照模型引入了高光来增强渲染真实感,从下图可以看到,他引入了观察者视角这一参数,反射向量R与视角向量V的夹角决定了高光的强度。
Phong = Ambient(环境光)+ Diffuse(漫反射) + Specular(高光)
从上图可以看到,Phong氏光照模型由三个部分组成:环境光、漫反射、高光反射。其中的Diffuse在上面已经讲过了,而Specular(高光反射)则是一个与用户视线相关的值,通过反射光线的向量与视线方向的点积来影响高光的值,如果反射光线与视线方向的夹角越小,则高光的作用越大。同时还加入了一个发光值(Shiness),来控制高光扩散程度。下面是Phong模型的数学展示图。
C(Specular) = (C(light)·C(Specular))·pow(max(0, V·R), shiness)
其中C(light)表示光的颜色,C(Specular)表示高光反射的系数,shiness则表示发光值。下面看下不同的发光值对Phong的影响,可以看到发光值越大,散射得越少,高光点越小。
Phong模型是在片段着色器中实现的,而在早期的光照着色器中,开发者在着色器中实现冯氏光照,这种模型Gouraud模型
,下面是这两者的区别。
- Phong模型:在片段着色器中实现,效果好,效率相对低
- Gouraud模型:在顶点着色器中实现,效果差,效率相对高
3.Blinn-Phong(1977)
Phong模型效果不错,性能也较高,但是,如果光源在靠近视野的位置的话就会出现反射向量与视线向量的夹角大于90度,从上面的Specular公式可以知道,Phong模型不允许两向量的点积值小于0,也就是不允许他们的夹角大于90度。
上面这种情况会导致镜面区域边缘迅速减弱并截止,如下图远处的暗处:
1977年James F. Blinn引入了Blinn-Phong着色,它扩展了我们目前所使用的Phong着色。Blinn-Phong模型很大程度上和Phong是相似的,不过它稍微改进了Phong模型,使之能够克服我们所讨论到的问题。
Blinn-Phong中引入了半程向量这一概念,半程向量h是视线向量与光线方向向量的和归一化后的结果,将这个值与表面法线进行点乘得到结果。
h = normalize(lightdir + viewdir)
C(Specular) = (C(light)·C(Specular))·pow(max(0, h·n), shiness)
引入半程向量来计算镜面反射后,我们再也不会遇到Phong着色的截止问题了,下面是对比图:
可以看到截止的问题已经消失了,整个过渡更加的真实。
Unity实现对应光照模型
To be continued...
参考
[1]https://zh.wikipedia.org/wiki/辐照度
[2]http://www.cnblogs.com/mengdd/archive/2013/08/05/3238123.html
[3]http://learnopengl-cn.readthedocs.io/zh/latest/02%20Lighting/02%20Basic%20Lighting/