注:在网上有一篇关于Cube Mapping的不可多得的好资料,深刻理解这篇文章后对Cube Mapping相关知识可以说有了一定的了解,具体地址是:http://developer.nvidia.com/object/cube_map_ogl_tutorial.html。
一开始我并不觉得这篇文章又多好(可是是当时读的时候很多东西不懂的缘故),第二次读的时候发现写的真的很好。下面就根据这篇文章,谈谈我的想法。
1.传统的2D纹理映射是将物体表面的某个点和一个2维坐标系中某个点对应的一种映射。环境映射(Environment Mapping)是将物体表面的某个点和一个3维空间中的某个向量对应的一种映射。
2.Cube Mapping是一种环境映射,其他的环境映射还有Sphere Mapping和Dual Daraboloid Mapping。Sphere Mapping在OpenGL可以通过指定纹理坐标生成模式为GL_SPHERE_MAP来实现,具体的代码如下:
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE,GL_SPHERE_MAP);
要实现Dual Daraboloid Mapping需要以下两个条件:
two texture units; //这个可以通过texture object来实现
或者
two texture passes; //这个可以通过multitexture来实现
同时还需要指定问题坐标生成模式为GL_REFLECTION_MAP,具体代码如下:
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE,GL_REFLECTION_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE,GL_REFLECTION_MAP);
3.Cube Mapping在OpenGL中是以EXT_texture_cube_map扩展的形式存在的,最早出现在OpenGL 1.3中。
4.Cube Mapping其他的用途包括:Stable Specular Highlights,Skylight Illumination,Dynamic Cube Map Reflections,Fancy Per-Pixel Lighting.在Per-Pixel Lighting中,Cube Mapping主要目的是用来归一化向量的,下面是具体的步骤:
设一个立方体(Cube)表面上的任意点的坐标是(x,y,z),则从立方体原点到此点的向量是V=(x,y,z),将此向量归一化后,设归一化后的向量是V'=(x',y',z'),其中-1<=x',y',z'<=1,在用颜色信息表示这个单位向量的过程中,需要做特殊的处理,将x',y',z'的大小转化到[0,255]这个范围内,具体的转换公式是:
V''=( V'+(1,1,1) )/2.0*255;
然后用同样的方法将立方体表面上的每个点赋给一个象素值。这样实际上就是为任意向量建立了单位向量查询表,任意方向,任意长度的向量都可以在立方体的表面上对应一个象素值,此象素值的颜色信息就是此向量对应的单位向量。
下面是我写的一个完整的Cube Mapping代码:
static GLenum faceTarget[6] = {
GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT,
GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT,
GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT,
GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT,
GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT
};
/* Pre-generated cube map images. */
char *faceFile[6] = { "cm_left.bmp", "cm_right.bmp", "cm_top.bmp", "cm_bottom.bmp",
"cm_back.bmp", "cm_front.bmp" };
void makeCubemap()
{
glEnable(GL_TEXTURE_CUBE_MAP_EXT);
for( int i=0; i<6; i++ )
{
LoadBMPff(faceFile[i],faceTarget[i]);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT);
glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
}
参考文献:
1. http://developer.nvidia.com/object/cube_map_ogl_tutorial.html
2. http://www.cg.tuwien.ac.at/studentwork/CESCG/CESCG-2002/GSchroecker/node14.html
-----------------------------致力于多媒体技术,成为有思想的软件工程师------------------------
此文章为我原创作品,若要转载,请和本人联系,或注明出处。
欢迎大家对文章内容提出宝贵意见,同时希望大家及时指出文中的错误之处,这样我可以及时更正。
我的联系方式:
QQ: 7578420
Email: [email protected]
----------------------------------------------------------------------------------------