数学可视化(11)——Phong与Blinn-Phong

  1. 1. 前言
  2. 2. Phong经验光照模型
  3. 3. Blinn-Phong经验光照模型

 

前言

  • 对于光滑表面表现出来的镜面反射高光,Lambert模型的表现就乏力了

Phong经验光照模型

  • 镜面反射分量的光强,与反射光线向量r及视线向量v的夹角α相关
  • Phong光照方程:
  • Ispec = Clight * mspec * (r · v)mgloss = Clight * mspec * (cosα)mgloss
  • Clight为光源颜色或强度
  • mspec为材质的镜面反射系数,也可理解为材质镜面反射的颜色
  • 反射光线方向r可由入射方向光l和物体表面法线n求出。公式为:r = 2 (n · l) * n - l
  • mgloss代表光泽度,也就是物体表面的光滑程度
  • 反射光线方向与观察方向的夹角越小,镜面反射高光的贡献值就越大,高光强度就越强
  • 换句话说,镜面反射的光强与观察者的角度有关。Phong光照模型有助于观察者了解物体表面的弯曲情况,判断出光源方向和位置


1
2
3
4
5
6
// Phong光照模型
float3 Phong(float3 lightDir, float3 normal, float3 viewDir, float shininess, float3 lightColor, float3 specularColor)
{
float3 reflectDir = reflect(-lightDir, normal);
return lightColor * specularColor * pow(max(0.0, dot(reflectDir, viewDir)), shininess);
}
  • 先计算反射光方向,再根据光源颜色、镜面反射系数、反射光方向和观察者向量点乘的结果,以及光泽度,计算出镜面反射分量

  • 白点就是Phong光照模型计算出的镜面反射分量,也就是高光的表现
  • 再将环境光照、漫反射光照与镜面反射光叠加,就可以得到一个经典的局部光照模型了
1
2
3
4
5
...
float3 ambient = float3(0.2, 0.2, 0.2);
float3 diffuse = Lambert(lightdirI, n, lightColor, matColor);
float3 specular = Phong(lightdirI, n, -rayDir, 32.0, lightColor, matColor);
c += ambient + diffuse + specular;

Blinn-Phong经验光照模型

  • 是基于Phone光照模型的修正模型,只是将公式中的(r · v)换成了(n · h)
  • h为半角向量(半程向量),位于观察向量v与光线l的角平分线方向,可以由l+v单位化后获得,比计算反射向量r更快
  • 对比发现,Blinn-Phong与Phong模型都有高光表现,但Blinn-Phong的高光表现在相同的光泽系数下,高光表现更为分散一些