OpenGL cube map方式实现的环境贴图●如何设置相机

时间:2022-01-11 06:35:02

对cube map有一些了解的朋友都知道,如果要在物体表面实现镜面反射的效果,需要在物体的中心设置一个相机,沿+X,-X,+Y,-Y,+Z,-Z六个方向分别取景,渲染到cube map的六个子texture中。

设置相机的时候,一般都不会弄错相机的朝向,但是,估计很多人搞不清楚相机的UP方向。

OpenGL cube map方式实现的环境贴图●如何设置相机

网络上的资料很少论及这个问题,因此,决定自己做一个简单的小实验,彻底搞清楚这个问题。为此,准备了下面的6张图片,分别充当cube map的六个子texture。

OpenGL cube map方式实现的环境贴图●如何设置相机OpenGL cube map方式实现的环境贴图●如何设置相机OpenGL cube map方式实现的环境贴图●如何设置相机OpenGL cube map方式实现的环境贴图●如何设置相机OpenGL cube map方式实现的环境贴图●如何设置相机OpenGL cube map方式实现的环境贴图●如何设置相机

使用cube map方式将它们渲染到一个正方体表面,观察它们的方向,使用的vertex shader代码如下:

#version 140 core

in vec4 vs_position_modelSpace;
out vec3 fs_position_modelSpace;
uniform mat4 worldViewProjectionMatrix;

void main()
{
gl_Position = worldViewProjectionMatrix * vs_position_modelSpace;
fs_position_modelSpace = vs_position_modelSpace.xyz;
}
fragment shader代码如下

#version 140 core

in vec3 fs_position_modelSpace;
out vec4 color;
uniform samplerCube cubeMapTexture;//立方贴图

void main()
{
vec3 texCoord = normalize(fs_position_modelSpace - vec3(0, 0, 0));//正方体的中心点是(0, 0, 0)
color = texture(cubeMapTexture, texCoord);
}
我们要观察正方体的六个面,但是每次只能看到它的三个面。

为了观察+X,+Y,+Z面,我们需要剔除物体的背面,只渲染正面:

glCullFace(GL_BACK);
渲染的结果如下:

OpenGL cube map方式实现的环境贴图●如何设置相机

为了观察-X,-Y,-Z面,我们需要剔除物体的正面,只渲染背面:

glCullFace(GL_FRONT);
渲染结果如下:

OpenGL cube map方式实现的环境贴图●如何设置相机

结论如下,(使用OpenGL的cube map)生成环境贴图的时候:

①当相机朝向+X,-X,+Z,-Z方向的时候,其UP方向都是+Y方向;

②当相机朝向+Y方向的时候,其UP方向是-Z方向

③当相机朝向-Y方向的时候,其UP方向是+Z方向


其实值得注意的只是顶部和底部的+Y和-Y两个方向。有一个比较傻瓜的做法是:渲染+Z方向之后,就让相机后仰90°,就可以渲染+Y方向了;渲染+Y方向之后,就让相机前倾180°,就可以渲染-Y方向了。


以下图片可以帮助大家更好地理解cube map各个子texture之间的关系:

OpenGL cube map方式实现的环境贴图●如何设置相机

最后,提个醒,使用glTexImage2D()或glTexStorage2D()为GL_TEXTURE_CUBE_MAP_POSITIVE_X、GL_TEXTURE_CUBE_MAP_NEGATIVE_X、GL_TEXTURE_CUBE_MAP_POSITIVE_Y...分配空间的时候,width和height必须相等,也就是说图片的长和宽必须相等,不然就会返回错误。因为这个问题,笔者耽搁了两天,差点唾弃自己的intel核显OpenGL cube map方式实现的环境贴图●如何设置相机