1. 流程

简单的光照材质无法满足要求,接下来我们要对不同材质的物体在各个片段的反射做出精准控制

1.1 漫反射贴图

之前,我们对物体的环境光和漫反射做了简单的单色定义,现在我们加入纹理贴图,让纹理的颜色作为环境光和漫反射的颜色:

因为环境光和漫反射的颜色基本都是纹理颜色,所以我们给他归为一个materials输入属性(利用之前的纹理采样器sampler2D定义,sampler2D是所谓的不透明类型(Opaque Type),也就是说我们不能将它实例化,只能通过uniform来定义它。如果我们使用除uniform以外的方法(比如函数的参数)实例化这个结构体,GLSL会抛出一些奇怪的错误。这同样也适用于任何封装了不透明类型的结构体。)

#version 330 core
struct Material {sampler2D diffuse;vec3 specular;float shininess;
}; struct Light {vec3 position;vec3 ambient;vec3 diffuse;vec3 specular;
};out vec4 FragColor;in vec3 Normal;
in vec3 FragPos;
in vec2 Texcoords;uniform vec3 objectColor;
uniform vec3 lightColor;
uniform vec3 lightPos;
uniform vec3 viewPos;
uniform Material material;
uniform Light light;void main()
{    // 环境光vec3 ambient = light.ambient * vec3(texture(material.diffuse, Texcoords));// 漫反射 vec3 norm = normalize(Normal);vec3 lightDir = normalize(lightPos - FragPos);float diff = max(dot(norm, lightDir), 0.0);vec3 diffuse = light.diffuse * (diff * vec3(texture(material.diffuse, Texcoords)));// 镜面光vec3 viewDir = normalize(viewPos - FragPos);vec3 reflectDir = reflect(-lightDir, norm);  float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);vec3 specular = light.specular * (spec * material.specular);  vec3 result = ambient + diffuse + specular;FragColor = vec4(result, 1.0);
}

别忘记设置它的纹理单元,渲染的时候绑定激活:

 ourShader.use();ourShader.setInt("material.diffuse", 0);
 glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_2D, texture[0]);

效果:

1.2 镜面光贴图

解决了环境光和漫反射,接下来我们要解决镜面反射的问题,从上面的图来看,镜面高光看起来有些奇怪,因为我们的物体大部分都是木头,我们知道木头不应该有这么强的镜面高光的。

我们可以将物体的镜面光材质设置为vec3(0.0)来解决这个问题,但这也意味着箱子钢制的边框将不再能够显示镜面高光了,我们知道钢铁应该是有一些镜面高光的,所以我们可以使用一个专门用于镜面高光的纹理贴图。


镜面高光的强度可以通过图像每个像素的亮度来获取。镜面光贴图上的每个像素都可以由一个颜色向量来表示,比如说黑色代表颜色向量vec3(0.0),灰色代表颜色向量vec3(0.5)。在片段着色器中,我们接下来会取样对应的颜色值并将它乘以光源的镜面强度。一个像素越「白」,乘积就会越大,物体的镜面光分量就会越亮。

过程与漫反射贴图基本一致,这里就不赘述了

效果:

可见,镜面高光反射的效果就真实了许多

2. 练习

2.1 调整光源的环境光、漫反射和镜面光向量,看看它们如何影响箱子的视觉输出。

光源的环境光影响了背光处的亮度,漫反射光影响了面光处的亮度,镜面光影响了高光处的亮度

2.2 尝试在片段着色器中反转镜面光贴图的颜色值,让木头显示镜面高光而钢制边缘不反光(由于钢制边缘中有一些裂缝,边缘仍会显示一些镜面高光,虽然强度会小很多)

vec3 specular = light.specular * (spec * (1 - vec3(texture(material.specular, Texcoords))));

由于钢制边缘贴图大多数为灰色,所以反转的效果并不是很好,还是能看到不少高光:

2.3 使用漫反射贴图创建一个彩色而不是黑白的镜面光贴图,看看结果看起来并不是那么真实了。如果你不会生成的话,可以使用这张彩色的镜面光贴图

钢制材质显现出红色,看起来不够真实

2.4 添加一个叫做放射光贴图(Emission Map)的东西,它是一个储存了每个片段的发光值(Emission Value)的贴图。发光值是一个包含(假设)光源的物体发光(Emit)时可能显现的颜色,这样的话物体就能够忽略光照条件进行发光(Glow)。游戏中某个物体在发光的时候,你通常看到的就是放射光贴图(比如 机器人的眼,或是箱子上的灯带)。将这个纹理(作者为 creativesam)作为放射光贴图添加到箱子上,产生这些字母都在发光的效果


读取纹理后直接在片段着色器的结果处加上这个纹理的颜色就相当于发光了

vec3 result = ambient + diffuse + specular + vec3(texture(emission, Texcoords));

效果:

