OpenGL学习脚印:光源类型和使用多个光源(Light source and multiple lights)

写在前面
上一节光照中使用材质和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 增大时光照的强度将会减弱。我们需要模拟这个特点来是点光源更加逼真。光照强度的衰减系数 Fatt 与距离 d 之间的关系如何确定呢? 如果简单的使用线性函数,距离稍微远点的物体光照强度减小得太过于明显,不符合实际情况,因此一般要考虑使用二次函数。可以定义光照强度的衰减系数 Fatt 与距离 d 之间的关系如下式:

F
  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值