Blinn-Phong光照模型是在Phong的基础上改造过来的,我们知道Phone光照模型中:
光照 = 漫反射(Diffuse) + 高光反射(Specular) + 环境光(Ambient)
漫反射和环境光的计算方式,Blinn-Phong和Phong是相同的,唯一的区别在于高光反射的计算。
在此之前,请先对Phong光照模型有比较清楚的了解,具体地可以查看光照模型的原理和实现思路——Phong
在Phong光照模型中,它计算高光反射的公式是:
用代码来表示:
half3 view_dir = normalize(_WorldSpaceCameraPos.xyz - i.pos_world);
half3 reflect_dir = reflect(-light_dir, normal_dir);
half RdotV = dot(reflect_dir,view_dir);
half3 spec_color = max(0.0,RdotV) * _LightColor0.xyz;
它是通过光照的反方向和顶点法线方向,先计算出反射方向。
然后将反射方向和摄像机观察方向的进行点乘后,最后得出高光反射的颜色。
用下图来表示,就是调用reflect函数,传入矢量I (光源方向)的负方向矢量和矢量n(法线方向),求出矢量r(反射方向),然后矢量r和矢量v(观察方向)进行点乘,最后得出高光反射的结果。
但Blinn-Phong光照模型采用的另外一种优化后的计算方式,以下图为例:
它首先将I矢量和v矢量相加,得到一个半角矢量h;然后半角矢量h和矢量n进行点乘,得到另一个新矢量,然后使用这个新矢量来计算高光反射。
用代码表示就是:
// Blint-Phong光照模型的计算
half3 half_dir = normalize(light_dir + view_dir);
half NdotH = dot(normal_dir,half_dir);
half3 spec_color = pow(max(0.0,NdotH),_Shininess) * _LightColor0.xyz * _SpecIntensity * spec_mask.rgb;
Phong模型和Blinn-Phong模型最大的不同,一个是根据反射方向(r)和观察方向(v)的夹角来计算高光,而另一个是根据半角方向(h)和法线方向(n)来计算高光。
两种光照模型并没有孰优孰劣之分,但一般情况下,Blinn-Phong模型的计算速度会比Phong模型更快。