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如下:

 #version  core

 layout(location = ) in vec3 inPosition;// 顶点位置

 uniform mat4 mvpMatrix;

 out vec3 texCoord;// 立方体纹理在此顶点处的坐标值

 void main()
{
vec4 position = mvpMatrix * vec4(inPosition, 1.0);
gl_Position = position.xyww;// 保证天空盒的深度始终为最深
texCoord = inPosition;// 立方体纹理的特殊情况
}

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

其fragment shader如下:

 #version  core

 uniform samplerCube skybox;

 in vec3 texCoord;

 out vec4 color;

 void main()
{
color = texture(skybox, texCoord);
}

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

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

反射(Reflection)

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

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

实现反射的vertex shader如下:

 #version  core

 layout (location = ) in vec3 inPosition;
layout (location = ) in vec3 inNormal; uniform mat4 projection;
uniform mat4 view;
uniform mat4 model; out vec3 passNormal;
out vec3 passPosition; void main()
{
gl_Position = projection * view * model * vec4(inPosition, 1.0); passNormal = mat3(transpose(inverse(model))) * inNormal;
passPosition = vec3(model * vec4(inPosition, 1.0));
}

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

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

 #version  core

 uniform vec3 cameraPos;
uniform samplerCube skybox; in vec3 passNormal;
in vec3 passPosition; out vec4 FragColor; void main()
{
vec3 I = normalize(passPosition - cameraPos);
vec3 R = reflect(I, normalize(passNormal));
FragColor = vec4(texture(skybox, R).rgb, 1.0);
}

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

折射(Refraction)

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

 #version  core

 uniform vec3 cameraPos;
uniform samplerCube skybox; in vec3 passNormal;
in vec3 passPosition; out vec4 FragColor; void main()
{
float ratio = 1.00 / 1.52;
vec3 I = normalize(passPosition - cameraPos);
vec3 R = refract(I, normalize(passNormal), ratio);
FragColor = vec4(texture(skybox, R).rgb, );
}

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

总结

没什么可总结的。

CSharpGL(43)环境映射(Environment Mapping)-天空盒(Skybox)反射(Reflection)和折射(Refraction)的更多相关文章

  1. 3DShader之立方体环境映射(cubic environment mapping)

    前面讲了球形环境映射,然而目前采用更多的是立方体环境映射.国际惯例:上图先: 1.反射: 2.折射 3.fresnel(反射+折射) 4.色散 好了,大概讲下原理, 立方体纹理我就不多讲了,它以一个3 ...

  2. 《The Cg Tutorial》阅读笔记——环境贴图 Environment Mapping

    本文为大便一箩筐的原创内容,转载请注明出处,谢谢:http://www.cnblogs.com/dbylk/p/4969956.html 环境贴图 Environment Mapping 一.简介 环 ...

  3. Environment Perception: 3D Truss Environment Mapping and Parametric Expression Extraction

    Experiments Preparation roscore rosrun pcl_ros pcd_to_pointcloud ~/.ros/wh2_lg707070_1ms0.01_filtere ...

  4. [经验] Unity3D 里怎么制作天空盒(skybox)

    记载一个简单的  天空盒子  的制作方法 第一步: 在 assets 文件夹下新建一个文件夹, 随便取个名字, 不过最好是用来专门管理场景游戏对象的文件夹,    例如放在这个 Skybox 里:  ...

  5. 立方体贴图(Cubemap)

    http://blog.csdn.net/asdjy123/article/details/51190643 点击打开链接 好东西保存方便查看 立方体贴图(Cubemap) 原文 Cubemaps 作 ...

  6. (转)OpenGL学习——立方体贴图

    转自:https://learnopengl-cn.readthedocs.io/zh/latest/04%20Advanced%20OpenGL/06%20Cubemaps/ 我们之前一直使用的是2 ...

  7. OpenGL 核心技术之立方体贴图

    笔者介绍:姜雪伟,IT公司技术合伙人,IT高级讲师,CSDN社区专家.特邀编辑,畅销书作者,国家专利发明人;已出版书籍:<手把手教你架构3D游戏引擎>电子工业出版社和<Unity3D ...

  8. Grand Theft Auto V (侠盗列车手5)图形研究

    原文地址:http://www.adriancourreges.com/blog/2015/11/02/gta-v-graphics-study/   原文的简介: GTA(侠盗猎车)系列自从1997 ...

  9. DirectX11 With Windows SDK--22 立方体映射:静态天空盒的读取与实现

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

随机推荐

  1. loadrunner11的移动端性能测试之脚本录制

    以前使用LR11录制过一个app的登录操作,这里记录一下 测试准备 硬件要求 1,  负载测试机一台(内存8G以上,cpu 1.5GHZ以上,存储空间20G以上)或两台以上(控制机和多个负载机). 2 ...

  2. MongoDB--操作符

    $gt -- > $lt -- < $gte -- >= $lte -- <= $all 与 in 类似,不同的是必须满足[]内所有的值 $exists 字段是否存在 db.s ...

  3. 解决安卓手机input获取焦点时会将底部固定定位按钮顶起的问题

    一个页面上有个固定在底部的按钮,页面中有个input框,点击input框获取焦点时,在苹果手机上没事,但在安卓手机上弹出的键盘会将按钮顶起来,这就很不好看了,想了个办法解决一下.之前一直觉得用inpu ...

  4. TortoiseGit保存密码

    TortoiseGit保存密码 方法一:使用Bash命令 1.设置name和emailgit config --global user.name "yilei"git config ...

  5. Index Scans 索引扫描

    官方文档链接地址 http://docs.oracle.com/cd/E11882_01/server.112/e40540/indexiot.htm#CNCPT1170 Index Scans 在索 ...

  6. 【Android Developers Training】 10. 序言:支持不同设备

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  7. Python3分析sitemap.xml抓取导出全站链接

    最近网站从HTTPS转为HTTP,更换了网址,旧网址做了301重定向,折腾有点大,于是在百度站长平台提交网址,不管是主动推送还是手动提交,前提都是要整理网站的链接,手动添加太麻烦,效率低,于是就想写个 ...

  8. Spring Security 概念基础 验证流程

    Spring Security 概念基础 验证流程 认证&授权 认证:确定是否为合法用户 授权:分配角色权限(分配角色,分配资源) 认证管理器(Authentication Manager) ...

  9. Windows10 Enterprise版本周年更新问题

    安装Windows10的时候,蛋疼选择了企业版本,导致后来周年更新遇到了蛋疼的问题. 首先是无法接收到周年更新的推送.记得首个周年更新的时候,等了大半年都没有.后来使用了易升进行更新,可以检测到,但是 ...

  10. C# Socket编程笔记(自己看,转载)

    看到这个题目,是不是很眼熟?在博客园里搜下,保证会发现关于这个东东的文章实在是太多了~~~真得是没有写得必要,而且我也有点懒得去琢磨字句.(看到这,肯定得来个转折的了,不然就看不到下文了,不是吗)但是 ...