为了加快渲染速度和减少纹理锯齿,贴图被处理成由一系列被预先计算和优化过的图片组成的文件,这样的贴图被称为Mipmap

使用DirectX Texture Tool(DX自带工具)预生成Mipmap Chain

Original  Mip1 Mip2 Mip3 Mip4 Mip5 Mip6 Mip7 Mip8
256x256 128x128 64x64 32x32 16x16 8x8 4x4 2x2 1x1

(1)Mipmap宽高值不一定要相等,但需要为2的n次幂,最低精度为1x1

(2)从原始高精度的Mipmap宽高减半,逐级生成低精度的Mipmap层级;所有低精度层级加起来,会增加1/3存储空间的占用

① Mipmap贴图文件占用更多硬盘空间     -- 解决方法:使用dds进行压缩存储
      ② Mipmap纹理占用更多内存、显存空间

DDS文件

DDS(DirectDraw Surface):一种使用S3 Texture Compression (S3TC,sometimes also called DXTn or DXTC)算法来压缩存储Mipmap层级的数据格式,

DXTn(DXT1、DXT2、DXT3、DXT4及DXT5)算法可被GPU硬件解压缩,这也使得DDS文件被广泛用来存储纹理数据,其中DXT2与DXT4为过渡算法,用得不多。

当然,DDS也可存储不具有mipmap级别、及未压缩的像素格式的贴图。

算法 说明
DXT1

压缩比为1:8(最高),只有1bit Alpha(可选),Alpha通道信息几乎完全丧失。

每个4x4的块可以根据需要有或没有这个透明通道。不需要alpha通道时,每个块可以有四种颜色(其中两个是插值得到的);

需要alpha通道时,则只能有三种颜色,11 被保留用来描述透明的点。

一般将不带Alpha通道的图片压缩成这种格式。

DXT3

压缩比为1:4

在DXT1的基础上,增加了4bit的alpha通道(可以有16个Alpha值),每个4x4块多用了64bit来保存这些alpha通道信息

可很好地用于Alpha通道锐利、对比强烈的半透和镂空材质。

DXT5

压缩比为1:4

相对与DXT3,DXT5 对 alpha 通道的储存作了改进。它依旧用 64bit储存16个alpha 信息,但存储格式有些不同。

前面2个字节(16bit)保存了当前块的最大alpha值和最小alpha值。接下来的48bit ,每个像素占用3bit空间,刚好描述4x4个像素。

特别适合Alpha通道柔和的材质,如高光掩码材质。

DirectX Texture Tool工具也可以编辑DDS文件的DXT压缩方式;关于DXT的更多信息可参考:DXT 图片压缩

UE3的Texture2D对象

Epic Game公司在UE3中在DDS文件的基础上,开发出了Texture2D对象(如下图),用于储存贴图数据。

Texture2D对象增加了渲染相关的配置(蓝色的框)与生成Mipmap相关的配置(红色的框)。

在生成Mipmap时,Texture2D提供如下选项:

① TMGS_FromTextureGroup  // 使用LODGroup中定义的Mipmap生成算法

② TMGS_SimpleAverage  // 两次线性插值算法

③ TMGS_Sharpen0、TMGS_Sharpen1、... 、TMGS_Sharpen10 // 不同阈值的两次立方插值算法

④ TMGS_NoMipmaps  // 不生成Mipmaps层级

⑤ TMGS_LeaveExistingMips  // 使用现有的Mipmaps层级

图像重采样插值算法简介

算法

说明

最近相邻插值

(Nearest Neighbour Interpolation)

优点是计算量很小,算法简单,运算速度较快。但它仅使用离待测采样点最近的像素的颜色值作为该采样点的颜色值,而没考虑其他相邻像素点的影响,

因而重新采样后颜色值有明显的不连续性,图像质量损失较大,会产生明显的马赛克和锯齿现象。

两次线性插值

(Bilinear Interpolation)

2x2 average

average four pixels

