立方体贴图
作者:互联网
文章目录
立方体贴图
什么是立方体贴图?
- 立方体贴图就是一个包含了6个2D纹理的纹理,每个2D纹理都组成了立方体贴图的一个面
- 特性:只要立方体贴图的中心位于原点,我们就能使用立方体的实际位置向量做为纹理坐标对立方体贴图进行采样
为什么要用立方体贴图?
- 用立方体贴图可以实现环境贴图
怎么使用立方体贴图?
-
绑定立方体贴图时,纹理目标要设置为GL_TEXTURE_CUBE_MAP
-
要为立方体贴图的每个面创建纹理,这时的纹理目标要设置为立方体贴图某个特定的面(GL_TEXTURE_CUBE_MAP_POSITIVE_X/Y/Z/_NEGATIVE_X/Y/Z)
-
纹理环绕方式:GL_TEXTURE_WRAP_S/T/R,分别代表x,y,z方向
-
纹理x,y,z方向的环绕方式设置为GL_CLAMP_TO_EDGE,原因是:当对两个面之间进行采样时,能够获得纹理的边界值
-
在片段着色器中,采样器的类型为samplerCube,纹理坐标的类型也变为vec3
天空盒
客户端的绘制
- 在绘制天空盒时,要保证他是场景中第一个绘制的,并且禁用深度写入,这么做的目的是保证天空盒始终在其他物体的后面
- 为了实现摄像机在场景中移动时,天空盒的位置保持不变,在顶点着色器中使用视图矩阵时,要将视图矩阵中有关移动的分量去掉,也就是视图矩阵的第四列去掉(这一步可以在客户端执行,也可以在顶点着色器中执行)
顶点着色器
- 当立方体的中心位于原点时,立方体上的每个位置向量都是从原点发出的方向向量,所以可以用立方体上的位置向量做为立方体贴图的纹理坐标
- 因此在顶点着色器中可以直接将立方体的位置向量输出,然后在片段着色器中当纹理坐标使用
片段着色器
- 用从顶点着色器输入进来的位置向量对立方体贴图采样即可
改进天空盒绘制方式
先说一下提前深度测试
- 提前深度测试是一种硬件特性,他允许在片段着色器运行前进行深度测试;这样在提前深度测试时,只要发现某个片段不可见,就丢弃他,不再运行该片段的片段着色器,提高程序性能
- 使用提前深度测试最有效的方式是:提前运行一条渲染管线,这条渲染管线只用来写入深度缓冲,其中顶点着色器只变换顶点位置,不需要片段着色器
- OpenGL中强制开启提前深度测试的方法:使用一个带有layout qualifier的片段着色器:
layout (early_fragment__tests) in;
改进思路
- 由于先绘制天空盒,就会对屏幕上每个像素运行一次片段着色器,即使是只有一小部分的天空盒最终可以被看到。如果先绘制场景中的其他物体,使其填充深度缓冲,最后绘制天空盒,这样根据提前深度测试的原理,在绘制天空盒时,就可以进行提前深度测试,然后只对通过的片段执行片段着色器,从而在很大程度上减少片段着色器的调用,提高效率
顶点着色器
- 将gl_Position的z分量设置为w;原因是:在顶点着色器之后,进行标准设备坐标转换时,可以保证天空盒的z值或者说是深度值始终为1.0
客户端的绘制
- 由于天空盒的深度值将会是1.0,所以需要将深度测试的比较函数修改为GL_LEQUAL
环境映射
- 由天空盒的例子可知,立方体贴图实际上就是将整个环境映射到了一个纹理上,这样的贴图又叫做环境贴图
- 像天空盒一样使用立方体贴图的技术就叫做环境映射,使用环境映射的方式有反射和折射
反射
- 这里说的反射是指物体表面反射出他周围的环境,意思是:从观察者角度看去,物体表面的颜色或多或少的等于他周围环境的颜色
片段着色器
- 根据摄像机的位置和物体顶点位置计算观察方向
- 根据观察方向和物体顶点法线方向计算反射方向,利用glsl的内置函数reflect(…)
- 根据放射方向采样环境贴图
顶点着色器
- 由于摄像机的位置是世界坐标,所以物体也应该输出世界坐标系中的顶点位置
- 输出世界坐标系中的法线方向;这里需要用到法线矩阵
- 法线矩阵等于模型矩阵去掉矩阵中平移分量后的逆矩阵的转置矩阵,也可以先求出模型矩阵逆矩阵的转置矩阵,再去掉平移部分,平移部分就是矩阵的第四列;去掉矩阵中的平移部分是因为法线只关心方向不关心位置
mat3 normalMat = transpose(inverse(mat3(modelMat)));
//或者
mat3 normalMat = mat3(transpose(inverse(modelMat)));
折射
- 折射与反射类似,不同的是计算折射方向的方法。
- 采样从观察方向折射出的环境贴图颜色,要知道两种材质的折射率,然后利用glsl内置函数refract(…)计算折射方向
标签:贴图,片段,矩阵,立方体,顶点,着色器 来源: https://blog.csdn.net/m0_57980287/article/details/117265996