Unity Shader Blinn-phong光照模型
一、镜面反射简介
对于许多物体,漫反射不够真实,比如擦亮的金属、光滑的塑料。要模拟光滑表面,还需要添加镜面高光反射的颜色,。在金属这样的光滑表现上,能模拟出光泽
1. 理想镜面反射
一束平行光射到平面镜上,入射光严格遵循光的反射定律平行的反射出去,这种反射叫做镜面反射。
2. 非理想镜面反射
现实中的物体表面都不是完全光滑的。在微观上物体的表面面元是由许多朝向的微小平面组成,其镜面反射光分布于物体镜面反射方向的周围。
3. 镜面反射光特点
- 跟入射方向有关
- 跟观察的角度有关
黑暗的房间中,手电筒的光射向一面镜子,只有眼睛与光线平行的时候才能看到光,改变观察的角度看到不到光。
二、光照模型
1. Phong光照模型
Phong光照模型属于经验模型,它在Lambert模型(纯漫反射模型)的基础上考虑了镜面反射的效果,该模型只考虑物体对方向光的镜面反射作用,不考虑环境光的镜面反射(认为环境光只发生漫反射),主要用来模拟光滑物体表面的光照现象。
此模型假设物体表面为非理想镜面反射体(既会发生漫反射也会发生镜面发射,且镜面反射为非理想的镜面反射),场景中存在两种光,一种为环境光,一种为方向光,然后我们分别计算这两种光照射到物体表面所产生的光照现象(注意:phong不考虑环境光的镜面反射,也就是说我们要考虑到环境光的漫反射和方向光的漫反射和镜面反射),最后再将两个结果相加,得出反射后的光强值。
首先是计算环境光的公式:
I_inDirectionDiffuse = K_d * I_a;
其中,K_d为粗糙物体表面材质对光的反射系数,这个系数由程序编写者在宿主程序中给出,I_a为环境光的光强,也就是环境光的颜色数值,一般是一个float3型的变量
然后是计算方向光的公式:
I_direction = I_directionDiffuse + I_directionSpecular;
I_directionDiffuse = K_d * I_l * max(0,dot(N, L)); //方向光漫反射强度
I_directionSpecular = K_d * I_l * pow( max(0, dot(R,V)), n); //方向光镜面射强度
其中I_l为方向光的光强,也就是其颜色值;N为顶点的单位法向量;L为入射光的单位法向量(注意,光照向量是从顶点指向光源的向量;也就是,它与线的传播方向正好相反)。R表示反射光的单位向量,V为顶点到视点的向量。
我们知道,在理想状况下,镜面反射后的光之集中在一条线上,因此我们的视线离这条线的距离越近,射入我们眼中的光线就越多,我们看到的光强也就越强。同时,镜面反射也与物体表面的高光指数(物体表面光泽程度)有关,其数值