LearnOpenGL(八)之光照

一、冯氏光照模型

冯氏光照模型(Phong Lighting Model)主要由环境(Ambient)、漫反射(Diffuse)和镜面(Specular)光照这三部分组成,各效果如下:

1、环境光照

即使在黑暗的情况下,世界上通常也仍然有一些光亮(月亮、远处的光),所以物体几乎永远不会是完全黑暗的。我们可以使用一个环境光照(Ambient Lighting)常量来模拟这个。

如何把环境光照添加到场景呢?我们可以用光的颜色乘以一个很小的常量环境因子,再乘以物体的颜色,然后将最终结果作为片段的颜色:

void main()
{
    float ambientStrength = 0.1;
    vec3 ambient = ambientStrength * lightColor;

    vec3 result = ambient * objectColor;
    FragColor = vec4(result, 1.0);
}

2、漫反射光照

模拟光源对物体的方向性影响(Directional Impact)。物体的某一部分越是正对着光源,它就会越亮。

从上图我们可以看出,光线越垂直于物体表面,这束光对物体的影响会越大,即物体越亮。为了测量光线和片段的角度,我们可以使用一个叫做法向量(Normal Vector)的东西,它是垂直于片段表面的一个向量(图中以黄色箭头表示)。

计算漫反射光照需要法向量定向的光线!!

2.1 法向量

法向量是一个垂直于顶点表面的(单位)向量。我们可以使用叉乘对立方体所有的顶点计算法向量,但是由于3D立方体不是一个复杂的形状,所以我们可以简单地把法线数据手工添加到顶点数据中,然后更新顶点着色器:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;

out vec3 Normal;
...

void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0);
    Normal = aNormal;
}

在片段着色器添加:

in vec3 Normal;

2.2 定向的光线

定向的光线,作为光源的位置与片段的位置之间向量差的方向向量。我们可以通过光的位置向量片段的位置向量计算该光线。

由于光源的位置是一个静态变量,我们在片段着色器中把它声明为uniform:

uniform vec3 lightPos;

然后在渲染循环中将lightPos向量传进去:

lightingShader.setVec3("lightPos", lightPos);

对于片段的位置,我们可以通过把顶点位置属性乘以模型矩阵(不是观察和投影矩阵)来获取。这个在顶点着色器中很容易完成:

out vec3 FragPos;  
out vec3 Normal;

void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0);
    FragPos = vec3(model * vec4(aPos, 1.0));
    Normal = aNormal;
}

然后,在片段着色器中添加相应的输入变量:

in vec3 FragPos;

至此,我们便可以计算定向的光线了——光源位置向量与片段位置向量之间的向量差。

vec3 norm = normalize(Normal);
vec3 lightDir = normalize(lightPos - FragPos);

接着,可以计算漫反射分量了。对norm和lightDir向量进行点乘,计算光源对当前片段实际的漫反射影响。结果值再乘以光的颜色,得到漫反射分量。两个向量之间的角度越大,漫反射分量就会越小:

float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = diff * lightColor;

将环境光分量和漫反射分量相加,然后把结果乘以物体的颜色,可以获得片段最后的输出颜色:

vec3 result = (ambient + diffuse) * objectColor;
FragColor = vec4(result, 1.0);

3、镜面光照

模拟有光泽物体上面出现的亮点。镜面光照的颜色相比于物体的颜色会更倾向于光的颜色。

和漫反射光照一样,镜面光照也决定于光的方向向量物体的法向量,但是它也决定于人(摄像机)的观察方向。可以把物体表面设想为一面镜子,那么镜面光照最强的地方就是我们看到表面上反射光的地方,如下图:

我们通过根据法向量翻折入射光的方向来计算反射向量。然后我们计算反射向量与观察方向的角度差,它们之间夹角越小,镜面光的作用就越大,我们看到的效果就越亮。

观察向量是我们计算镜面光照时需要的一个额外变量,我们可以使用观察者(摄像机)的世界空间位置和片段的位置来计算它。之后我们计算出镜面光照强度,用它乘以光源的颜色,并将它与环境光照和漫反射光照部分加和。

