QT+OpenGL光照
QT+OpenGL光照
本篇完整工程见gitee:QtOpenGL 对应点的tag,由turbolove提供技术支持,您可以关注博主或者私信博主
颜色
现实生活中看到的物体的颜色并不是这个物体真正拥有的颜色,而是它所反射的颜色
太阳光能被看见的白光是多找演的的组合
颜色的数据化的由红色,绿色和蓝色三个分量组成,他们通常被缩写为RGB
例如:珊瑚红色
QVector3D color(1.0f, 0.5f, 0.31f);
上图颜色的代码展示
// 灯光颜色
QVector3D lightColor(1.0f, 1.0f, 1.0f);
// 珊瑚红色
QVector3D toyColor(1.0f, 0.5f, 0.31f);
QVector3D result = lightColor * toyColor; // 分量相乘,不是点乘也不是叉乘
代码展示:
light.frag
#version 330 core
out vec4 FragColor;
uniform vec3 lightColor;
void main()
{FragColor = vec4(lightColor, 1.0);
}
light.vert
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aTexCord;uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;void main()
{gl_Position = projection * view * model * vec4(aPos, 1.0);
}
void TurboOpenGLWidget::paintGL()
{QMatrix4x4 model;QMatrix4x4 view;float time = m_time.elapsed() / 50.0;model.rotate(time, 1.0f, 5.0f, 0.0f);glClearColor(0.2f, 0.3f, 0.3f, 1.0f);glEnable(GL_DEPTH_TEST);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);shader_program_.bind();glBindVertexArray(VAO);QMatrix4x4 projection;projection.perspective(camera_.getZoom(), float(width() / height()), 0.1, 100);shader_program_.setUniformValue("projection", projection);view = camera_.getViewMatrix();switch(shape_){case Rect:shader_program_.setUniformValue("model", model);shader_program_.setUniformValue("view", view);for(const auto &item: cubePositions){model.setToIdentity();model.translate(item);model.rotate(time, 1.0, 5.0, 0.5);shader_program_.setUniformValue("model", model);glDrawArrays(GL_TRIANGLES,0,36);}break;}glBindVertexArray(0);glBindVertexArray(lightVAO);light_shader_program_.bind();light_shader_program_.setUniformValue("projection", projection);light_shader_program_.setUniformValue("model", model);light_shader_program_.setUniformValue("view", view);model.setToIdentity();model.translate(lightPos);model.rotate(1.0, 1.0, 5.0, 0.5);model.scale(0.2);light_shader_program_.setUniformValue("model", model);glDrawArrays(GL_TRIANGLES,0,36);update();
}
效果展示
冯氏光照模型
冯氏光照模型的主要结构有三个:
- 环境光(ambient)
- 即使在黑暗情况下,通常也仍然有一些光亮
- 漫反射(diffuse)
- 模拟光源对物体的方向性影响
- 镜面反射(specular)
- 模拟有光泽物体表面上出现的亮点
Iphong=ka⋅Iambient+∑i=1numLightsIi⋅(kd(L^i⋅N^)+ks⋅(R^i⋅V^)nshiny)I_{phong} = k_a\cdot I_{ambient} + \sum_{i = 1}^{numLights}I_i\cdot (k_d(\hat L_i\cdot \hat N) + k_s\cdot (\hat R_i \cdot \hat V)^{n^{shiny}}) Iphong=ka⋅Iambient+i=1∑numLightsIi⋅(kd(L^i⋅N^)+ks⋅(R^i⋅V^)nshiny)
其中kakdksk_a k_d k_skakdks是系数
环境光代码:
#version 330 core
out vec4 FragColor;
uniform vec3 objectColor;
uniform vec3 lightColor;
void main()
{float ambientStrength = 0.2;vec3 ambient = ambientStrength * lightColor;vec3 result = ambient * objectColor;FragColor = vec4(result, 1.0);
}
向上面代码,如果我们只有环境光,会是如下效果,并不是完全黑的。
漫反射代码:
计算漫反射光照需要:
- 法向量:一个垂直于顶点表面的向量
- 定向的光线:作为光源的位置与片段的位置之间的向量差的方向向量;为了计算这个光线,我们需要光的位置向量和片段的位置向量
片段着色器:
#version 330 core
out vec4 FragColor;uniform vec3 objectColor;
uniform vec3 lightColor;
uniform vec3 lightPos;in vec3 Normal;
in vec3 fragPos;void main()
{// ambientfloat ambientStrength = 0.1;vec3 ambient = ambientStrength * lightColor;// diffusevec3 norm = normalize(Normal);vec3 lightDir = normalize(lightPos - fragPos);float diff = max(dot(norm, lightDir), 0.0);vec3 diffuse = diff + lightColor;vec3 result = (ambient + diffuse) * objectColor;FragColor = vec4(result, 1.0);
}
镜面反射代码:
片段着色器:
#version 330 core
out vec4 FragColor;uniform vec3 objectColor;
uniform vec3 lightColor;
uniform vec3 lightPos;
uniform vec3 viewPos;in vec3 Normal;
in vec3 fragPos;void main()
{// ambientfloat ambientStrength = 0.1;vec3 ambient = ambientStrength * lightColor;// diffusevec3 norm = normalize(Normal);vec3 lightDir = normalize(lightPos - fragPos);float diff = max(dot(norm, lightDir), 0.0);vec3 diffuse = diff * lightColor;// specularfloat 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;vec3 result = (ambient + diffuse + specular) * objectColor;FragColor = vec4(result, 1.0);
}
法向量
-
如果模型矩阵执行了不等比例的缩放,顶点的改变导致法向量不再垂直与表面。
-
修复这个行为的诀窍是使用一个为法向量专门定制的模型矩阵。这个矩阵称之为法线矩阵
Normal = mat3(transpose(inverse(model))) * aNormal;
相关文章:

