1.关于mipmap的解释
mipmap一词出自Lance Willianms 的论文<<Pyramidal Parametrics>>--1983年,mip
-> multum in parvo "在一个小城区的很多种东西"。mipmap技术使用了一些聪明的做法将图像数据打包到内存中。
OpenGL 在使用 mipmap时会自动判断当前使用的纹理贴图是那个层级,这是基于被映射物体的尺寸(以像素为单位
)决定的,通过这种做法,我们可以根据纹理贴图的细节层次(level of detail),找到当前会知道屏幕的最合适图像,如果物体变得更小,那么纹理贴图层次也会的尺寸也会减小,mipmap需要一些额外的计算和纹理存储的区域。如果我们不使用mipmap的话,纹理被映射到较小的物体上之后可能会出现闪烁现象。
在介绍OpenGL mipmap的时候,并没有讨论纹素尺寸之间的缩放参数,此外还假设mipmap的所有参数都使用了默认值。
mipmap简单来说就是一些列的纹理图像,后一个纹理图像是前一个纹理图像的1/4,知道最后一个图的像素是1*1d的时候停止。多级渐远背后的原理就是:观察者距离物体超过一定的阈值,OpenGL会使用不同的多级渐远纹理,即最适合物体的距离的那个。由于距离远,解析度不高也不会被用户注意到。
下图就是简单展示了一下渐远纹理的样子:

图中1,2,3区域距离观察者越来越远。
1.1mipmap技术解决了那些问题
- 解决了大纹理使用在小物体上的时候的闪烁问题;
当屏幕中的物体表面比使用的纹理小很多的时候,会发生闪烁的现象,mipmap解决了这个问题; - 性能问题
夹在大量内存,并对它们进行过滤处理,但屏幕只显示很少的一部分片段的时候,纹理越大,占用的内存就越多,这个问题就会越严重。
这两个问题看似可以使用同样样式的更小的纹理来解决,但是当观察者与物体距离靠近的时候,物体表面就会被渲染得更大,这样就会导致纹理不得不拉伸,从而形成了视觉模糊或者斑驳状纹理的现象;
1.2 设置纹理参数-mipmap参数
//void glTexParameteri(...); 使用这个方法设置纹理参数
//设置mip贴图基层
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_BASE_LEVEL,0);
//设置mip贴图最大层
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAX_LEVEL,0);
我们虽然可以通过设置GL_TEXTURE_BASE_LEVEL和GL_TEXTURE_MAX_LEVEL来设置那些mip层被加载到屏幕上,但是我们仍然需要使用GL_TEXTURE_MIN_LOAD 和 GL_TEXTURE_MAX_LOAD来限制已经加载的mip层的使用范围。
1.3 什么时候生成mip贴图?
只有minFilter等于下面四种模式的时候才可以生成mip贴图:
参数值 | 解释 |
---|---|
GL_ENAREST | 在mip基层上使用临近过滤 |
GL_LINEAR | 在mip基层上使用线性过滤 |
GL_NEAREST_MIPMAP_NEAREST | 在最临近的mip层,执行临近过滤(具有非常好的性能,且闪烁现象非常弱) |
GL_NEAREST_MIPMAP_LINEAR | mip层之间执行线性插补,并执行临近过滤 |
GL_LINEAR_MIPMAP_NEAREST | 在最临近的mip层使用线性过滤(常用于游戏加速,使用了高质量是线性过滤器) |
GL_LINEAR_MIPMAP_LINEAR | 在mip层之间执行线性插补,并执行线性过滤,有称为三线性mip贴图,具有最高精度 |
///设置缩小过滤方式
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,minFilter);
//判断缩小过滤方式:
if (minFilter == GL_NEAREST_MIPMAP_NEAREST ||
minFilter == GL_LINEAR_MIPMAP_NEAREST ||
minFilter == GL_LINEAR_MIPMAP_LINEAR ||
minFilter == GL_NEAREST_MIPMAP_LINEAR)
{
// 纹理生成所有的mip层 参数:1D/2D/3D
glGenerateMipmap(GL_TEXTURE_2D);
//void glGenerateMipmap(GLenum target);
// 这个函数为纹理生成一组完整的mipmap图层;
}
2. 各向异性过滤
当我们给一个几何图形纹理贴图的时候,如果它的观察视角刚好垂直于这个几何面,那么这个纹理贴图的过程是最完美的。

当观察角度倾斜时,对周围纹理进行采样,会导致一些纹理信息丢失,从而看上去会很模糊。
为了更加逼真和准确的采样,应该沿着包含纹理的平面进行延伸,如果我们进行处理纹理过滤时,考虑观察角度,那么这个方式就叫做 各向异性过滤。
在mip纹理贴图过滤模型中,或者其他所有的基本纹理过滤,我们可以应用各向异性过滤;
2.1应用各向异性过滤的步骤
-
1.查询得到支持各向异性过滤的最大数量 ,调用
glFloatv()
函数,并使用GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT参数,获得最大支持数量 -
2. 调用
glTexParameterf(...)
方法,使用GL_TEXTURE_MAX_ANISOTROPY_EXT
参数,设置各向异性过滤数据:
case 6:
//设置各向异性过滤
GLfloat fLargest;
//获取各向异性过滤的最大数量
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest);
//设置纹理参数(各向异性采样)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, fLargest);
break;
case 7:
//设置各向同性过滤,数量为1.0表示(各向同性采样)
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.0f);
break;


网友评论