一般而言,Phong光照模型分为三个累加阶段:漫反射,镜面反射和环境光
以下按顺序说明:
1.漫反射(Diffuse)
对于表面比较粗糙的物体,基本表面的明暗就是漫反射效果,比如裤子的材质。某一个象素的明暗系数只取决于该点与光源的相对位置,而与眼睛的位置无关。
diffuse_color = base_map * ( N * V_L )* mat_diffuse * light_diffuse;
上式中base_map代表该点的基础颜色,一般通过纹理索引;
N 是该点的法线;
V_L是该点到光源方向的单位向量;
N * V_L 即两者的点积,注意需要用max( ( N * V_L ), 0 ),因为负的值是没有意义的;
mat_diffuse和light_diffuse分别是材质和光源的漫反射系数,用来宏观调制漫反射的颜色。
下图是只有N * V_L 项的渲染结果:
2.镜面反射(Specular)
尽管漫反射已经可以很好地表达光照,但是由于它是与视点无关的,所以多少有些欠缺生动,
而镜面反射是视点相关的,所以会随着眼睛位置的变化而“流动”。
specular_color = pow( v_e' * v_l, gloss ) * mat_specular * light_specular;
这里解释一下:
v_e' 是e_v的反射向量(v_e' = reflect( e_v, n ) ),
而e_v是眼睛到该点的单位向量,
所谓反射向量,即以与该点的法线所垂直的平面做镜面反射所得到的向量
(虽然按照原理来说,应该是光线反射,而非视线反射...都没有问题吧);
v_l是该点到光源的单位向量;
v_e' * v_l 是两者的点积, 同样要用max(v_e' * v_l, 0),负的值也是不需要的;
pow是幂积,点积是底,gloss是指数;
gloss用来调制亮斑的大小,一般来说,gloss越大,光斑越细小,gloss越小,光斑分布越宽泛。
mat_specular,light_specular分别是材质和光源的镜面反射系数,用来宏观调制镜面反射的颜色。
注意不是点乘,而是各项分别相乘,就是所谓的调制...
下图是只有镜面反射系数的渲染结果:
3.环境光(ambient)
光照不到的地方是不是就是全黑的呢,对于受空气散射影响比较大的环境来说不是的
(比如说室外环境),这里只是简单的对base_map调制了一下:
ambient_color = base_map * mat_amvient * light_ambient;
4.累加(accumulate)
最后就是将他们相加了:
result_color = diffuse_color + specular_color + ambient_color;
5.其他
(1)在以上式中所使用的法线是由各顶点的法线插值得到的,我们可以使用法线贴图来编码
各点的实际法线值,以获得更细致的表面:
转自:http://hi.baidu.com/gltracy/item/37f5852939404af850fd87d5