Qt::QOpenGLWidget 渲染天空壳

news2025/4/14 15:01:37

在qt窗口中嵌入opengl渲染天空壳和各种立方体

一 学前知识

天空壳的渲染学前小知识

1 立方体贴图 天空壳的渲染就是利用立方体贴图来实现渲染流程

2 基础光照 光照模型

3 opengl帧缓冲 如何自定义帧缓冲实现后期特效

4 glsl常见的shader内置函数 glsl编程常用的内置函数

二 shader代码

1 顶点着色器

#version 410 core
//顶点着色器
uniform mat4 lightview;
uniform mat4 projection_mat;
uniform mat4 view_mat;
uniform mat4 model_mat;
uniform mat3 normal_mat;
uniform vec4 light_position;
uniform vec4 light_ambient;
uniform vec4 light_diffuse;
uniform vec4 light_specular;
uniform vec4 material_specular;
uniform float material_shininess;
uniform int  render_type;

layout(location = 0) in vec3 a_position;
layout(location = 1) in vec3 a_texcoord;
layout(location = 2) in vec3 a_normal;

layout(location = 0) out vec3 position;
layout(location = 1) out vec3 normal;
layout(location = 2) out vec3 texcoord;
layout(location = 3) out vec4 lightDirection;
layout(location = 4) out vec4 color;

void main()
{
    //给像素着色器传递参数
    {
        //光照方向
        lightDirection = lightview * light_position;
        //法线向量
        normal = normal_mat * a_normal;
        //纹理坐标
        texcoord = a_texcoord;
        //颜色
        color = vec4(1.0f, 1.0f, 1.0f, 0.0f);
        //观察空间坐标(从右向左做运算) = 观察矩阵 * 变换矩阵 * 局部空间坐标
        position = (view_mat * model_mat * vec4(a_position, 1)).xyz;
    }
    //如果是渲染立方体
    if (render_type == 0)
    {
        //最终屏幕坐标 = 透视矩阵 * 观察矩阵 * 变换矩阵 * 局部空间坐标(从右向左做运算)
        gl_Position = projection_mat *  view_mat * model_mat * vec4(a_position, 1);
    }
    else  //如果是渲染天空壳
    {
        /*
           天空盒很可能会渲染在所有其他对象之上,因为它只是一个1x1x1的立方体(意味着距离
        摄像机的距离也只有1),我们需要欺骗深度缓冲,让它认为天空盒有着最大的深度值1.0,只
        要它前面有一个物体,深度测试就会失败。
           在坐标系统小节中我们说过,透视除法是在顶点着色器运行之后执行的,将gl_Position的xyz
        坐标除以w分量。我们又从深度测试小节中知道,相除结果的z分量等于顶点的深度值。使用这些信
        息,我们可以将输出位置的z分量等于它的w分量,让z分量永远等于1.0,这样子的话,当透视
        除法执行之后,z分量会变为w / w = 1.0。
        */
        vec4 pos = projection_mat *  view_mat * model_mat * vec4(a_position, 1);
        gl_Position = pos.xyww;
    }
}

2 天空壳像素着色器

#version 410 core
//像素着色器
#extension GL_NV_shadow_samplers_cube : enable
out vec4 FragColor;

layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec3 texcoord;
layout(location = 3) in vec4 lightDirection;

uniform samplerCube env;
uniform vec4 light_position;
uniform vec4 light_ambient;
uniform vec4 light_diffuse;
uniform vec4 light_specular;
uniform vec4 material_specular;
uniform float material_shininess;

void main() 
{ 
    //输出颜色 = 直接取天空壳纹理色
    FragColor = textureCube(env,texcoord.xyz);
}

3 中心立方体像素着色器

#version 410 core
//像素着色器
#extension GL_NV_shadow_samplers_cube : enable
out vec4 FragColor;

layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec3 texcoord;
layout(location = 3) in vec4 lightDirection;
layout(location = 4) in vec4 color;

uniform sampler2D tex;
uniform vec4 basicColor;
uniform vec4 light_position;
uniform vec4 light_ambient;
uniform vec4 light_diffuse;
uniform vec4 light_specular;
uniform vec4 material_specular;
uniform float material_shininess;