计算量稍大,基本克服了最近相邻插值算法颜色值不连续的特点,因为它考虑了待测采样点周围四个直接邻点对该采样点的相关性影响。

但是,此方法仅考虑待测样点周围四个直接邻点颜色值的影响, 而未考虑到各邻点间颜色值变化率的影响, 因此具有低通滤波器的性质,

从而导致缩放后图像的高频分量受到损失, 图像边缘在一定程度上变得较为模糊。

两次立方插值

(Bicubic Interpolation)

8x8 [with sharpening]

4x4 filter [with sharpening]

计算量最大,算法也最为复杂的。在几何运算中,两次线性插值算法的平滑作用可能会使图像的细节产生退化,在进行放大处理时,这种影响更为明显。

在其他应用中,两次线性插值算法的斜率不连续性会产生不希望的结果。两次立方插值算法不仅考虑到周围四个直接相邻像素点颜色值的影响,还考虑到它们颜色值变化率的影响。

因此克服了前两种方法的不足之处,能够产生比两次线性插值更为平滑的边缘,计算精度很高,处理后的图像像质损失最少,效果是最佳的。

Adobe PhotoShop CS6在图像缩放时,提供了以上三种算法供用户选择:

D3D9中使用Mipmap

① 载入Mipmap贴图文件到内存

  1. void* MipData[MAX_TEXTURE_MIP_COUNT];
  2. LoadMipmapFile(“Maya_Basho_A_Leaf_sm_D.dds”, &MipData);

② 创建Mipmap纹理,并绑定数据

  1. IDirect3DTexture9 * pMipMap;
  2. // 第3个参数 5 表示从256向下生成5个Mipmap层级(含256);该参数为0表示使用D3D来生成所有层级的Mipmap
  3. m_pD3DDevice->CreateTexture(, , , , D3DFMT_R8G8B8, D3DPOOL_MANAGED, &pMipMap);
  4. for( INT MipIndex=; MipIndex<; MipIndex++ )
  5. {
  6. D3DLOCKED_RECT LockedRect;
  7. pMipMap->LockRect( MipIndex, &LockedRect, NULL, D3DLOCK_NOSYSLOCK );
  8. GetTexDataFromMipData( MipData, MipIndex, LockedRect.pBits, LockedRect.Pitch );
  9. pTexture->UnlockRect( MipIndex );
  10. }

