创建立方体贴图

注意:立方体贴图的大小决定被转化的辐照度贴图的精度。

irradianceCubeMap = new CubeMap(32);

调用

CubeMap::CubeMap(int CubeSize) : CubeSize(CubeSize)
{initializeOpenGLFunctions();//CubeMap 创建空间图glGenTextures(1, &envCubemap);glBindTexture(GL_TEXTURE_CUBE_MAP, envCubemap);for (unsigned int i = 0; i < 6; ++i){// note that we store each face with 16 bit floating point valuesglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, GL_RGB16F,CubeSize, CubeSize, 0, GL_RGB, GL_FLOAT, nullptr);}glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}

从已有的场景立方体贴图获取辐照度立方体贴图。

irradianceCubeMap->getIrrandianceCubMapFromCube(envCubemap);

调用

void CubeMap::getIrrandianceCubMapFromCube(unsigned int SourceMap)
{//MatrixQMatrix4x4 captureProjection;QMatrix4x4 lookatMatrix[6];captureProjection.perspective(90.0f, 1.0f, 0.1f, 10.0f);lookatMatrix[0].lookAt(QVector3D(0.0f, 0.0f, 0.0f), QVector3D( 1.0f,  0.0f,  0.0f), QVector3D(0.0f, -1.0f,  0.0f));lookatMatrix[1].lookAt(QVector3D(0.0f, 0.0f, 0.0f), QVector3D(-1.0f,  0.0f,  0.0f), QVector3D(0.0f, -1.0f,  0.0f));lookatMatrix[2].lookAt(QVector3D(0.0f, 0.0f, 0.0f), QVector3D( 0.0f,  1.0f,  0.0f), QVector3D(0.0f,  0.0f,  1.0f));lookatMatrix[3].lookAt(QVector3D(0.0f, 0.0f, 0.0f), QVector3D( 0.0f, -1.0f,  0.0f), QVector3D(0.0f,  0.0f, -1.0f));lookatMatrix[4].lookAt(QVector3D(0.0f, 0.0f, 0.0f), QVector3D( 0.0f,  0.0f,  1.0f), QVector3D(0.0f, -1.0f,  0.0f));lookatMatrix[5].lookAt(QVector3D(0.0f, 0.0f, 0.0f), QVector3D( 0.0f,  0.0f, -1.0f), QVector3D(0.0f, -1.0f,  0.0f));//Bufferunsigned int captureFBO, captureRBO;glGenFramebuffers(1, &captureFBO);glGenRenderbuffers(1, &captureRBO);glBindFramebuffer(GL_FRAMEBUFFER, captureFBO);glBindRenderbuffer(GL_RENDERBUFFER, captureRBO);glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24, CubeSize, CubeSize);glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, captureRBO);//渲染到envCubemap。使用irradianceShaderQOpenGLShaderProgram irradianceShader;irradianceShader.addShaderFromSourceFile(QOpenGLShader::Vertex,":/rectTocube.vert");irradianceShader.addShaderFromSourceFile(QOpenGLShader::Fragment,":/irradiance_convolution.frag");irradianceShader.link();irradianceShader.bind();irradianceShader.setUniformValue("projection",captureProjection);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_CUBE_MAP, SourceMap);glViewport(0,0,CubeSize,CubeSize);glBindFramebuffer(GL_FRAMEBUFFER,captureFBO);for(unsigned int i = 0; i < 6; ++i){irradianceShader.setUniformValue("view",lookatMatrix[i]);glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,\GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, \envCubemap,0);glClear(GL_COLOR_BUFFER_BIT |  GL_DEPTH_BUFFER_BIT);renderCube();}glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

新建帧缓存,渲染缓存,设置渲染缓存大小(深度、模板大小),绑定到帧缓存。

设置Shader参数
for(i :6){
\quad 绑定立方体贴图六个面中的某一个面到帧缓存。
\quad glClear()
\quad 渲染到绑定的立方体贴图的该面。
}

Shader

.vert

#version 330 core
layout (location = 0) in vec3 aPos;out vec3 WorldPos;uniform mat4 projection;
uniform mat4 view;void main()
{WorldPos = aPos;gl_Position =  projection * view * vec4(WorldPos, 1.0);
}

.frag

#version 450 core
out vec4 FragColor;
in vec3 WorldPos;layout(binding = 0)uniform samplerCube environmentMap;const float PI = 3.14159265359;void main()
{// The world vector acts as the normal of a tangent surface// from the origin, aligned to WorldPos. Given this normal, calculate all// incoming radiance of the environment. The result of this radiance// is the radiance of light coming from -Normal direction, which is what// we use in the PBR shader to sample irradiance.vec3 N = normalize(WorldPos);vec3 irradiance = vec3(0.0);// tangent space calculation from origin pointvec3 up    = vec3(0.0, 1.0, 0.0);vec3 right = normalize(cross(up, N));up         = normalize(cross(N, right));//采样点采集float sampleDelta = 0.025;float nrSamples = 0.0;for(float phi = 0.0; phi < 2.0 * PI; phi += sampleDelta)//cos角度{for(float theta = 0.0; theta < 0.5 * PI; theta += sampleDelta)//sin角度{// 球面到笛卡尔坐标(切线空间)vec3 tangentSample = vec3(sin(theta) * cos(phi),  sin(theta) * sin(phi), cos(theta));// 切线空间到世界空间vec3 sampleVec = tangentSample.x * right + tangentSample.y * up + tangentSample.z * N;//乘以系数 cos(θ) ,因为较大角度的光较弱,而系数 sin(θ) 则用于权衡较高半球区域的较小采样区域的贡献度。irradiance += texture(environmentMap, sampleVec).rgb * cos(theta) * sin(theta);nrSamples++;}}irradiance = PI * irradiance * (1.0 / float(nrSamples));FragColor = vec4(irradiance, 1.0);
}

结语

可以看出,对于辐照度贴图的每一个纹理点,都需要大量的采样点计算。如果采样点过大,或渲染纹理点较多,则会导致程序运行结果变慢的结果。
一般情况下,为了程序运行速度提高,采用直接载入辐照度贴图的方法来加快程序运行。

结果展示


32x32辐照图帖图

边角位置

2x2 辐照图帖图(在显示天空图时,由于天空图的精度小于屏幕精度,故投影到屏幕会做线性插值)

线性插值只会发生在但个纹理贴图中,纹理贴图之间不会执行线性插值。

1x1

天空图立方体贴图转化为辐照度立方体贴图相关推荐

  1. 多个折线样式_新技能get,折线图转化成多阶梯瀑布图

    瀑布图是由麦肯锡顾问公司所独创的图表类型,因为形似瀑布流水而称之为瀑布图. 此种图表采用绝对值与相对值结合的方式,适用于表达数个特定数值之间的数量变化关系. 10月-12月累计等于四季度,一季度-四季 ...

  2. 2021-07-27 对labelme标注出来的JSON文件进行灰度图转化(标签值0.1.2.3.4)

    对labelme标注出来的JSON文件进行灰度图转化(标签值0.1.2.3.4) 原图如下: 标注后生成json文件如下: import cv2 import numpy as np import j ...

  3. 利用公式实现RGB图转化为灰度图

    通过公式完成RGB图转化为灰度图 任务介绍 公式介绍 关键代码 效果展示 任务介绍 我们在进行RGB图像转灰度图时可以使用Opencv中的库函数imread,需要将参数flags设置为0,cv2.im ...

  4. 怎么把word里面的彩色图转化为灰度图,直接在word里面操作,无需转其他软件,超简单!(位图和矢量图都可以)

    怎么把word里面的彩色图转化为灰度图,直接在word里面操作,无需转其他软件,超简单!(位图和矢量图都可以) Microsoft Office Word是微软公司的一个文字处理器应用程序.它最初是由 ...

  5. 案例讲解如何将ER图转化为关系模型

    要将ER图转化为关系模型,就得先弄清楚ER图中的基本元素. 如果不清楚主体.属性.键等元素分别代表什么,那么下面谈转化准则的时候,大家可能会冒出很多问号. 关于ER图的基本元素,此前在这篇文章中做过详 ...

  6. 图像由彩色图转化为灰度图的三种方法

    一.原理 对于图像由彩色图转化为灰度图有三种方法 分别为 加权法 均值法 最大值法 加权法就是  GRAY==0.3*R+0.59*G+0.11*B 均值法就是 GRAY==(R+G+B)/3 最大值 ...

  7. Python图片转gif(将静态图转化为分块加载的动态图)

    简介 将静态图转化为分块加载的动态图 方案 1. PIL: 1. 创建背景图2. 将原图拆分成N块并依次合成到背景图的相应位置, 得到N张素材图3. 将N张素材图合成GIF2. pygifsicle对 ...

  8. 各种图(流程图,思维导图,UML,拓扑图,ER图)简介

    来源于:http://www.cnblogs.com/jiqing9006/p/3344221.html 流程图 1.定义:流程图是对过程.算法.流程的一种图像表示,在技术设计.交流及商业简报等领域有 ...

  9. 图神经网络(一)图信号处理与图卷积神经网络(5)图卷积神经网络

    图神经网络(一)图信号处理与图卷积神经网络(5)图卷积神经网络 0. 概述 1. 对频率响应矩阵进行参数化 2. 对多项式系数进行参数化 3. 设计固定的图滤波器 0. 概述 在学习了图滤波器定义的基 ...

最新文章

  1. mqtt android简书,iOS MQTT协议笔记
  2. LeetCode 495. Teemo Attacking
  3. php常用插件,关于PHP网站编程中常用插件的使用——w3cdream|前端学习-开发
  4. mysql最高权限超级用户是_MySQL中,预设的、拥有最高权限超级用户的用户名为( )...
  5. 7-25日牛客网刷题 未知点、错题 集合
  6. Linux软件安装管理 - CentOS (三) ---- 源码包管理
  7. python3 http.server 本地服务支持跨域
  8. linux中tar命令的使用
  9. 【操作系统】上下文切换
  10. IOS Animation-KeyPath值
  11. 每日三道前端面试题--vue 第二弹
  12. java poi 生成ppt表格,关于java使用POI导出ppt ,其中表格setText 失败问题
  13. TensorFlow-gpu安装和测试(TensorFlow-gpu1.14+Cuda10)
  14. 笔记本电脑耳机插入后声音还是外放的解决办法
  15. 报错error C3872: '0x3000': this character is not allowed in an identifier
  16. TCP滑动窗口原理终于清楚了!
  17. 图论入门六:哥尼斯堡七桥问题
  18. 从优酷到阿里文娱,大麦终于“转正”了?
  19. 通过搜狗抓取微信公众号--------破解url
  20. 福建省计算机二级知识点,福建省计算机二级语言复习资料.doc

热门文章

  1. Corral the Cows POJ - 3179(二分+前缀和+离散化)
  2. android 连接商米POSV1内置打印机
  3. 计算机考研是选地区还是学校,2021考研:举例说明,怎么选择院校和地区
  4. 从零开始学习CANoe(十一)—— 信号发生器(Signal Generator)
  5. Ros:people包下子包leg_detector及其相关包笔记
  6. 39岁单身程序员入住养老院
  7. PMP 项目管理 考前专题(02)敏捷开发专题总结
  8. 破解美团外卖的 _token算法
  9. ASP.NET Lambda表达式
  10. 动力电池:车企们的新角斗场