QT之OpenG立方体贴图
创始人
2025-05-30 17:54:17

QT之OpenGL立方体贴图

  • 1. 概述
  • 2. 绘制天空盒
    • 2.1 demo
  • 3. 环境映射
    • 3.1 反射
      • 3.1.1 demo
      • 3.1.2
    • 3.2 折射
      • 3.2.1 demo
  • 4. 反射纹理
    • 4.1 demo
  • 5. 参考

1. 概述

立方体贴图(Cube Map)是将多个纹理组合起来映射到一张纹理上的一种纹理类型。立方体贴图就是包含6个2D纹理的纹理,它有一个很方便的特性,就是可以通过一个方向向量来对纹理进行索引/采样。大小为1x1x1的立方体如下所示:
在这里插入图片描述

2. 绘制天空盒

利用立方体绘制天空盒的步骤主要如下:

  • 准备6个2D纹理
  • 设置立方体贴图纹理
    在这里插入图片描述
    // 创建立方体纹理
    m_cubeMap=new QOpenGLTexture(QOpenGLTexture::TargetCubeMap);
    // 加载纹理图片
    QImage _right   = QImage(":/images/images/skybox/right.jpg").convertToFormat(QImage::Format_RGB888);
    QImage _left    = QImage(":/images/images/skybox/left.jpg").convertToFormat(QImage::Format_RGB888);
    QImage _top     = QImage(":/images/images/skybox/top.jpg").convertToFormat(QImage::Format_RGB888);
    QImage _bottom  = QImage(":/images/images/skybox/bottom.jpg").convertToFormat(QImage::Format_RGB888);
    QImage _front   = QImage(":/images/images/skybox/front.jpg").convertToFormat(QImage::Format_RGB888);
    QImage _back    = QImage(":/images/images/skybox/back.jpg").convertToFormat(QImage::Format_RGB888);
    // 设置宽高
    m_cubeMap->setSize(_right.width(), _right.height());
    // 设置颜色模式
    m_cubeMap->setFormat(QOpenGLTexture::RGBFormat);
    // 分配存储区域
    m_cubeMap->allocateStorage(QOpenGLTexture::RGB, QOpenGLTexture::UInt8);
    // 分别设置六个面的纹理数据
    m_cubeMap->setData(0, 0, QOpenGLTexture::CubeMapPositiveX,QOpenGLTexture::RGB, QOpenGLTexture::UInt8, (const void *)_right.bits());
    m_cubeMap->setData(0, 0, QOpenGLTexture::CubeMapNegativeX,QOpenGLTexture::RGB, QOpenGLTexture::UInt8, (const void *)_left.bits());
    m_cubeMap->setData(0, 0, QOpenGLTexture::CubeMapPositiveY,QOpenGLTexture::RGB, QOpenGLTexture::UInt8, (const void *)_top.bits());
    m_cubeMap->setData(0, 0, QOpenGLTexture::CubeMapNegativeY,QOpenGLTexture::RGB, QOpenGLTexture::UInt8, (const void *)_bottom.bits());
    m_cubeMap->setData(0, 0, QOpenGLTexture::CubeMapPositiveZ,QOpenGLTexture::RGB, QOpenGLTexture::UInt8, (const void *)_front.bits());
    m_cubeMap->setData(0, 0, QOpenGLTexture::CubeMapNegativeZ,QOpenGLTexture::RGB, QOpenGLTexture::UInt8, (const void *)_back.bits());//纹理放大或缩小时,像素的取值方法 ,线性或就近抉择
    m_cubeMap->setMinificationFilter(QOpenGLTexture::Linear);
    m_cubeMap->setMagnificationFilter(QOpenGLTexture::Linear);
    //设置纹理边缘的扩展方法
    m_cubeMap->setWrapMode(QOpenGLTexture::DirectionS, QOpenGLTexture::ClampToEdge);
    m_cubeMap->setWrapMode(QOpenGLTexture::DirectionT, QOpenGLTexture::ClampToEdge);
    
  • 绘制立方体贴图
    // 深度测试函数确保天空盒等于1也能通过测试
    glDepthFunc(GL_LEQUAL); 
    m_skyBoxShaderProgram.bind();
    QMatrix4x4 skyboxView=m_view;
    // 移除skyboxView的位移属性
    skyboxView.setColumn(3,QVector4D(0.0f,0.0f,0.0f,1.0f));
    m_skyBoxShaderProgram.setUniformValue("projection", m_projection);
    m_skyBoxShaderProgram.setUniformValue("view", skyboxView);
    // 指定纹理单元索引
    m_skyBoxShaderProgram.setUniformValue("skybox", 0);
    // 绑定立方体纹理
    m_cubeMap->bind(0);
    // 激活VAO
    glBindVertexArray(m_skyboxVAO);
    glDrawArrays(GL_TRIANGLES, 0, 36);
    glBindVertexArray(0);
    // 深度测试函数设置为默认行为
    glDepthFunc(GL_LESS);
    m_skyBoxShaderProgram.release();
    

