QT+OpenGL光照

news2024/9/29 13:23:29

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)
    • 模拟有光泽物体表面上出现的亮点

I p h o n g = k a ⋅ I a m b i e n t + ∑ i = 1 n u m L i g h t s I i ⋅ ( k d ( L ^ i ⋅ N ^ ) + k s ⋅ ( R ^ i ⋅ V ^ ) n s h i n y ) 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)

其中 k a k d k s k_a k_d k_s kakdks是系数

环境光代码:

#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()
{
    // ambient
    float ambientStrength = 0.1;
    vec3 ambient = ambientStrength * lightColor;

    // diffuse
    vec3 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()
{
    // ambient
    float ambientStrength = 0.1;
    vec3 ambient = ambientStrength * lightColor;

    // diffuse
    vec3 norm = normalize(Normal);
    vec3 lightDir = normalize(lightPos - fragPos);
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = diff * lightColor;

    // specular
    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;

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

在这里插入图片描述

法向量

  • 如果模型矩阵执行了不等比例的缩放,顶点的改变导致法向量不再垂直与表面。

  • 修复这个行为的诀窍是使用一个为法向量专门定制的模型矩阵。这个矩阵称之为法线矩阵

Normal = mat3(transpose(inverse(model))) * aNormal;

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Linux部署项目

一、手动部署 1、终端直接部署(前台运行) (1)在IDEA中开发SpringBoot项目并打成jar包 (2)将jar包上传到Linux服务器 mkdir /usr/local/app #创建目录,将项目jar包放到此目录(3&…

C++——哈希4|布隆过滤器

目录 布隆过滤器 完整代码 布隆过滤器应用 布隆过滤器的查找 布隆过滤器删除 布隆过滤器优点 布隆过滤器缺陷 布隆过滤器海量数据处理 布隆过滤器 位图只能映射整形,而对于字符串却无能为力。 把字符串用哈希算法转成整形,映射一个位置进行标…

Axure教程(一)——线框图与高保真原型图制作

前面我们学习了制作网页的技能,从这里开始我们来学习前端必备技能,就是用Axure来制作原型图,一方面我们能提前绘制出我们所需的页面,这在我们开发的时候能节省大量的时间,另一方面我们能通过给用户进行体验从而能够发现…

robotframework + selenium自动化测试常见的问题

1、 插入中文数据提示 FAIL UnicodeEncodeError: ‘latin-1’ codec can’t encode characters in position 92-107: ordinal not in range(25 DataBaseLibrary插入中文乱码的解决:修改D:\Python27\Lib\site-packages\DatabaseLibrary\connection_manager.py里的co…

极客大挑战 2021

题量很大,收获挺多,持续时间也长,据说结束之后会再持续一段时间,然后题目会开源。 WEB Dark 暗网签到,难以置信 Welcome2021 改个请求方法会提示你文件,再进去就好了 babysql 直接把请求包扔sqlmap里&…

什么是仓库管理?

仓库管理包括仓库日常运营所触及的准绳和流程。从较高的层次上讲,这包括接纳和组织仓库空间、布置劳动力、管理库存和完成订单。放大来看,你会发现有效的仓库管理触及到优化和集成这些过程中的每一个,以确保仓库操作的一切方面协同工作&#…

ElasticSearch之RestClient操作索引库和文档

前言:上文介绍了使用DSL语言操作索引库和文档,本篇文章将介绍使用Java中的RestClient来对索引库和文档进行操作。 希望能够加深自己的印象以及帮助到其他的小伙伴儿们😉😉。 如果文章有什么需要改进的地方还请大佬不吝赐教&#x…

linux系统编程1--文件编程read和write

write函数进行文件写入操作1.write函数原型:ssize_t write(int fd, const void *buf, size_t count);2.参数1:int fd,文件描述符即open函数的返回值;参数2:const void *buf,写入到fd文件内容的写入缓冲区&a…

10万字企业数字化(技术中台、数据中台、工业互联网平台建设方案

【版权声明】本资料来源网络,知识分享,仅供个人学习,请勿商用。【侵删致歉】如有侵权请联系小编,将在收到信息后第一时间删除!完整资料关注公众号“智慧方案文库”,部分资料内容: 目录 1 概述 …

【nodejs-05】黑马nodejs学习笔记05-数据库基本操作02

文章目录4.在项目中操作MySQL4.1 在项目中操作数据库的步骤4.2 安装与配置 mysql 模块4.3 使用 mysql 模块操作 MySQL 数据库5.前后端的身份认证5.1 Web 开发模式5.2 身份认证5.3 Session 认证机制5.4 在 Express 中使用 Session 认证5.5 JWT 认证机制5.6 在 Express 中使用 JW…

用类比方式学习编程中函数递归(个人理解仅供参考)(内含汉诺塔问题的求解)

目录 1.前言 2.递归的数学模型 3.相关的c语法 4.将递归的数学模型写成编程语言 5.利用类比方法将实际问题的代码写成函数递归的形式 例1: 例2: 6.汉诺塔问题的求解 1.前言 本人在学习函数递归编程方法的过程中,发现用类比的方式学习递归法可帮助我们在各种编…

day14_类中成员之一:构造器

由来 我们发现我们new完对象时,所有成员变量都是默认值,如果我们需要赋别的值,需要挨个为它们再赋值,太麻烦了。我们能不能在new对象时,直接为当前对象的某个或所有成员变量直接赋值呢。可以,Java给我们提…

【算法】二分

作者:指针不指南吗 专栏:算法篇 🐾或许会很慢,但是不可以停下来🐾 文章目录1.二分思想2.二分模板3.二分应用1.二分思想 思想 单调的元素,一定可以二分;非单调不一定不能二分 每次把整个区间 [ …

【企业云端全栈开发实践-1】项目介绍及环境准备、Spring Boot快速上手

本节目录一、 项目内容介绍二、Maven介绍2.1 Maven作用2.2 Maven依赖2.3 本地仓库配置三、Spring Boot快速上手3.1 Spring Boot特点3.2 遇到的Bug:spring-boot-maven-plugin3.3 遇到的Bug2:找不到Getmapping四、开发环境热部署一、 项目内容介绍 本课程…

肿瘤HRR和HRD 简单记录

最近看到两个在肿瘤领域高频出现的词HRR和HRD, 遂简单记录下。 HRR和HRD的概念 当细胞受到外界不良环境的压力下往往会导致DNA的损伤,此时便会触发DNA 损伤反应 (DDR),从而激活许多DNA修复通路。在这些DNA损伤中,DNA 双链断裂&a…

【云原生】centos7搭建安装k8s集群 v1.25版本详细教程实战

文章目录前言一. 实验环境二. k8s 的介绍三 . k8s的安装3.1 搭建实验环境3.1.1 硬件层面的要求3.1.2 软件层面环境配置3.2 docker的安装3.2.1 搭建docker3.2.2 部署 cri-dockerd3.3 部署k8s3.3.1 配置添加阿里云的yum源3.3.2 安装kubeadm kubelet kubectl3.3.3 k8s-master节点初…

浪涌保护器,防雷浪涌保护器的作用和类型指南

1. 什么是SPD浪涌保护器?地凯防雷SPD浪涌保护器是防止雷击导致故障的避雷器和浪涌保护设备。广泛用于电源浪涌对策的变阻器在通电超过规格的雷电浪涌电流、超过最大容许电路电压的过电压、过电流时,会进入短路故障模式,存在冒烟起…

Mysql元数据获取方法(information_schema绕过方法)

前提:如果waf或其它过滤了information_schema关键字,那我们该如何获取元数据呢?能够代替information_schema的有:sys.schema_auto_increment_columnssys.schema_table_statistics_with_bufferx$schema_table_statistics_with_buff…

大数据框架之Hadoop:HDFS(七)HDFS 2.X新特性

7.1集群间数据拷贝 scp实现两个远程主机之间的文件复制 ​ scp -r hello.txt roothadoop103:/root/hello.txt // 推 push ​ scp -r roothadoop103:/root/hello.txt hello.txt // 拉 pull ​ scp -r roothadoop103:/root/hello.txt roothadoop104:/root //是通过本地主机中…

计算机技术与软件(初级、中级、高级)考试(软考)是什么?软考的时间安排是什么时候?

一、软考是什么? 计算机技术与软件专业技术资格(水平)考试(以下简称计算机软件资格考试)是原中国计算机软件专业技术资格和水平考试(简称软件考试)的完善与发展。计算机软件资格考试是由国家人力…