观察者(摄像机)的世界空间位置:

lightingShader.setVec3("viewPos", camera.Position);

高光强度:

float specularStrength = 0.5;//镜面强度

视线方向向量,以及对应的沿着法线轴的反射向量:

vec3 viewDir = normalize(viewPos - FragPos);
vec3 reflectDir = reflect(-lightDir, norm);

镜面分量:

float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
vec3 specular = specularStrength * spec * lightColor;

先计算视线方向与反射方向的点乘(并确保它不是负值),然后取它的32次幂。这个32是高光的反光度(Shininess)。一个物体的反光度越高,反射光的能力越强,散射得越少,高光点就会越小。不同反光度的视觉效果影响如下:

最后,把它加到环境光分量和漫反射分量里,再用结果乘以物体的颜色:

vec3 result = (ambient + diffuse + specular) * objectColor;
FragColor = vec4(result, 1.0);

demo下载:点击跳转

效果如下:

觉得有帮助的话,打赏一下呗。。

           

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/602640.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

只允许内网访问时,如何设置hosts

1、Hosts文件简介 hosts文件是一个没有扩展名的计算机文件,用于将主机名与对应的 IP 地址关联起来。在操作系统中,hosts文件通常用于在本地解析域名,以便将域名映射到特定的IP地址。这个文件可以用来屏蔽广告、加速访问特定网站、解决DNS解析…

微服务项目实战-黑马头条(十三):持续集成

文章目录 项目部署_持续集成1 今日内容介绍1.1 什么是持续集成1.2 持续集成的好处1.3 今日内容 2 软件开发模式2.1 软件开发生命周期2.2 软件开发瀑布模型2.3 软件的敏捷开发 3 Jenkins安装配置3.1 Jenkins介绍3.2 Jenkins环境搭建3.2.1 Jenkins安装配置3.2.2 Jenkins插件安装3…

第十四届蓝桥杯大赛软件赛省赛(Python大学A组)

2023年蓝桥杯 省赛真题Python大学A组 试题A:特殊日期 试题B:分糖果 试题C:三国游戏 试题D:平均 试题E:翻转 试题F:子矩阵 试题G:阶乘的和 …

张大哥笔记:先挣小钱,再赚大钱

先挣小钱,再赚大钱!挣小钱,无需向上社交! 现在很流行向上社交,反正只要前面加上一个向上,就感觉很牛逼的样子,有必要吗?我认为是没有必要的。 人活着不是为了社交,而是找…

大模型日报|今日必读的 4 篇大模型论文

大家好,今日必读的大模型论文来啦! 1.清华、智谱AI 团队推出无限超分辨率模型 Inf-DiT 近年来,扩散模型在图像生成方面表现出了卓越的性能。然而,由于在生成超高分辨率图像(如 40964096)的过程中内存会二…

银河麒麟QT项目打包详细教程

银河麒麟QT项目打包详细教程 一、QT项目打包 下载linuxdeployqt,下载地址:https://github.com/probonopd/linuxdeployqt/releases 安装Linuxdeployqt 2.1 为了安装方便,将下载下来的文件名称改短些 mv linuxdeployqt-6-x86_64.AppImage lin…

数据分析从入门到精通 1.numpy剑客修炼

会在某一瞬间突然明白,有些牢笼是自己给自己的 —— 24.5.5 一、数据分析秘笈介绍 1.什么是数据分析 是把隐藏在一些看似杂乱无章的数据背后的信息提炼出来,总结出所研究对象的内在规律。使得数据的价值最大化 案例: 分析用户的消…

webpack5基础和配置

初步体验webpack打包 webpack是一个静态资源打包工具。 它会以一个或多个文件作为打包的入口,将我们整个项目所有文件编译组合成一个或多个文件输出出去。 输出的文件就是编译好的文件,就可以在浏览器段运行了。 1.初始化最简单的一个目录文件&#xff…