③ 设置Mipmap纹理采样器参数

  1. m_pD3DDevice->SetTexture(SamplerIdx, pMipMap);
  2. Direct3DDevice->SetSamplerState(SamplerIdx,D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
  3. Direct3DDevice->SetSamplerState(SamplerIdx,D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR);
  4. Direct3DDevice->SetSamplerState(SamplerIdx,D3DSAMP_ADDRESSW, D3DTADDRESS_WRAP);
  5. Direct3DDevice->SetSamplerState(SamplerIdx,D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
  6. Direct3DDevice->SetSamplerState(SamplerIdx,D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);
  7. Direct3DDevice->SetSamplerState(SamplerIdx,D3DSAMP_MIPFILTER, D3DTEXF_POINT);
  8. Direct3DDevice->SetSamplerState(SamplerIdx,D3DSAMP_MIPMAPLODBIAS, );// Mipmap层级向高精度偏移1个层级
  9. Direct3DDevice->SetSamplerState(SamplerIdx,D3DSAMP_MAXANISOTROPY, );// 最大异性采样阈值设置为4

纹理地址模式

UE的纹理坐标的原点在左上角像素的中心,u轴向右  v轴向下,范围为:[0, 1] x [0, 1] 。若顶点u和v大于1或小于0时,则需要用相应的纹理地址模式来寻址,以确定该顶点所应采用的纹理像素颜色值。

常用纹理地址模式有:包裹模式(Wrap)  镜像模式(Mirror)  夹子模式(Clamp)。

注1:UE3、UE4的纹理坐标与D3D10+坐标是一致的

注2:Unity的纹理坐标与OpenGL的坐标是一致的,坐标原点为左下角像素的中心   u轴向右 v轴向上

注3:D3D9的纹理坐标原点为左上角像素的左上角   u轴向右  v轴向下

纹理映射

定义:使用uv坐标将纹理像素(texel)映射到屏幕像素(pixel)的过程。

纹理过滤

由于相机不一定正对着物体,以及透视投影为非正交投影,纹理并不会1:1的投影到物体表面并最终呈现到实际的屏幕像素上。

当最后呈现到屏幕中的尺寸比纹理实际尺寸大的时候,此时需要对纹理进行放大(Texture Magnification),反之需要缩小(Texture Minification)。

纹理放大采样的时候如果不经处理,则会出现马赛克等方块等情况,如果纹理缩小采样的时候不经处理,那么就会产生纹理锯齿。因此,纹理过滤就变得非常必要。

从上图像素点被缩放的程度上看,当屏幕像素(pixel):纹理像素(texel)为n:1时,则进行纹理放大;为1:n时,则进行纹理缩小。 注:n>1

纹理过滤算法

各向同性:屏幕像素(pixel)在u、v方向上使用相同精度纹理像素(texel)

各向异性:屏幕像素(pixel)在u、v方向上使用不同精度纹理像素(texel)

MIPFILTER说明

① 为D3DTEXF_NONE,表示不使用MipMap

② 为D3DTEXF_POINT,在一层Mipmap进行纹理采样

③ 为D3DTEXT_LINEAR,在两层Mipmap进行纹理采样,然后在两层之间做线性融合,因此在不同层级的Mipmap之间有更好地过度

Mipmap层级选择 -- 各向同性

① 计算得到映射比【屏幕像素(pixel):纹理像素(texel)】最小P(min)的屏幕像素点A

② 计算像素点A的uv在屏幕空间的对应方向,并沿着该方向得到屏幕像素区域的最小外接平行四边形MNOP

③ 计算n=Min{m=x*P(min)(u), n=y*P(min)(v)}   注:x、y为平行四边形MNOP的u、v对应方向上的边长;m、n为u、v方向的纹理像素值

④ 通过n<=h && Min{h1, h2, ...}条件,得到MIPFILTER=D3DTEXF_POINT的Mipmap层级L(上图中为: 64)

⑤ 若MIPFILTER=D3DTEXF_LINEAR,除了选择层级L外,还要选择L低一级的Mipmap层级(上图中为: 32)

Mipmap层级选择 -- 各向异性

① 计算得到映射比【屏幕像素(pixel):纹理像素(texel)】最大P(max)的屏幕像素点A

② 计算像素点A的uv在屏幕空间的对应方向,并沿着该方向得到屏幕像素区域的最小外接平行四边形MNOP

③ 计算m=Max{m=x*P(max)(u), n=y*P(max)(v)}   注:x、y为平行四边形MNOP的u、v对应方向上的边长;m、n为u、v方向的纹理像素值

④ 通过m<=w && Min{w1, w2, ...}条件,得到MIPFILTER=D3DTEXF_POINT的Mipmap层级L(上图中为: 256)

⑤ 若MIPFILTER=D3DTEXF_LINEAR,除了选择层级L外,还要选择L低一级的Mipmap层级(上图中为: 128)

各向异性纹理采样(以MIPFILTER=D3DTEXF_POINT为例)

① 根据上面“Mipmap层级选择 -- 各向异性”的规则,得到Mipmap层级L: 256

② 计算任意像素点K的uv在屏幕空间的对应方向,并沿着该方向得到屏幕像素区域的最小外接平行四边形MNOP

③ 分别计算uv方向的纹理像素值 m=x*P(k)(u), n=y*P(k)(v)   注:x、y为平行四边形MNOP的u、v对应方向上的边长

④ 分别计算S(u)=Min{MaxAnisotropy, L/m},S(v)=Min{MaxAnisotropy, L/n}

⑤ 对S(u),S(v)进行四舍五入取整 (上图中为: S(u)=2 S(v)=4)

⑥ 屏幕像素K对应纹理像素点所在的2x4的区域内采样,并线性插值计算屏幕像素K的颜色值

最大MaxAnisotropy阈值

(1) 使用DirectX Caps Viewer查看显卡的MaxAnisotropy阈值

(2) 另外要注意控制面板中的显卡全局设置(① 是否由3D应用程序决定  ②若由显卡决定,看看MaxAnisotropy设置大小)

不同MaxAnisotropy效果对比

MaxAnisotropy设置得越大,远处的画面细节保留得越多(上图中离视点越远的地方,各向异性程度越高)

常用的纹理过滤参数组合

过滤方式

MinFilter

MagFilter

MipFilter

采样数

Point(最近点采样)

D3DTEXF_POINT

D3DTEXF_POINT D3DTEXF_POINT 1

Bilinear(双线性插值)

D3DTEXF_LINEAR

D3DTEXF_LINEAR D3DTEXF_POINT 4

Trilinear(三线性插值)

D3DTEXF_LINEAR D3DTEXF_LINEAR D3DTEXF_LINEAR 8

AnisotropicPoint(各向异性)

D3DTEXF_ANISOTROPIC

D3DTEXF_LINEAR D3DTEXF_POINT 4 x n

AnisotropicLinear(各向异性)

D3DTEXF_ANISOTROPIC D3DTEXF_LINEAR D3DTEXF_LINEAR 8 x n

① 采样数可以反映出算法的复杂度:采样数越大,耗费的计算越多

② Point、Bilinear、Trilinear画面效果基本差不多;细看的话,Trilinear > Bilinear > Point,Trilinear在Mipmap层级间过渡更自然平滑些

③ AnisotropicLinear效果最好,在Mipmap层级间过渡方面要好于AnisotropicPoint,不过基本上看不出来AnisotropicPoint与AnisotropicLinear的差别了

参考

Texture filtering: mipmaps

Texture filtering

Texture filtering: anisotropy

各项异性滤波简介Anisotropic Filtering(AF)

Mipmap与纹理过滤的更多相关文章

  1. 纹理过滤模式中的Bilinear、Trilinear以及Anistropic Filtering

    1. 为什么在纹理采样时需要texture filter(纹理过滤). 我们的纹理是要贴到三维图形表面的,而三维图形上的pixel中心和纹理上的texel中心并不一至(pixel不一定对应textur ...

  2. Android OpenGL ES(七)----理解纹理与纹理过滤

    1.理解纹理 OpenGL中的纹理能够用来表示图像.照片,甚至由一个数学算法生成的分形数据.每一个二维的纹理都由很多小的纹理元素组成.它们是小块的数据,类似于我们前面讨论过的片段和像素.要使用纹理,最 ...

  3. OpenGL(二十三) 各向异性纹理过滤

    如果使用一般的纹理过滤,当观察方向跟模型表面不是相互垂直的的情况下,会出现纹理信息的丢失,表现为图像看上去比较模糊,如下图所示,远处场景的细节信息很差: 针对这种情况,可以采用同向异性过滤的方式处理纹 ...

  4. 【转】OpenGL超级宝典笔记——纹理映射Mipmap

    原文地址 http://my.oschina.net/sweetdark/blog/177812 , 感谢作者,若非法转载请联系本人. 目录[-] Mipmapping Mipmap过滤 构建Mip层 ...

  5. Directx11学习笔记【十七】纹理贴图

    本文由zhangbaochong原创,转载请注明出处http://www.cnblogs.com/zhangbaochong/p/5596180.html 在之前的例子中,我们实现了光照和材质使得场景 ...

  6. 一文详解 纹理采样与Mipmap纹理——构建山地渲染效果

    在开发一些相对较大的场景时,例如:一片铺满相同草地纹理的丘陵地形,如果不采用一些技术手段,就会出现远处的丘陵较近处的丘陵相比更加的清晰的视觉效果,而这种效果与真实世界中近处的物体清晰远处物体模糊的效果 ...

  7. OpenGL: 纹理采样 texture sample

    Sampler (GLSL) Sampler通常是在Fragment shader(片元着色器)内定义的,这是一个uniform类型的变量,即处理不同的片元时这个变量是一致不变的.一个sampler和 ...

  8. 【转】MipMap

    原文地址http://www.cppblog.com/wc250en007/archive/2011/08/06/152653.html 首先从MIPMAP的原理说起,它是把一张贴图按照2的倍数进行缩 ...

  9. MipMap

    MipMap 首先从MIPMAP的原理说起,它是把一张贴图按照2的倍数进行缩小.直到1X1.把缩小的图都存储起来.在渲染时,根据一个像素离眼睛为之的距离,来判断从一个合适的图层中取出texel颜色赋值 ...

随机推荐

  1. shell正则表达式

    正则表达式 主要用于字符串的模式分割/匹配/查找及替换操作. 正则表达式与通配符 通配符 正则与通配符的区别: 正则匹配字符串,通配符匹配文件名. 正则--->包含匹配 通配符--->完全 ...

  2. mfc+vtk

    MFC中view类主要处理显示视图,doc类处理文档,mainframe主要为整个窗口的和工程的设置管理.由此,VTK与MFC联合编程时,需要主要的是数据操作,以及显示要很好的与MFC中的结构结合,做 ...

  3. 在Unity中使用UGUI修改Mesh绘制几何图形

    在商店看到这样一个例子,表示很有兴趣,他们说是用UGUI做的.我想,像这种可以随便变形的图形,我第一个就想到了网格变形. 做法1: 细心的朋友应该会发现,每个UGUI可见元素,都有一个‘Canvas ...

  4. rcu机制

    转载自:再谈Linux内核中的RCU机制-MagicBoy2010-ChinaUnix博客 http://blog.chinaunix.net/uid-23769728-id-3080134.html ...

  5. Apache服务器安装过程及问题的解决(for windows system32bit)

    在使用Hbuilder设计网站时,在制作本站搜索时,用到了Php文件,而Hbuilder的内置web服务器不支持php的解析, 所以需要安装配置外部服务器,有多个选择,我安装的apache服务器,并遇 ...

  6. JavaScript - 正则表达之二

    正则表达式的大致匹配过程是:依次拿出表达式和文本中的字符比较,如果每一个字符都能匹配,则匹配成功:一旦有匹配不成功的字符则匹配失败. 正则表达式通常用于在文本中查找匹配的字符串.Python里数量词默 ...

  7. Android五岁了

    今日(2013-9-24),谷歌开源系统Android迎来了它5岁的生日. 时间过得真快啊!当时的android并不被人看好,而现在的android已经成为了全球最大的智能手机操作系统.而现在的诺基亚 ...

  8. vue2.0实战

    学了几周的vue2.0,终于有时间去做一个应用了. 为了全面联系相关知识,所以用到了vue-router,以及作者最新推荐的axios,组件库用的是饿了么的mint-ui2.0. 项目构建使用官方vu ...

  9. OC与c混编实现Java的String的hashcode()函数

    首先,我不愿意大家需要用到这篇文章里的代码,因为基本上你就是被坑了. 起因:我被Java后台人员坑了一把,他们要对请求的参数增加一个额外的字段,字段的用途是来校验其余的参数是否再传递过程中被篡改或因为 ...

  10. 转载自lanceyan: 一致性hash和solr千万级数据分布式搜索引擎中的应用

    一致性hash和solr千万级数据分布式搜索引擎中的应用 互联网创业中大部分人都是草根创业,这个时候没有强劲的服务器,也没有钱去买很昂贵的海量数据库.在这样严峻的条件下,一批又一批的创业者从创业中获得 ...