void main()
{
    //归一化法线向量
    vec3 N = normalize(normal);

    //光照和法向量的夹角的cos值
    float NdotL = dot(N, lightDirection.xyz);
    //反射光照和法向量的夹角的cos值
    float RdotL = dot(reflect(normalize(position), N), lightDirection.xyz);

    //向量的绝对值
    vec3 absN = abs(texcoord.xyz);
    //把立方体坐标系移到坐标轴的原点
    vec3 zerttexcoord = texcoord + 0.5;
    vec2 texCoord;
    //左右两个面(纹理取向量yz)
    if (absN.x > absN.y && absN.x > absN.z)
        texCoord = vec2(zerttexcoord.yz);
    //上下两个面
    else if (absN.y > absN.z)
        texCoord = vec2(zerttexcoord.zx);
    //前后两个面
    else
        texCoord = vec2(zerttexcoord.xy);

    //获取对应坐标纹理的颜色值
    vec4 texColor = texture(tex, texCoord.xy);
    //混合基础颜色和纹理色
    vec4 unlitColor = color * mix(basicColor, vec4(texColor.xyz, 1.0), texColor.w);
    //输出最终颜色 =(环境光照 + 漫反射光照 * 光照夹角cos值) * 初始颜色 + 材质的颜色
    FragColor = (light_ambient + light_diffuse * max(NdotL, 0.0)) * unlitColor +
                    material_specular * light_specular * pow(max(RdotL, 0.0), material_shininess);
}

4 更完整的项目地址:

gitee地址

github 地址

三 运行效果展示

四 参考文章

1 噪声算法

2 不只是噪音

3 Normal Matrix(法向量变换矩阵)

4 深度好文:关于图形渲染以及离屏渲染

5 OpenGL-离屏渲染

6 OpenGL Frame Buffer Object (FBO)

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

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

相关文章

部署运行ai智障写作记录【ChatRWKV】

文章目录前言一、环境安装1.python环境:Python 3.10。2.安装一些 pip 库numpy 、tokenizers 、prompt_toolkit3.安装pytorch 1.13.1CUDA 11.7二、运行记录1、下载代码2、下载训练参数3、编辑代码运行总结前言 看到知乎一篇教程, 大佬自己弄得ai小说续写…

AI环境搭建步骤(Windows环境)

1. 安装好Anaconda3版本(1) 安装链接:https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/?CM&OD本文使用Anaconda3下载链接:Anaconda5(2) 注意安装anaconda时一定要把环境变量加入windows环境中。要没有勾选,安装完后还有手动加入…

线性代数学习-2

线性代数学习-2矩阵消元消元回代消元矩阵置换矩阵逆矩阵本文转载于https://herosunly.blog.csdn.net/article/details/88713747 该文章本人认为十分有用,便自己敲一遍笔记加固印象原文链接 原文这个笔记感觉比我老师讲的更加透彻,清晰。很好的展示了线性…

车辆热管理测试方案

车辆热管理是在能源危机出现、汽车排放法规日益严格以及人们对汽车舒适性要求更高的背景下应运而生的。将各个系统或部件如冷却系统、润滑系统和空调系统等集成一个有效的热管理系统;控制和优化车辆的热量传递过程,保证各关键部件和系统安全高效运行&…

《C++ Primer Plus》(第6版)第5章编程练习

《C Primer Plus》(第6版)第5章编程练习《C Primer Plus》(第6版)第5章编程练习1. 计算闭区间内的整数和2. 重新编写程序清单5.43. 累加4. 投资价值5. 销售情况6. 销售情况27. 汽车8. 统计单词数量9. 统计单词数量210. 嵌套循环《…

(五十)大白话深入研究索引之前,先来看看磁盘数据页的存储结构

前面我们已经给大家把MySQL数据库的部分内核原理,更新语句的执行原理,事务原理以及锁原理,都初步的讲给大家听了,同时还穿插了一些相关的数据库性能优化的案例,相信现在大家已经对数据库执行增删改语句的原理有了较为深…

小程序容器与微服务架构:提高应用程序开发效率和部署速度的利器

随着移动互联网的发展,小程序已经成为了一种非常流行的应用方式,它可以在不安装任何应用的情况下,直接在移动终端设备(如:App,iPad等)中运行。微服务架构则是一种的分布式系统架构,可…

三维数据可视化软件,可视化地图是用什么做的?

可视化地图是用什么做的?数据可视化地图是一种利用空间数据来表现地理信息的方式,能够为人们提供关于地理信息的准确、直观的可视化图形,以便更好地理解相关信息。数据地图可以最直观的表达出数据之间的空间关系,因此在很多数据分…

【组织架构】中国铁路兰州局集团有限公司