2.1 demo

Demo输出如下:
在这里插入图片描述

3. 环境映射

通过使用环境立方体贴图,可以给物体使用反射(Reflection)折射(Refraction)属性,这样使用的技术被称为环境映射(Environment Mapping)

3.1 反射

反射这个属性表现为物体(或物体的一部分)反射它周围环境,原理图如下:
在这里插入图片描述

3.1.1 demo

Demo输出如下:
在这里插入图片描述
相关代码主要与m_reflectionShaderProgram变量相关。

3.1.2

通常物体不会产生全反射的效果,此时使用反射贴图会更合理些

3.2 折射

折射是通过斯涅尔定律(Snell’s Law)来描述的,其原理图如下:
在这里插入图片描述
折射率:
在这里插入图片描述
使用这些折射率可以计算光在两种不同材质间传播的比值,如从空气到水1.00/1.52=0.658

3.2.1 demo

Demo输出如下:
在这里插入图片描述

相关代码主要与m_refractionShaderProgram变量相关。

4. 反射纹理

修改内容如下:

  • 片段着色器
    // 反射纹理颜色
    vec3 reflectionTextureColor = vec3(texture(material.reflection,TextureCoords));// 计算反射纹理
    vec3 I = normalize(FragmentPosition - viewPosition);
    vec3 R = reflect(I, normalize(Normal));
    vec3 reflectionSkyBox = textureCube(skybox, R).rgb;
    vec3 reflection=reflectionTextureColor * reflectionSkyBox;FragColor = vec4((ambient + diffuse + specular + reflection), 1.0);
    
  • 代码
/*myopenglwidget.cpp*/ 
// 指定纹理单元索引
m_shaderProgram.setUniformValue("skybox", 4);
// 绑定立方体纹理
m_cubeMap->bind(4);/*model.cpp*/
/*
OpenGL官网说的是用aiTextureType_AMBIENT类型接收反射纹理,
但是我看Assimp中有单独的aiTextureType_REFLECTION类型,
且使用起来与aiTextureType_AMBIENT没有什么差别
*/
QVector reflectionMaps = loadMaterialTextures(material, aiTextureType_REFLECTION, "texture_reflection");
textures.insert(textures.end(), specularMaps.begin(), specularMaps.end());/*mesh.cpp*/
else if(name == "texture_specular")
{// 设置反射纹理通道编号shader.setUniformValue("material.reflection", index);
}

4.1 demo

demo效果如下:
在这里插入图片描述

5. 参考

  • 立方体贴图

相关内容

热门资讯