QT+OpenGL光照
QTOpenGL光照 本篇完整工程见gitee:QtOpenGL 对应点的tag,由turbolove提供技术支持,您可以关注博主或者私信博主 颜色 现实生活中看到的物体的颜色并不是这个物体真正拥有的颜色,而是它所反射的颜色 太阳光能被看见的白光是多找演的的组合…...

OpenCV-PyQT项目实战(7)项目案例03:鼠标框选
欢迎关注『OpenCV-PyQT项目实战 Youcans』系列,持续更新中 OpenCV-PyQT项目实战(1)安装与环境配置 OpenCV-PyQT项目实战(2)QtDesigner 和 PyUIC 快速入门 OpenCV-PyQT项目实战(3)信号与槽机制 …...
vue2版本《后台管理模式》(上)
后台管理模式项目开发经验总结如下,希望对你们有些帮助: 文章目录一、app 出口位置二 、 index.js 路由配置三、package.json 文件四、 main.js 既然安装插件那就需要引入五、 跨域问题总结首先需要一个完整的v2版本的项目 vue2版本思路:首先…...
C++与C基础重叠部分
Cmake CPP程序开发过程 计算机硬件—>机器语言—>汇编—>cppcpp—>机器(gcc)Make(makefile)—>本地智能批处理翻译机制Cmake—>跨平台生成不同设备上的makefile进行执行 Cpp基础学习 基本知识 基本格式 #include<iostream> using namespace std;…...

