第十九节—光照计算1
本文为L_Ares个人写作,如需转载请表明原文出处。
在我们经常玩的游戏中呢,可以找到光照的效果,但是无论哪个游戏引擎,它都是在模拟光照,这就需要我们进行关照的计算。游戏引擎也不可能创建真实的光照,也是在模拟光照。
一、光照类型
- 环境光照(ambient)
就是模拟自然光。比如正常白天的时候,物体是都可以反光的,同样的,在夜晚或者在黑暗的环境下,物体也不可能是完全看不到的轮廓的,因为自然光现实情况中都是存在的,所以说所有的物体不可能完全的黑暗,这个存在的光就是环境光照。
一般情况下,环境光照最多的场景可能就是太阳,照射到物体表面,发生折射,物体变得可见。
环境光照是没有起点的,不可能像手电筒一样,直接就能随意控制的打开关闭,想打光到哪里就打光到哪里。
- 漫反射光照(diffuse)
漫反射光照模拟的是发光物体对其他物体方向的影响。比如一个物体有一面是面向光照的,那么这个面就会亮一些,看的清楚一些,而他的侧面或者背面是没有被光照射的,那么他就会比较暗一点。
- 镜面光照(specular)
镜面光照是相对平滑的表面被光照射,物体的表面会出现一个聚焦的亮点,这个亮点的亮度会比周边明显,比如你晚上打手电筒的时候,照射在一个玻璃上,就是这种效果。
- 综合光照(combined(Phong))
综合光照是综合了上面三个常见的光照类型的光,它们的效果会combined,显示的会比较真实一点。
一般情况下,光照不会出自单一的光源,所以综合光照可能会更普遍一些。
二、光照特性
一个物体表面产生的光照颜色不仅仅是由光照单独决定的,还会由它的材质等因素决定。
- 发射光
由物体本身发光,这就是发射光,比如太阳。
- 环境光
环境光是充斥在环境中的散射的光,是没有方向性的。比如你的房间里面,你知道房间是有光的,但是这个光从哪里来的,这是无法确认的。
- 漫反射光
漫反射光是来自于某个方向,打到了物体上,经过了物体的各个方向的反射,把物体显示了出来。
- 镜面高光
镜面高光是有一个特定的方向的,光会由特定的方向照射到光滑物体表面,然后会被物体表面以一个特定的方向反射出去。
三、材质属性
还是那个道理,光不是自己就决定了物体显示的颜色的,是和物体的材质相关的。
物体呈现出来的颜色是由光和材质共同决定的。
- 泛射材质
泛射材质的物体,当光直射过去的时候,它的反射率是很高的。
- 漫反射材质
漫反射材质的计算要考虑到光的入射角和反射角,需要计算它的夹角。
- 镜面反射材质
会有一些斑斑点点的感觉,比如一些光晕。
- 发射材质
就是这个物体的材质本身就有光,比如一个夜明珠。
四、光照计算
1. 环境光的计算
环境光 = 光源的环境光颜色 * 物体的材质的颜色
物体材质的颜色在OpenGL中可以通过texture2D
获取物体对应的纹素来获取。
环境光的计算举例(包含亮度参数,或者说阴影参数):
设 :
物体的材质的颜色 : Pixel_Color = ,
光源的环境光颜色 : Light_Color = ,
亮度(阴影) : A = Ambient intensity
最终物体显示的颜色 : Final_Pixel_Color
Final_Pixel_Color = Light_Color * Pixel_Color * A
2. 发射光的计算
发射光颜色 = 物体的反射材质颜色
3. 漫反射光照计算
漫反射光照颜色 = 光源的漫反射颜色 * 物体材质的漫反射颜色 * diffuseFactor
diffuseFactor = max(0,dot(N,L))
取得是0到N和L点乘的最大值,diffuseFactor被称作漫反射因子,它的值是光线与顶点法线向量的点积,也就是求角度。
光线是要自己设置的,光从哪里来要看需求。
点的法线向量是可以算的。
漫反射光照可以增加物体显示的真实度。
漫反射光照的光照强度是光本身强度和光线与物体表面法线的夹角cos值的乘积决定的。
有效的光照方向是光线与物体表面法线夹角在0~90度之间的。因为你的光不可能从地面照射出来。
漫反射的简单示意图如图4.1所示:
4.1.png4. 镜面光照计算
镜面光照颜色 = 光源的镜面光颜色 * 物体的镜面材质颜色 * SpecularFactor
SpecularFactor = power(max(0,dot(N,H)),shiniess)
N : 平面法线向量
H : 视线向量E和光线向量L的半向量
dot(N,H) : 两个向量夹角的cos值
shiniess : 光的反光度。自己来设置的。
power函数 : 返回的是第一个参数的第二个参数次幂。
如下图4.2所示:
4.2.pngN : 平面法线
L : 入射光线
H : 反射光线
E : 视线
∂ : 视点与反射光线的夹角
5. 光照颜色计算
光照颜色 = (环境颜色 + 漫反射颜色 + 镜面反射颜色) * 衰减因子
这里没有发射光颜色是因为没有那么多的物体可以自己发光。
五、影响光照的因素
光照不是计算出来就可以的,毕竟这是模拟光源,要想显得真实,就需要做很多的工作,计算机在模拟光照的时候需要设置一些常用的影响因素,比如下列:
1. 衰减因子
光是会衰减的,不是照射过来就一成不变的,所以颜色最后要乘以衰减因子,才是到达或者说我们看到的颜色。
衰减因子的计算:
注释:
衰减因子 = 1.0 / (距离衰减常量 + 线性衰减常量 * 距离 + 二次衰减常量 * 距离的平方)
其中,距离衰减常量、线性衰减常量、二次衰减常量都是常量值,这都是我们要自己设置的。
环境光、漫反射光、镜面光的光照强度都会随着距离的增加而衰减,只有发射光和全局常量光的强度不受距离增大而衰减的限制。
2. 聚光灯因子
想计算聚光灯因子,就要先计算聚光灯夹角的cos值。
聚光灯夹角cos值 =
power
(max
(0,dot
(单位光源位置,单位光源向量) ), 聚光灯指数)
单位光源向量 :光源指向顶点的单位向量。
聚光灯指数 : 聚光灯的光亮强度
所以聚光灯夹角的cos值是:0到单位光源位置与单位光源向量的点积的最大值的聚光灯指数次幂。
有聚光灯过渡的图形会有一层薄雾感,显得更贴近现实。
聚光灯因子的计算
聚光灯因子 =
clamp
( (外环的聚光灯角度cos值 - 当前顶点的聚光灯角度的cos值) / (外环的聚光灯角度cos值 - 内环的聚光灯角度cos值), 0 ,1 );
六、光照的最终计算公式
光照颜色 = 发射颜色 + 全局环境颜色 + (环境颜色 + 漫反射颜色 + 镜面反射颜色) * 聚光灯效果 * 衰减因子;