在phong模型中,高光区域有明显的断层,这是因为镜面反射中,视线方向与反射方向角度大于90度,镜面光为0,实际上在较为粗糙的表面,镜面光仍有影响。
在此我们引入一种改进模型:Blinn-Phong着色模型
它唯一的变化是在计算镜面反射时加入了一个半程向量,如图,即光线与视线夹角一半方向上的一个单位向量。当半程向量与法线向量越接近时,镜面光分量就越大。
因此计算过程也变成了这样:
vec3 halfwayDir = normalize(lightDir + viewDir);
float spec = pow(max(dot(normal, halfwayDir), 0.0), shininess);
vec3 specular = lightColor * spec;
这样一来,镜面分量永远都会大于0,另外,半程向量与表面法线的夹角通常会小于观察与反射向量的夹角。所以,如果你想获得和冯氏着色类似的效果,就必须在使用Blinn-Phong模型时将镜面反光度设置更高一点。通常我们会选择冯氏着色时反光度分量的2到4倍。
视觉上,blinn-phong模型要更加锐利一些,它的运算效率也更高,所以应用的更广泛。