【前端八股文】JavaScri... 文章目录Set概念与arr的比较属性和方法并集、交集、差集Map概念属性和方法String用索引值和...
海康硬盘录像机接入RTSP/o... EasyNVR安防视频云服务平台可支持设备通过RTSP/Onvif协议接入平台,能提供...
在混合劳动力时代如何避免网络安... 在混合劳动力时代如何避免安全网络风险 三年多来,混合工作一直是工作生活中不可或缺的一...
2023还不懂Jmeter接口... 这里介绍的Jmeter接口测试的的实战,如果文章内容没遇看懂的话,我这边...
基于4G/5G弱网聚合的多链路... 基于4G/5G多卡聚合(弱网聚合)的智能融合通信设备技术亮点 增强带宽提供可靠连接 通过将多个有线和...
如何使用Synplify综合v... 文章目录使用Synplify综合的好处synplify的教程方法1(无效)...
2023年全国最新高校辅导员精... 百分百题库提供高校辅导员考试试题、辅导员考试预测题、高校辅导员考试真题、辅导员证考试题库等ÿ...
2022年18个值得期待的Le... 有数百个独特的LearnDash附加组件,您可能很难选择您的LearnDash LMS...
【java基础】Stream流... 文章目录基本介绍流的创建流的各种常见操作forEach方法filter方法map方法peek方法fl...
javaweb高校行政办公自动... 本课题基于我国高校管理信息化建设现状,结合在实际工作中所遇到的问题和收获,...
一款专门为自动化测试打造的集成... 你好,我是不二。 随着行业内卷越来越严重,自动化测试已成为测试工程师的...
【go-zero】golang... 一、casbin 概览 1、casbin基本了解 casbin的GitHub:https://git...
现在开发低代码平台算晚吗? 现在开发低代码平台算晚吗?作为低代码的亲戚——零代码厂商,这篇就以“厂商...
【JavaWeb】书城项目(2... 222.书城项目-第三阶段:修改所有html页面为jsp页面 改成jsp页面之后&#x...
基于jeecgboot的大屏设...      通过前面设计好数据源后,就要进行数据集的设计了。      一、还是在onl...
Linux命令小技巧:显示文件... 工作中会有很多千奇百怪的需求,比如:如何在 Linux 命令行中快速找到...
【找工作】-- 大数据工程师找... 目录 1.前言 2.找工作的理论知识 2.1 分析个人特征 2.1.1 你自身优势是什么?
C++基础算法④——排序算法(... 排序算法 1.插入排序 2.桶排序 1.插入排序 基本思想:将初始数据分为有序部分和...
nginx快速入门.跟学B站n... nginx快速入门.跟学B站nginx一小时精讲课程笔记nginx简介及环境准备nginx简介环境准...
ORACLE存过互相调用之间事... 今天在问答区看到一个问题是 假如有procedureA、procedureB和procedureC&...
基于java中Springbo... 基于java中Springboot框影视影院订票选座管理系统 开发语言:Java 框...
CVE-2018-18086 最近闲来无事,看到青少年CTF平台,感觉对新手还是比较友好的࿰...
【深度学习】基于Hough变化... 💥💥💞💞欢迎来到本博客❤️❤️&#x...
AtCoder Beginne... D - Bank (atcoder.jp)         (1)题目大...
VxWorkds 内存管理(3... 虚拟内存管理 对于带MMU的目标板,VxWorks提供虚拟内存的支持,V...
【微服务】—— 统一网关Gat... 文章目录1. 概述1.1 为什么需要网关1.2 SpringCloud Gateway2. gate...
文心一言实际测试——让我们拿实... 文心一言实际测试——让我们拿实际说好坏 4月16日,文心一言闪亮登场,就...
Postgresql源码(10... 0 总结 (可以最后看) PLpgSQL_execstate中包含的两个...
网络技术与应用概论(上)——“... 各位CSDN的uu们你们好呀,今天,小雅兰的内容依旧是计算机网络的一些知...
Yolov5 QAT量化训练 1. QAT介绍 从 模型量化(5): 敏感层分析可以看出来,对于yolov5-nano模型,对最后...