也称多级纹理。

  • 需求一:纹理缩放
    • 程序中经常会出现纹理缩放的需求,可以通过纹素过滤模式来处理适当范围的纹理缩放,但是如果缩放倍数过大,则仍然会出现失真。
  • 需求二:分辨率适配
    • 移动设备分辨率差异巨大,高分辨率设备使用低分辨率资源,或者低分辨率设备使用高分辨率资源都可能会出现图像失真,也会造成性能的浪费或者资源的浪费。

1983年,Lance Williams在他的论文《Pyramidal parametrices(金字塔式参数)》中提出了多级纹理(Mipmapping)的概念,多级纹理通过产生一个图像金字塔来适配不同分辨率的缩放,每级纹理都是预先生成(可以是程序外通过工具生成),所以并不会影响渲染性能。
多级纹理是一种高效的纹理采样技术,使图形应用程序不通过增加几何级复杂度来增加场景的视觉复杂度,不通过图元操作就可以达到更真实的画面。
多级纹理的级数由原始纹理的尺寸决定,原始纹理级数(level)是0,每一级是上一级尺寸的1/2,理论上每一级可以是上一级纹理的GL_LINEAR采样,多级纹理比原始纹理多占用1/3的内存空间。
多级纹理说白了就是在渲染前提前生成了不同分辨率级别的纹理,根据论文理论,OpenGL标准也提出了针对性的解决方案(glGenerateMipmap)。

一、纹素过滤模式

多级纹理相对于普通单张纹理多了4中选择,详细见:https://www.yuque.com/tvvhealth/cs/hfkcft#lHDGn

二、多级纹理上传

多级纹理的上传比普通单张纹理要复杂一点,详细见:https://www.yuque.com/tvvhealth/cs/hfkcft#N8Tcx

三、多级纹理生成

1、动态生成(程序内生成)

通过GL函数glGenerateMipMap生成。

  1. void Texture2D::generateMipmap() {
  2. // GLES2.0不要求原理纹理尺寸必须是POT,但是POT在使用过滤模式时有限制,
  3. // cocos限制只有POT纹理可以动态生成多级纹理。
  4. CCASSERT(_pixelsWide == ccNextPOT(_pixelsWide) &&
  5. _pixelsHigh == ccNextPOT(_pixelsHigh),
  6. "Mipmap texture only works in POT textures");
  7. GL::bindTexture2D( _name ); // glactiveTexture(GL_TEXTURE0 + textureUnit);
  8. // glBindTexture(GL_TEXTURE_2D, _name);
  9. glGenerateMipmap(GL_TEXTURE_2D); // 为纹理ID为_name的纹理生成多级纹理。
  10. _hasMipmaps = true;
  11. ......
  12. }

cocos默认不会生成多级纹理,在上传纹理数据的时候手动调用Texture2D::generateMipmap才能生效,这样无需提供多级纹理图片减少程序包大小,但是增大了内存占用一定程度上影响性能。

2、工具生成(程序外生成)

可以借助外部工具(PvrTexTool)生成多级纹理图片,可以减少程序生成多级纹理的计算量,但是会增加图片文件大小。
image.png