当前位置: 首页 > news >正文

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=kaIambient+i=1numLightsIi(kd(L^iN^)+ks(R^iV^)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;…...

神经网络基础部件-卷积层详解

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

【计算机网络】HTTPS协议原理

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

21岁,华科博士在读,我的赛事Top经验

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

基于ThinkPHP6.0+Vue+uni-app的多商户商城系统好用吗?

likeshop多商户商城系统适用于B2B2C、多商户、商家入驻、平台商城场景。完美契合平台自营联营加盟等多种经营方式使用&#xff0c;系统拥有丰富的营销玩法&#xff0c;强大的分销能力&#xff0c;支持官方旗舰店&#xff0c;商家入驻&#xff0c;平台抽佣商家独立结算&#xff…...

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、要完成的任务 目标&#xff1a;结合SQL和excel实现餐饮业日销售情况分析仪&#xff0c;如下表&#xff1a; 认识分析仪&#xff1a; 切片器&#xff1a;店面 分为四部分&#xff1a;KPI 、组合图、饼图、数…...

电商导购CPS,京东联盟如何跟单实现用户和订单绑定

前言 大家好&#xff0c;我是小悟 做过自媒体的小伙伴都知道&#xff0c;不管是发图文还是发短视频&#xff0c;直播也好&#xff0c;可以带货。在你的内容里面挂上商品&#xff0c;你自己都不需要囤货&#xff0c;如果用户通过这个商品下单成交了&#xff0c;自媒体平台就会…...

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、心跳机制简介 在分布式系统中&#xff0c;分布在不同主机上的节点需要检测其他节点的状态&#xff0c;如服务器节点需要检测从节点…...

python3.9安装和pandas安装踩坑处理

0、先决条件&#xff1a;系统内最好先安装有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. 转置矩阵

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

【人脸识别】Partial-FC:让你在一台机器上训练1000万个id人脸数据集成为可能!

论文题目&#xff1a;”Killing Two Birds with One Stone: Efficient and Robust Training of Face Recognition CNNs by Partial FC“ -CVPR 2022 代码地址&#xff1a;https://arxiv.org/pdf/2203.15565.pdf 代码地址&#xff1a;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学习记录:分布式锁

一、基本原理和实现方式对比 分布式锁&#xff1a;满足分布式系统或集群模式下多进程可见并且互斥的锁。 分布式锁的核心思想就是让大家都使用同一把锁&#xff0c;只要大家使用的是同一把锁&#xff0c;那么我们就能锁住线程&#xff0c;不让线程进行&#xff0c;让程序串行…...

对React-Fiber的理解,它解决了什么问题?

对React-Fiber的理解&#xff0c;它解决了什么问题&#xff1f;Fiber用来解决什么问题&#xff1f;Fiber是什么&#xff1f;Fiber是如何解决问题的&#xff1f;Fiber用来解决什么问题&#xff1f; JavaScript引擎和页面渲染引擎两个线程是互斥的&#xff0c;当其中一个线程执行…...

【Linux】初学Linux你需要掌握这些基本指令(二)

目录 1.man指令 2.cp指令 3.mv指令 4.tree指令 5.echo指令 6.more指令 7.less指令&#xff08;重要&#xff09; 8.head与tail指令 9.date指令 显示时间常用参数&#xff1a; 设置时间常用参数&#xff1a; 10.cal指令 11.find & whereis & which指令 …...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析

这门怎么题库答案不全啊日 来简单学一下子来 一、选择题&#xff08;可多选&#xff09; 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘&#xff1a;专注于发现数据中…...

如何在看板中有效管理突发紧急任务

在看板中有效管理突发紧急任务需要&#xff1a;设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP&#xff08;Work-in-Progress&#xff09;弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中&#xff0c;设立专门的紧急任务通道尤为重要&#xff0c;这能…...

P3 QT项目----记事本(3.8)

3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...

VTK如何让部分单位不可见

最近遇到一个需求&#xff0c;需要让一个vtkDataSet中的部分单元不可见&#xff0c;查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行&#xff0c;是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示&#xff0c;主要是最后一个参数&#xff0c;透明度…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...