之前加载模型的时候用的是方向光和phong模型实现的,这次试用点光源和blin-phong实现
blin-phong是简化的phong模型,能实现phong差不多的效果,效率比phong高很多
效果如下图所示:
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;
时间: 2024-10-06 00:38:32