1 公司简介 中国铁路兰州局集团有限公司,是中国国家铁路集团有限公司管理的18个铁路局集团有限公司之一,简称“兰局”。经过59年的发展,现已成为西北地区最大的交通运输企业之一,形成了以兰州为枢纽,由陇海铁路、包兰铁…

前端Cookie基础知识

一、简介 ​ Cookie(也称为HTTP Cookie、Web Cookie、浏览器 Cookie等等)是服务器发送到用户浏览器并保存在本地的一小块数据,该数据通常是用户账号相关的信息,不同浏览器对Cookie的数量和大小限制不同,但一般来说&am…

centos8安装

本文由个人总结,如需转载使用请标明原著及原文地址 1.下载镜像 1.1阿里镜像 可以在阿里云的镜像库里下载,阿里centos8只保留了8.5.2111如果需要别的版本看1.2 http://mirrors.aliyun.com/centos/8/isos/x86_64 1.2其他版本的镜像 下好镜像的可以跳过…

2023年1月京东“白酒”品类销售数据出炉,五粮液表现较好

鲸参谋电商数据监测的2023年1月份京东“白酒”品类销售数据出炉! 根据鲸参谋电商数据显示,2023年1月,京东平台上白酒的销量共计980万,环比增长约180%,同比去年增长约13%;销售额将近69亿,环比增长…

2021年全国职业院校技能大赛(中职组)网络安全竞赛试题A(1)

2021年全国职业院校技能大赛(中职组) 网络安全竞赛试题 (1) 这里是21的试题就以刷题为主,方法可能就不那么详细,如果是新题会详细过程,其他的详细过程可以看22的试题 目录 2021年全国职业院校…

【LeetCode】Day210-二叉搜索树的后序遍历序列

题目 剑指 Offer 33. 二叉搜索树的后序遍历序列【中等】 题解 二叉搜索树性质&#xff1a;左<根&#xff0c;右>根 后序遍历序&#xff1a;左右根 递归分治 利用递归求解&#xff0c;[ i,j ]区间中找到第一个比根节点大的元素&#xff0c;下标为m&#xff0c;则[i,m…

10月17日|实验报告|paddle paddle|概念辨析

目录 一、安装paddle paddle 第一章 零基础入门深度学习 机器学习和深度学习综述 1.人工智能、机器学习、深度学习的关系 1.1人工智能(Artificial Intelligence,AI) 1.2机器学习 1.2.1机器学习的实现 1.2.2机器学习方法论 1.3深度学习​​​​​​​ 一、安装paddle…

Transformer的位置编码笔记(positional encoding)

一、为什么Transformer需要对输入进行位置编码因为Transformer的输入并没有内涵位置信息&#xff0c;同样的词在不同位置&#xff0c;或者同一个序列以不同顺序输入&#xff0c;对应的词间都会得到相同的注意力权重和输出&#xff0c;但是在NLP领域&#xff0c;词的顺序会极大地…

P20 PyTorch 反向传播算法

前言&#xff1a;反向传播是深度学习的基础核心&#xff0c;如果掌握了这个&#xff0c;其它的模型会很容易理解。这里面结合前面的多层感知机&#xff0c;深入了解一下权重数是如何更新的目录&#xff1a;1: 多层感知机节点间的权重系数更新2&#xff1a; 反向传播的基本思路3…

基于VS Code的插件开发(基础篇)

一、基础介绍 VSCode 采用了 Electron&#xff0c;在语言上&#xff0c;VSCode 使用了自家的 TypeScript 语言开发。Electron是基于 Chromium 和 Node.js&#xff0c;使用 JavaScript, HTML 和 CSS 构建跨平台的桌面应用&#xff0c;它兼容 Mac、Windows 和 Linux&#xff0c;…

认识DOM和架构

DOM 代表文档对象模型&#xff0c;是 HTML 和 XML 文档的接口(API)。当浏览器第一次读取(解析)HTML文档时&#xff0c;它会创建一个大对象&#xff0c;一个基于 HTM L文档的非常大的对象&#xff0c;这就是DOM。它是一个从 HTML 文档中建模的树状结构。DOM 用于交互和修改DOM结…

SpreadJS 16.0 中文版在线电子表设计预览EXCEL-Crack

SpreadJS 纯前端表格控件 - V16.0 新特性--内容摘自互联网 新文件结构是 SpreadJS 近几个版本中最为重要的架构级更新。这种新文件结构可以大大提高导入大型 Excel 文件的性能&#xff0c;同时在保存时创建更小、优化更好的文件。 在 V15.0 及更早的版本中&#xff0c;Spread…