代码改变世界

OpenGL Cube Map Texturing

2012-12-10 10:39  三戒1993  阅读(153)  评论(0编辑  收藏  举报

都是非纯2D的texture

cube map  texture可以理解为6个面的纸盒, sample的时候使用vector射线型的sample.

volume texture可以理解是一摞2D texture,sample的时候用第几摞+2D坐标来sample.

虽然都是非2D,sample都用3维数据,差异大啊.

CubeMap 在实时渲染中应用十分广泛. 通过视线和法线计算出的反射光线来查询CubeMap
可以创建一个真实的反射镜面体, 通过视线和法线计算出的折射光线来查询CubeMap
可以创建一个透明体. 由于查询速度快的原因,在实时的CG渲染中应用十分的广泛.

我们的CubeMap大都是从外部的图片得来的, 图片是不可以变化的, 故是静态的. 
但问题是, 如果有其他物体在反射物体外运动. 如果我们仅仅查询静态的CubeMap
是不能够反射到动态物体的影象,所以我们需要一个动态的CubeMap, 即我们需要Render to 

Preface
red book 上对于一些内容的讲解,确实比较简略,比如 cube map texturing。
GL 1.2 时,cube map texturing 还是作为 extension 存在,目前 2.1/3.0 早已成为正式标准。

这里有详细的介绍,看完就懂了。
http://developer.nvidia.com/object/cube_map_ogl_tutorial.html

Cube Mapping Explained
对于金属直感的物体,会映射出周围场景的环境(environment mapping),如何在程序中模拟出这个效果呢,cube map texturing 是一种方法。其他方法如:sphere mapping、dual paraboloid mapping 等等。

对于 cube map texturing,其实就是用6张贴图(6 targets),一个 cube,作为当前物体的环境贴图(environment),在绘制物体时,不同的点,会对应到不同的 target 上,取得不同的 tex pixel 信息。

对于 (x, y, z),哪个值最大,就选取那个为 mayor(ma)。
major axis 
direction     target                                                            sc      tc     ma
 
----------          ---------------------------------                                              ---       ---      ---
  
+rx             GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT    -rz      -ry     rx
  
-rx               GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT   +rz    -ry     rx
  
+ry             GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT     +rx    +rz   ry
  
-ry               GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT   +rx     -rz    ry
  
+rz             GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT    +rx    -ry     rz
  
-rz              GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT    -rx     -ry     rz  

s   =   ( sc/|ma| + 1 ) / 2 
t   =   ( tc/|ma| + 1 ) / 2

sc / |ma| = -1.0 ~ 1.0
(sc / |ma| + 1)/2 = 0.0 ~ 1.0
对于每个 target surface,s/t 会映射为:
(0.0, 0.0)
       +-----------------------------+
        |                       |
        |                       |
        |                       |
       +-----------------------------+
                           (1.0, 1.0)

Sample
---- init ----
glGenTextures(1, &texName);
glBindTexture(GL_TEXTURE_CUBE_MAP, texName);

glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_REPEAT);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_REPEAT);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_REPEAT);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, TEX_WIDTH, TEX_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, mytex1);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, TEX_WIDTH, TEX_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, mytex2);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, TEX_WIDTH, TEX_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, mytex3);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, TEX_WIDTH, TEX_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, mytex4);
glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, TEX_WIDTH, TEX_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, mytex5);
glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, TEX_WIDTH, TEX_HEIGHT, 0, GL_RGBA, GL_UNSIGNED_BYTE, mytex6);

glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP);
glEnable(GL_TEXTURE_GEN_S);
glEnable(GL_TEXTURE_GEN_T);
glEnable(GL_TEXTURE_GEN_R);

---- draw it ----
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_TEXTURE_CUBE_MAP);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
glBindTexture(GL_TEXTURE_CUBE_MAP, texName);

glutSolidSphere(1.0, 30, 10);

对于 mytex1 ~ 6 就是简单的 64x64 single-color texture。使用 cube mapping 也只是设置到 target 即可。
[ogl] Cube Map Texturing - kasicass - Code@Pig Home