写在前面
上一节光照中使用材质和lighting maps介绍了使用材质属性和lighting maps使物体的光照效果能反映物体的材料特性,看起来更逼真。在前面的章节中使用的实际上都是一个点光源,本节将学习其他几种光源类型,以及在场景中使用多个光源。本节代码均可以在我的github下载。
本节内容整理自:
1.www.learnopengl.com light casters
2.www.learnopengl.com Multiple lights
通过本节可以了解到
- 方向光源
- 点光源
- 聚光灯光源
- 使用多个光源
光源类型
在前面章节中,我们通过位置和成分分量大小来指定光源属性,这个光源实际上是一个点光源。除了点光源外,还包括方向光源,聚光灯光源等其他类型的光源,他们的特点如下图所示(来自Simple Lighting):
使用不同的光源主要是为了模拟现实环境中不同类型的光,使场景光照效果更能满足需求。每种类型的光源各有其特点,下面予以介绍。
方向光源
方向光源的特点就是光的方向几乎都平行,只有一个方向,这是为了模拟光源在无限远处的情景,例如太阳光。方向光源一般不考虑光的衰减,它与光源具体位置无关,我们只需要为它指定方向即可。注意一般我们指定方向光源的方向时,习惯从光源指向物体,而在计算光照时,又需要从物体指向光源的方向,因此需要做一个翻转。指定方向光源的结构体在着色器中定义为:
// 方向光源属性结构体
struct DirLightAttr
{
vec3 direction; // 方向光源
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
在计算光照时,我们不必利用物体的位置和光源位置计算光源方向了,
// 不再需要
vec3 lightDir = normalize(light.position - FragPos);
直接使用这个direction即可:
vec3 lightDir = normalize(-light.direction); // 翻转方向光源的方向
在着色器中计算光照的效果与上一节的光照计算是相同的:
void main()
{
// 环境光成分
vec3 ambient = light.ambient * vec3(texture(material.diffuseMap, TextCoord));
// 漫反射光成分 此时需要光线方向为指向光源
vec3 lightDir = normalize(-light.direction); // 翻转方向光源的方向
vec3 normal = normalize(FragNormal);
float diffFactor = max(dot(lightDir, normal), 0.0);
vec3 diffuse = diffFactor * light.diffuse * vec3(texture(material.diffuseMap, TextCoord));
// 镜面反射成分 此时需要光线方向为由光源指出
float specularStrength = 0.5f;
vec3 reflectDir = normalize(reflect(-lightDir, normal));
vec3 viewDir = normalize(viewPos - FragPos);
float specFactor = pow(max(dot(reflectDir, viewDir), 0.0), material.shininess);
vec3 specular = specFactor * light.specular * vec3(texture(material.specularMap, TextCoord));
vec3 result = ambient + diffuse + specular;
color = vec4(result , 1.0f);
}
另外还需要在主程序中指定光源的方向如下:
GLint lightDirLoc = glGetUniformLocation(shader.programId, "light.direction");
glm::vec3 lampDir(0.5f, 0.8f, 0.0f);
glUniform3f(lightDirLoc, lampDir.x, lampDir.y, lampDir.z); // 方向光源
使用方向光源的效果就是,场景中无论远近,物体得到的光照都一样,光从同一个平行的方向射向物体表面,效果如下图所示:
点光源
在前面两节使用的光源都是一个简单的点光源,场景中物体不管离光源位置远近得到的光照强度都相同,这一点与实际不相符合。实际中的点光源向各个方向发射光,但是物体与光源的距离 d 增大时光照的强度将会减弱。我们需要模拟这个特点来是点光源更加逼真。光照强度的衰减系数