Mipmap MipMap 机制Mipmap是目前应用最为广泛的纹理映射技术之一。Willams将低一级图像的每边的分辨率取为高一级图像的每边的分辨率的二分之一,而同一级分辨率的纹理组则由红、绿、蓝三个分量的纹理数组组成。由于这一个查找表包含了同一纹理区域在不同分辨率下的纹理颜色值,因此被称为Mipmap。
Mipmap可以用一个四棱锥来描述。,如图所示。该四棱锥的总层数为 ,S为初始纹理图像每边的分辨率。若最底层图像为给定的原始图像,则第二层图像可以由最底层图像与边长为2个象素的正方形滤波器做卷积运算得到。一般的,第 层图像可以由第 层图像与边长为 个象素的正方形滤波器做卷积运算得到。例如,某一纹理图像的Mipmap的层数为10层,第10层图像为一个象素,它由原始图像经与边长为512个象素的正方形滤波器做卷积运算压缩得到,其分辨率为1×1。
Mipmap纹理映射在确定屏幕上每一象素内可见的平均纹理颜色时需要计算三个参数,即屏幕象素中心在纹理平面上映射点的坐标 和屏幕象素内可见表面在纹理平面上所映射的边长d。其中 取屏幕象素内可见表面在纹理平面上近似正方形映射区域的中心,d取该近似正方形的边长。显然,d决定了应该在哪一级分辨率的纹理图像平面上查找Mipmap表。
虽然我们很容易通过纹理映射变换和取景变换的逆变换求得屏幕象素中心在纹理平面上映射点的参数坐标 ,但是d的值确不容易确定。一般而言,d的取值应使得在纹理平面上以 为中心,d为边长的正方形尽可能地覆盖屏幕象素地实际映射区域,从而可取该正方形内平均纹理颜色值作为屏幕象素实际映射区域的平均纹理颜色的近似值。在实际处理时,可取d为屏幕象素在纹理屏幕上映射区域的最大边长。
OpenGL中的Mipmap纹理贴图
OpenGL实现了Mipmap的功能。void glTexImage2D ( GLenum target, GLint level, GLint components, GLsizei width, glsizei height, GLint border, GLenum format, GLenum type, const GLvoid * pixels)函数定义一个二维纹理映射。
参数target是常数GL_TEXTURE_2D。
参数level表示多级分辨率的纹理图像的级数,若只有一种分辨率,则level设为0。参数components是一个从1到4的整数,指出选择了R、G、B、A中的哪些分量用于调整和混合,1表示选择了R分量,2表示选择了R和A两个分量,3表示选择了R、G、B三个分量,4表示选择了R、G、B、A四个分量。
参数width和height给出了纹理图像的长度和宽度,参数border为纹理边界宽度,它通常为0,width和height必须是2m+2b,这里m是整数,长和宽可以有不同的值,b是border的值。纹理映射的最大尺寸依赖于OpenGL,但它至少必须是使用64x64(若带边界为66×66),若width和height设置为0,则纹理映射有效地关闭。
参数format和type描述了纹理映射的格式和数据类型,参数format可以是GL_COLOR_INDEX、GL_RGB、GL_RGBA、GL_RED、GL_GREEN、GL_BLUE、GL_ALPHA、GL_LUMINANCE或GL_LUMINANCE_ALPHA(注意:不能用GL_STENCIL_INDEX和GL_DEPTH_COMPONENT)。类似地,参数type是GL_BYPE、GL_UNSIGNED_BYTE、GL_SHORT、 GL_UNSIGNED_SHORT、GL_INT、GL_UNSIGNED_INT、GL_FLOAT或GL_BITMAP。
参数pixels包含了纹理图像数据,这个数据描述了纹理图像本身和它的边界。
纹理映射是一个相当复杂的过程,OpenGL最基本的执行纹理映射所需的步骤主要是:1)定义纹理glTexImage2D();2)控制滤波 glTexParameterf();3)说明映射方式glTexEnvf();4)绘制场景,给出顶点的纹理坐标和几何坐标glEnable(GL_TEXTURE_2D)和glTexCoord2f()。纹理映射只能在RGBA方式下执行,不能运用于颜色表方式。
Clipmap机制针对Mipmap的一些缺点,提出了Clipmap方法。Clipmap方法首先对原始大纹理创建Mipmap,然后选择一个分割尺寸,再把每一个Mipmap层分割成矩形网格状的片,避免了传统方法先把大纹理分割成小纹理再进行Mipmap过滤,而必须处理纹理边界的做法。这种分割是在大纹理被指定在单一的坐标系统中,对MMipmap每一层进行的,与几何无关。
Clipmap的优点在于没有把整个影像金字塔的纹理装入内存,而是将裁剪中心周围一定范围内的纹理通过裁剪装入内存。通过这种方法,分辨率最高的纹理只覆盖了几何模型的一小部分,而分辨率较低的纹理占了大部分。需要贴图的部分只是Clip-mapping的一小部分。
图3-4的1)显示出,Clipmap的优点在于没有把整个影像金字塔的纹理装入内存,而是将裁剪中心周围一定范围内的纹理通过裁剪装入内存。通过这种方法,分辨率最高的纹理只覆盖了几何模型的一小部分,而分辨率较低的纹理占了大部分。图3-4的2)显示出,需要贴图的部分只是Clip-mapping的一小部分。
裁剪中心(ClipCenter)是一个任意的纹理坐标,在0层(最高分辨率层)指定一个裁剪中心,其它高层可由此导出,各层中心都沿一条线对中,从0层的中心直到Mipmap的顶点。在Mipmap的每一层,通过裁剪中心(ClipCenter)和裁剪尺寸(ClipSize)的定义就精确地选择了要裁剪的区域,裁剪下来的这些固定大小的矩形区域叫裁剪区(Clipregion)。经裁剪后的Mipmap形成了ClipTexture。ClipTexture是绘制每一帧所需要的Mipmap的小子集,其存储空间小可以克服硬件容量和带宽的限制。ClipTexture的整个形状象方尖塔形,它由两部分构成,即ClipTexture栈和ClipTexture金字塔。凡是比裁剪尺寸大的Mipmap层就被裁剪,其裁剪下来的裁剪区组成ClipTexture栈,由于裁剪中心是随视点移动而变化的,由此而生成的裁剪区也动态改变,那么ClipTexture栈数据也需要动态切换。ClipTexture金字塔是由Mipmap中小于等于裁剪尺寸的层组成,这些层不用裁剪,它正好是原始的Mipmap金字塔“塔尖”部分,这些层一次能整个容纳在纹理内存中,其数据是静态的,不随视点移动而变化。
在Clipmap中关键问题在于确立裁剪中心ClipCenter点。在平坦的地形上最简单的方法就是将观察点投影到地形上,然后利用纹理坐标作为裁剪中心。这个方法的缺点在于clipmap包含了了观察点后面的纹理,而且出了观察视景体之外。如果把裁剪中心从观察点向前挪一定的距离,那么就需要针对不同的分辨率选择不同的裁剪中心。
虽然裁剪纹理算法处理大纹理产生了很好的效果,但是,就目前它的实现基础来看还有以下限制:
(l)它需要大容量的纹理存储硬件;
(2)裁剪纹理的有效实时操作需要一些特殊硬件的协助,如需要自动变换纹理映射的硬件,把纹理坐标从原始虚拟空间映射到这个经裁剪的纹理空间叭
(3)裁剪纹理依赖于快速的硬盘访问以取得纹理数据;
(4)目前支持这项技术的高层系统软件只有OpenGLPerformer,并且对操作系统要求苛刻,硬件上只有其专用图形工作站才能支持。所有这些特点对于当前低端平台和低带宽环境是一种不足,其实现成本高、可移植性差限制了它的推广应用。
尽管如此,裁剪纹理的实现思想对于解决图形学中相关问题有非常大的指导意义,这种方法不仅对显示任意大范围的纹理是重要的,同时还能减少几何建模工作。裁剪纹理采用动态从大量数据上裁剪一小部分用于显示,使用了一些缓存预测算法思想提高漫游的实时性和运用环形装载模式进行数据重用等,这些方法对处理大量几何数据的显示也很重要,利用裁剪纹理的纹理数据显示算法,整体的数据流可以被轻易地以应用需要按一定大小裁剪,开发这种显示大场景几何数据LOD信息的系统是可能的,同时从2D纹理扩展到3D纹理应用也可以借鉴这一做法。