神经网络基础部件-卷积层详解
前言 在全连接层构成的多层感知机网络中,我们要通过将图像数据展平成一维向量来送入模型,但这会忽略了每个图像的空间结构信息。理想的策略应该是要利用相近像素之间的相互关联性,将图像数据二维矩阵送给模型中学习。 卷积神经网络(convolu…...

【计算机网络】HTTPS协议原理
文章目录一、认识HTTPS协议二、为什么要发明HTTPS三、HTTP与HTTPS的区别四、常见的加密方式1. 对称加密2. 非对称加密3. 数据摘要4. 数字签名五、HTTPS的原理探究方案1:只使用对称加密方案2:只使用非对称加密方案3:双方都使用非对称加密方案4…...

21岁,华科博士在读,我的赛事Top经验
Datawhale干货 作者:vaew,华中科技大学,博士二年级在读简介笔者vaew,21岁,现为华中科技大学机械科学与工程学院陶波教授课题组博士二年级学生。主要研究方向是基于视触融合的机器人灵巧操作。学业之余的研究兴趣包括图…...

基于ThinkPHP6.0+Vue+uni-app的多商户商城系统好用吗?
likeshop多商户商城系统适用于B2B2C、多商户、商家入驻、平台商城场景。完美契合平台自营联营加盟等多种经营方式使用,系统拥有丰富的营销玩法,强大的分销能力,支持官方旗舰店,商家入驻,平台抽佣商家独立结算ÿ…...
Linux中断
文章目录 前言一、Linux 中断介绍二、中断上文和中断下文三、中断相关函数1 获取中断号相关函数2.申请中断3.释放中断4.中断处理函数四.中断下文之 tasklet1.概念2.Linux 内核中的 tasklet 结构体:3.使用步骤4.相关函数a.初始化 tasklet结构体b.调度 taskletc.杀死 tasklet总结…...

Excel+SQL实战项目 - 餐饮业日销售情况分析仪
目录1、要完成的任务2、认识数据3、SQL数据加工4、excel形成分析仪1、要完成的任务 目标:结合SQL和excel实现餐饮业日销售情况分析仪,如下表: 认识分析仪: 切片器:店面 分为四部分:KPI 、组合图、饼图、数…...

电商导购CPS,京东联盟如何跟单实现用户和订单绑定
前言 大家好,我是小悟 做过自媒体的小伙伴都知道,不管是发图文还是发短视频,直播也好,可以带货。在你的内容里面挂上商品,你自己都不需要囤货,如果用户通过这个商品下单成交了,自媒体平台就会…...

Redis学习【6】之BitMap、HyperLogLog、Geospatial操作命令 (1)
文章目录前言BitMap 操作命令1.1 BitMap 简介1.2 setbit1.3 getbit1.4 bitcount1.5 bitpos[pos:position]1.6 bitop1.7 应用场景二 HyperLogLog 操作命令2.1 HyperLogLog 简介2.2 pfadd2.3 pfcount2.4 pfmerge2.5 应用场景三 Geospatial【地理空间】操作命令3. 1 Geospatial 简…...

JAVA实现心跳检测【长连接】
文章目录1、心跳机制简介2、心跳机制实现方式3、客户端4 、服务端5、代码实现5.1 KeepAlive.java5.2 MyClient.java5.3 MyServer5.4 测试结果1、心跳机制简介 在分布式系统中,分布在不同主机上的节点需要检测其他节点的状态,如服务器节点需要检测从节点…...
python3.9安装和pandas安装踩坑处理
0、先决条件:系统内最好先安装有gcc、libffi-devel等 1、安装包下载 https://www.python.org/downloads/source/ 2、解压安装包并上传到/usr/local/python3.9 3、打开shell cd /usr/local/python3.9要先把python3.9的所有文件复制到/usr/local/python3.9才会成功…...

2023.2.15每日一题——867. 转置矩阵
每日一题题目描述解题核心解法一:二维表示 模拟解法二:一维表示 模拟题目描述 题目链接:867. 转置矩阵 给你一个二维整数数组 matrix, 返回 matrix 的 转置矩阵 。 矩阵的 转置 是指将矩阵的主对角线翻转,交换矩阵…...

【人脸识别】Partial-FC:让你在一台机器上训练1000万个id人脸数据集成为可能!
论文题目:”Killing Two Birds with One Stone: Efficient and Robust Training of Face Recognition CNNs by Partial FC“ -CVPR 2022 代码地址:https://arxiv.org/pdf/2203.15565.pdf 代码地址:https://github.com/deepinsight/insightfac…...
递归方法读取任意深度的 JSON 对象的键值
有以下json字符串 {"name":"John","age":30,"address":{"city":"New York","state":"NY","zip":"10001","coordinates":{"latitude":40.712776,&q…...

黑马redis学习记录:分布式锁
一、基本原理和实现方式对比 分布式锁:满足分布式系统或集群模式下多进程可见并且互斥的锁。 分布式锁的核心思想就是让大家都使用同一把锁,只要大家使用的是同一把锁,那么我们就能锁住线程,不让线程进行,让程序串行…...
对React-Fiber的理解,它解决了什么问题?
对React-Fiber的理解,它解决了什么问题?Fiber用来解决什么问题?Fiber是什么?Fiber是如何解决问题的?Fiber用来解决什么问题? JavaScript引擎和页面渲染引擎两个线程是互斥的,当其中一个线程执行…...

【Linux】初学Linux你需要掌握这些基本指令(二)
目录 1.man指令 2.cp指令 3.mv指令 4.tree指令 5.echo指令 6.more指令 7.less指令(重要) 8.head与tail指令 9.date指令 显示时间常用参数: 设置时间常用参数: 10.cal指令 11.find & whereis & which指令 …...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)
题目:3442. 奇偶频次间的最大差值 I 思路 :哈希,时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况,哈希表这里用数组即可实现。 C版本: class Solution { public:int maxDifference(string s) {int a[26]…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢
随着互联网技术的飞速发展,消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁,不仅优化了客户体验,还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用,并…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

Cinnamon修改面板小工具图标
Cinnamon开始菜单-CSDN博客 设置模块都是做好的,比GNOME简单得多! 在 applet.js 里增加 const Settings imports.ui.settings;this.settings new Settings.AppletSettings(this, HTYMenusonichy, instance_id); this.settings.bind(menu-icon, menu…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...

《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...

【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...