以steamDB的好评排名为引 - 详解wilson评分算法

写在前面 中文互联网上缺少关于二项分布估计的知识,而对二项分布参数如何准确且合理的估计的技巧,实际上在商业数据分析领域用处极多。尤其是在互联网企业,算法排名的依据很大程度要依赖这个统计量。我试图抛砖引玉,以steamDB的评…

语言模型测试系列【7】

语言模型 文心一言星火认知大模型通义千问豆包360智脑百川大模型腾讯混元助手Kimi Chat商量C知道 今天看CSDN文章,看到了斐波那契数列这个有趣的数列计算,然后就在文心一言中对答了一波,给的答案很完整,而且给出来python的实现代…

WDW-10B微机控制电子万能试验机技术方案

一.设备外观照片: 项目简介: 微机控制电子式万能试验机是专门针对高等院校、各种金属、非金属科研厂家及国家级质检单位而设计的高端微机控制电子式万能试验机、计算机系统通过全数字控制器,经调速系统控制伺服电机转动&#xff…

证照之星是什么软件 证照之星哪个版本好用?证照之星支持哪些相机 证照之星XE免费版

许多人都需要使用证件照,为了满足这一需求,人们会使用照相机、手机、电脑等工具进行拍摄。除此之外,市面上还存在专门的证件照拍摄软件,比如证照之星。那么,各位小伙伴是否了解证照之星哪个版本好用,证照之…

嵌入式RTOS面试题目

用过哪些嵌入式操作系统?使⽤RTOS和裸机代码开发有什么区别(优缺点)? 之前的⼀个项⽬是采⽤裸机代码开发的,写起来还⾏,通过状态机来管理业务逻辑和各种外设。 但是随着外设的增加,任务之间的…

【WEB前端2024】简单几步制作web3d《萌宠星球》智体节点模板(2)

【WEB前端2024】简单几步制作web3d《萌宠星球》智体节点模板(2) 使用dtns.network德塔世界(开源的智体世界引擎),策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体…

【优选算法】——Leetcode——611. 有效三角形的个数

目录 ​编辑 1.题目 2 .补充知识 3.解法⼀(暴⼒求解)(可能会超时): 算法思路: 算法代码: 4.解法⼆(排序双指针): 算法思路: 以输入: nums …

2024年5月12日(星期天)骑行海囗

2024年5月12日 (星期天)骑行海口,早8:30到9:00大观公园门口集合,9:30准时出发【因迟到者,骑行速度快者,可自行追赶偶遇。】 偶遇地点:大观公园门口集合 ,家住东,西,南,北…

wangEditor富文本编辑器与layui图片上传

记录&#xff1a;js 显示默认的wangEditor富文本编辑器内容和图片 <style>body {background-color: #ffffff;}.layui-form-select dl{z-index:100000;} </style> <div class"layui-form layuimini-form"><div class"layui-form-item"…

MT3034 算术招亲

跟MT3033新的表达式类似&#xff0c;只多了一个括号合法性的判断 #include <bits/stdc.h> using namespace std; const int N 40; bool tag[N]; bool is_op(char c) {return c || c - || c * || c / || c ^; } int priority(char op) { // 优先级排序if (op ||…

数据结构-线性表-应用题-2.2-9

线性表&#xff08;a1,a2,a3,...,an&#xff09;中的元素递增有序且按顺序存储于计算机内。要求设计一个算法&#xff0c;用最少的时间在表中查找数值为x的元素&#xff0c;若找到&#xff0c;则将其与后继元素位置相交换&#xff0c;若找不到&#xff0c;则将其插入表中并使表…

钉钉开放平台创建企业内部H5微应用或者小程序

前言&#xff1a; 在当今企业数字化转型的浪潮中&#xff0c;创建企业内部H5微应用或小程序已成为提升工作效率和促进内部沟通的重要举措。发话不多说本文将介绍如何利用钉钉平台快速创建这些应用&#xff0c;让企业内部的工作更加便捷高效。 步骤 1.在浏览器打开链接…