之前加载模型的时候用的是方向光和phong模型实现的,这次试用点光源和blin-phong实现

blin-phong是简化的phong模型,能实现phong差不多的效果,效率比phong高很多

效果如下图所示:

wKioL1kug_yz4AvxAABPdvAfxRU198.jpg-wh_50


1、点光源

这里光源的位置是传入一个vec4的向量,第四个分量为0表示方向光,为1表示点光源。

与方向光相同,基础强度为物体指向光源的向量点乘法线,但是还要乘上衰减系数

公式如下:

衰减系数 = 1.0 / (衰减常数 + 线性衰减系数 * 距离 + 平方衰减系数 * 距离 * 距离)

Fragmen Shader相关部分代码:

vec3 light = M_LightPos.xyz;
float distanceLight = 0.0;      // 距离光源的距离
float attenuation = 1.0;         // 衰减系数// 衰减因子
float constantFactor = 0.9; // 常亮衰减常数
float linerFactor = 0.05;  // 线性衰减系数
float expFactor = 0.0;    // 平方衰减系数// 点光源
if (M_LightPos.w != 0.0)
{light = M_LightPos.xyz - M_WordPos;distanceLight = length(light);attenuation = 1.0 / (constantFactor + linerFactor * distanceLight + expFactor * distanceLight * distanceLight);
}
vec3 LightNormal = normalize(light);       // 指向光源的单位向量
vec3 NormalNormal = normalize(M_normal);      //  法线的单位向量// 点乘获取光照强度
vec4 diffuseColor = M_DiffuseLightColor * M_DiffuseMaterial * max(0.0, dot(NormalNormal, LightNormal)) * attenuation;


2、blin-phong

计算镜面反射光照强度时,计算反射光线是比较耗时的下面介绍phong和blin-phong的计算方法


眼睛的位置在vec3(0.0, 0.0, 0.0)

phong

标准phong模型计算光照强度,反射光线与点到眼睛的单位向量点乘
vec3 reflerDir = normalize(reflect(-LightNormal, NormalNormal));
vec3 eyeDir = normalize(vec3(0.0) - M_WordPos);
float specularIntensity = pow(max(0.0, dot(reflerDir, eyeDir)), 100);

blin-phong

bline-phong模型计算光照强度,半角光线与法线的点乘
半角光线计算,光源向量+点到眼睛的向量
vec3 eyeVector = vec3(0.0) - M_WordPos;
vec3 halfDir = normalize(light + eyeVector);
float specularIntensity = pow(max(0.0, dot(NormalNormal, halfDir)), 150);
// 高光
vec4 specularColor = specularLightColor * specularMaterial * specularIntensity * attenuation;