【OpenGL】笔记十三、光照贴图相关推荐

  1. 【OpenGL学习】光照贴图

    光照贴图 上节中我们给物体添加了材质,使得物体能够对光照做出不同的反应,但是有个问题就是,使用该种材质的物体,只能够表现出我们所定义的一种性质,而实际生活中我们的一个物体往往具有多种材质,因此本节中我 ...

  2. OpenGL学习笔记:光照贴图

    漫反射贴图 简单说就是在上一节的基础上给物体添加上纹理,主要做两件事,将之前定义的vec3漫反射颜色向量替换为漫反射贴图,删除环境光源 这里就不贴完整例子了,简单说一下着色器的主要修改,添加纹理的部分 ...

  3. OPenGL笔记--给立方体贴图(纹理)

    文章目录 一.前置知识 二.效果展示. 三.完整代码 附.给立方体每个面渲染不同的纹理 一.前置知识 经过前面的学习,我们已经知道了立方体怎么创建了,接下来学习怎么给立方体贴图: 为了将纹理正确的映射 ...

  4. OpenGL学习笔记(十三):将纹理贴图应用到四边形上,对VAO/VBO/EBO/纹理/着色器的使用方式进行总结

    原博主博客地址:http://blog.csdn.net/qq21497936 本文章博客地址:http://blog.csdn.net/qq21497936/article/details/7919 ...

  5. OpenGL学习笔记(四)-光照-材质-光照贴图

    参考网址:LearnOpenGL 中文版 哔哩哔哩教程 第二章 光照 2.1 颜色 现实生活中人眼看到某一物体的颜色,是它所反射的颜色.如将白光照在红色的玩具上,玩具会吸收白光中除了红色以外的所有子颜 ...

  6. OpenGL Lightmap光照贴图的实例

    OpenGL Lightmap光照贴图 先上图,再解答. 完整主要的源代码 源代码剖析 先上图,再解答. 完整主要的源代码 #include <glad/glad.h> #include ...

  7. OpenGL 光照贴图Lighting maps

    OpenGL光照贴图Lighting maps 光照贴图Lighting maps简介 漫反射贴图 镜面光贴图 采样镜面光贴图 光照贴图Lighting maps简介 在上一节中,我们讨论了让每个物体 ...

  8. OpenGL原理与实践——核心模式(六):光照贴图、光源分类以及多光源场景主要源码实现

    本章主要以代码为主,理论理解即可.详细分析代码 目录 光照贴图 光源分类 平行光 点光源 shader--点光源 聚光灯 聚光灯边缘优化--光强递减 源码解析 main 全局变量.句柄 main函数主 ...

  9. 虚幻引擎图文笔记:调整网格的光照贴图分辨率(Light Map Res)改善光照烘焙质量

    通过调整网格的光照贴图分辨率(Light Map Res)改善光照烘焙质量 问题描述 下图所示的场景非常简单,光源是一个标记为Static的点光源(Point Light),经过烘焙之后,不难看出光斑 ...

  10. OpenGL光照贴图

    光照贴图 1. 光照贴图的意义 2. 漫反射贴图 3. 镜面光贴图 1. 光照贴图的意义 现实世界中的物体通常并不只包含有一种材质,而是由多种材质所组成.只有光照颜色的材质系统是不够的,它只是一个最简 ...

最新文章

  1. python自学视频教程-私藏已久的7个Python视频教程
  2. 信息项目管理师-整体管理知识点
  3. python生成xml文件工具_Python根据指定文件生成XML的方法
  4. 新版chrome调整开发者工具位置方式改变
  5. Oracle10g数据库的完全卸载:
  6. 巨人网络305亿并购海外棋牌类游戏公司审核遭暂停
  7. Python求梅森尼数
  8. windows设置定时自动关闭应用
  9. 六祎-简单的排版表(python)
  10. 卸载360天擎企业版
  11. 大使、布道师、贡献者,OpenHarmony社区发起三大贡献者激励计划
  12. 【历史上的今天】8 月 20 日:两位传奇程序员的诞生日!
  13. 【六祎 - HTML模板】提交按钮模板-带特效
  14. 影响蓝牙耳机音质的是什么因素?拒绝踩雷,这五款蓝牙耳机赶紧收藏
  15. 人工智能与神经生理学:差异为何重要
  16. PCI DSS安全评估简介
  17. Jenkins生成APP二维码下载链接
  18. 基于Testbench的FPGA实物自动化测试环境设计
  19. 数据结构(C语言)- 稀疏矩阵的快速乘法
  20. 波尔原子模型:一段令人愉悦的历史

热门文章

  1. JS小练习: 通过用户输入的年龄判断是哪个年龄段的人(儿童:<14;少年:14<=年龄<24;青年:24<=年龄<40;中年40<=年龄<60;老年:年龄>=60),并在页面上输出结果.
  2. 从长远来看,这 4 个区块链项目能够为你带来 10 倍的回报
  3. 基于BCH的SLP发币系统专属交易所正式上线
  4. android魅族手机 定位功能吗,魅族MX如何在手机上帮助别人定位手机知道对方的账号...
  5. 怎么翻译图片?可以试试这几招
  6. 纯javascript实现增删改查
  7. win10服务项哪些能禁用?
  8. [php] wordpress视频教程高清免费下载
  9. redis锁原理步骤解析
  10. centos7设置hostname