CSharpGL(43)环境映射(Environment Mapping)-天空盒(Skybox)反射(Reflection)和折射(Refraction)

开始

如图所示,本文围绕GLSL里的samplerCube记录天空盒(Skybox)、反射(reflection)、折射(refraction)的实现。

下载

CSharpGL已在GitHub开源,欢迎对OpenGL有兴趣的同学加入(https://github.com/bitzhuwei/CSharpGL)

天空盒(Skybox)

samplerCube

想在三维场景里渲染出天空和大地,可以利用一个巨大的立方体,把6个连接的图片分别贴在立方体的6个面上。

这样的立方体就是所谓的天空盒(Skybox)。

OpenGL提供了一个GL_TEXTURE_CUBE_MAP类型的纹理,其本身就是一个立方体,自带6个纹理面。它对应的GLSL里的类型就是samplerCube。SamplerCube正适合做天空盒。

SkyboxNode

渲染天空盒,实际上就是渲染一个巨大的立方体,并且用samplerCube为其上色。

其vertex shader如下:

 1 #version 330 core
 2
 3 layout(location = 0) in vec3 inPosition;// 顶点位置
 4
 5 uniform mat4 mvpMatrix;
 6
 7 out vec3 texCoord;// 立方体纹理在此顶点处的坐标值
 8
 9 void main()
10 {
11     vec4 position = mvpMatrix * vec4(inPosition, 1.0);
12     gl_Position = position.xyww;// 保证天空盒的深度始终为最深
13     texCoord = inPosition;// 立方体纹理的特殊情况
14 }

注意,这里的gl_Position = position.xyww;,是为了保证天空盒的深度始终为最深。这样就不会遮挡住场景里的其他物体。再注意,texCoord = inPosition;这句,就要求我们的天空盒模型必须是中心在坐标原点的立方体,这样才能保证inPosition在数值上等于此顶点的纹理坐标值。

其fragment shader如下:

 1 #version 330 core
 2
 3 uniform samplerCube skybox;
 4
 5 in vec3 texCoord;
 6
 7 out vec4 color;
 8
 9 void main()
10 {
11     color = texture(skybox, texCoord);
12 }

极其简单,就是从skybox纹理中取出对应位置的颜色,写入Framebuffer。

如果把镜头拉远,你会看到所谓的天空盒是这样的:一个剔除了正面的立方体 

反射(Reflection)

利用samplerCube,可以实现一个反射效果——根据反射原理,把天空盒的纹理贴到模型上,看上去的感觉是,模型像镜子一样反射了周围的东西。此即为环境映射的一种。

GLSL自带了反射函数reflect(,);

实现反射的vertex shader如下:

 1 #version 330 core
 2
 3 layout (location = 0) in vec3 inPosition;
 4 layout (location = 1) in vec3 inNormal;
 5
 6 uniform mat4 projection;
 7 uniform mat4 view;
 8 uniform mat4 model;
 9
10 out vec3 passNormal;
11 out vec3 passPosition;
12
13 void main()
14 {
15     gl_Position = projection * view * model * vec4(inPosition, 1.0);
16
17     passNormal = mat3(transpose(inverse(model))) * inNormal;
18     passPosition = vec3(model * vec4(inPosition, 1.0));
19 }

此vertex shader做了3件事:1.给gl_Position赋值。2.传递world space里的法线passNormal。3.传递world space里的位置passPosition。

下面根据反射原理为模型上色(fragment shader):

 1 #version 330 core
 2
 3 uniform vec3 cameraPos;
 4 uniform samplerCube skybox;
 5
 6 in vec3 passNormal;
 7 in vec3 passPosition;
 8
 9 out vec4 FragColor;
10
11 void main()
12 {
13     vec3 I = normalize(passPosition - cameraPos);
14     vec3 R = reflect(I, normalize(passNormal));
15     FragColor = vec4(texture(skybox, R).rgb, 1.0);
16 }

这里利用reflect函数找到反射方向(即纹理坐标),从而找到目标颜色。

折射(Refraction)

折射与反射类似,也是一种环境映射方式。其vertex shader与反射相同,fragment shader也只有一点点不同:利用GLSL内置的refract()函数找到折射方向。

 1 #version 330 core
 2
 3 uniform vec3 cameraPos;
 4 uniform samplerCube skybox;
 5
 6 in vec3 passNormal;
 7 in vec3 passPosition;
 8
 9 out vec4 FragColor;
10
11 void main()
12 {
13     float ratio = 1.00 / 1.52;
14     vec3 I = normalize(passPosition - cameraPos);
15     vec3 R = refract(I, normalize(passNormal), ratio);
16     FragColor = vec4(texture(skybox, R).rgb, 1);
17 }

注意,这里有个ratio是指两种透明物体的折射率。1.52是玻璃对空气的折射率。再注意,这里我们只计算了一个面的折射,然而本文的模型有光线的进入和穿出两次折射。不过一般这样也没关系,最终效果还是不错的。

总结

没什么可总结的。

转载于:https://www.cnblogs.com/bitzhuwei/p/CSharpGL-43-environment-mapping-skybox-reflection-refraction.html

CSharpGL(43)环境映射(Environment Mapping)-天空盒(Skybox)反射(Reflection)和折射(Refraction)...相关推荐

  1. 3Dshader之球形环境映射(sphere environment mapping)

    尼玛等了135天,终于第二个shader出炉了,哥,汗颜啊,真TM扯蛋,不过这几个月都在看一些基础图形的数学知识以及RTR,看了几本过后还是感觉实践才能真正理解所学的东西.好了废话不多说了,这个sha ...

  2. DirectX11进阶6_静态天空盒、反射动态场景与天空盒、Render-To-Texture(Fade/MiniMap/ScreenShot)

    一.静态天空盒与反射天空盒 这一章我们主要学习由6个纹理所构成的立方体映射,以及用它来实现一个静态天空盒. 但是在此之前先要消除两个误区: 认为这一章的天空盒就是简单的在一个超大立方体的六个面内部贴上 ...

  3. Unity3D 里怎么制作天空盒(skybox)

    第一步 新建一个材质球 第二步 点击材质球的Shader-->Skybox/6 sided----->插入6张天空图片 第三步点击 MainCamera 第四步 在MainCamera  ...

  4. BIT祝威博客汇总(Blog Index)

    +BIT祝威+悄悄在此留下版了个权的信息说: 关于硬件(Hardware) <穿越计算机的迷雾>笔记 继电器是如何成为CPU的(1) 继电器是如何成为CPU的(2) 关于操作系统(Oper ...

  5. 南邮|计算机图形学——导入模型、添加天空盒

    导入模型 1.网格 #include <string> #include <fstream> #include <sstream> #include <ios ...

  6. opengl环境映射,反射贴图

    注意完整的mesh与shader文件: mesh增加了法线与高度贴图: // render the meshvoid Draw(Shader shader){// bind appropriate t ...

  7. LearnOpenGL-高级OpenGL-6.天空盒

    本人刚学OpenGL不久且自学,文中定有代码.术语等错误,欢迎指正 我写的项目地址:https://github.com/liujianjie/LearnOpenGLProject 文章目录 天空盒 ...

  8. QT之OpenG立方体贴图

    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 ...

  9. LearnOpenGL 高级OpenGL—立方体贴图

    文章目录 写在前面 立方体贴图 创建立方体贴图 天空盒 加载天空盒 显示天空盒 优化 环境映射 反射 折射 动态环境贴图 总结 写在前面 原文链接.原文应该是github上的一个项目,本文主要用来记录 ...

最新文章

  1. golang-实现自己的事件驱动
  2. 我在大厂上班月薪7千,我晒大厂生活月入3万
  3. mac linux loader,M3 Bitlocker Loader Mac版
  4. SAP SM37后台作业结果显示为alv list怎么样可以显示alv grid形式呢?
  5. java创建一个人函数类_Java对象和类–学习如何创建和实现
  6. 110 同步、异步、阻塞、非阻塞
  7. 使用CImageList的一点心得
  8. Thinkpad SL400开机屏幕亮度问题解决了
  9. STM32F407移植FreeModbus中遇到接收最后一个字节是0xff或0xfe的解决方法
  10. 《孙子兵法战场机变之军争篇》
  11. 【vue】浏览器播放提示音audio
  12. sublime 实现浏览器预览功能
  13. 首届青年统计学家论坛 | 小微金融与个人征信专场
  14. 冰羚-README.md翻译
  15. 【华图教育】综合素质
  16. 你所不知的X86 CPU微码机制
  17. mysql 主库innodb从库myisam_MySQL的两种常用数据库存储引擎:MyISAM与InnoDB
  18. Linux系统安装过程详解
  19. 无人机学习笔记之电池篇
  20. 分享一个有趣的斯特林发动机

热门文章

  1. 「CTSC2018」假面
  2. Visual studio 利用Nuget 控制台安装已经下载好的插件
  3. codevs 2879 堆的判断
  4. 用window.open在同一个新窗口中访问指定url【IE页面缓存问题】
  5. 图像的Gamma(伽玛)校正的原理及OpenCV代码实现
  6. Java加载词向量_W2C得到词向量之后,如何得到句子向量,
  7. Tomcat User 配置
  8. linux存储--可执行文件结构和进程内存模型(三)
  9. android 开发数字键盘,Android 仿「微信」自定义数字键盘
  10. java http连接_Java中通过方法创建一个http连接并请求(服务器间进行通信)