Mipmap與紋理過濾


為了加快渲染速度和減少紋理鋸齒,貼圖被處理成由一系列被預先計算和優化過的圖片組成的文件,這樣的貼圖被稱為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通道信息幾乎完全喪失。一般將不帶Alpha通道的圖片壓縮成這種格式。
DXT2

壓縮比為1:4 ,使用了4bit Alpha,可以有16個Alpha值,可很好地用於Alpha通道銳利、對比強烈的半透和鏤空材質。

DXT3 壓縮比為1:4 ,使用了線形插值的4bit Alpha,特別適合Alpha通道柔和的材質,如高光掩碼材質。

DirectX Texture Tool工具也可以編輯DDS文件的DXT壓縮方式;關於DXT的更多信息可參考:DXT 圖片壓縮   

 

 

圖像重采樣插值算法簡介

算法

說明

最近相鄰插值

(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.  
    <span style= "font-family:Verdana;">void* MipData[MAX_TEXTURE_MIP_COUNT];
  2.  
    LoadMipmapFile(“Maya_Basho_A_Leaf_sm_D.dds”, &MipData);</span>


 ② 創建Mipmap紋理,並綁定數據

 

  1.  
    IDirect3DTexture9 * pMipMap;
  2.  
    // 第3個參數 5 表示從256向下生成5個Mipmap層級(含256);該參數為0表示使用D3D來生成所有層級的Mipmap
  3.  
    m_pD3DDevice->CreateTexture( 256, 256, 5, 0, D3DFMT_R8G8B8, D3DPOOL_MANAGED, &pMipMap);
  4.  
    for( INT MipIndex=0; MipIndex<5; 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紋理采樣器參數

m_pD3DDevice->SetTexture(SamplerIdx, pMipMap);
Direct3DDevice->SetSamplerState(SamplerIdx,D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
Direct3DDevice->SetSamplerState(SamplerIdx,D3DSAMP_ADDRESSV, D3DTADDRESS_MIRROR);
Direct3DDevice->SetSamplerState(SamplerIdx,D3DSAMP_ADDRESSW, D3DTADDRESS_WRAP);
Direct3DDevice->SetSamplerState(SamplerIdx,D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
Direct3DDevice->SetSamplerState(SamplerIdx,D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);
Direct3DDevice->SetSamplerState(SamplerIdx,D3DSAMP_MIPFILTER, D3DTEXF_POINT);
Direct3DDevice->SetSamplerState(SamplerIdx,D3DSAMP_MIPMAPLODBIAS, 1);// Mipmap層級向高精度偏移1個層級
Direct3DDevice->SetSamplerState(SamplerIdx,D3DSAMP_MAXANISOTROPY, 4);// 最大異性采樣閾值設置為4

紋理地址模式

 

 

紋理坐標uv的范圍為:[0, 1] x [0, 1] 。若頂點u和v大於1或小於0時,則需要用相應的紋理地址模式來尋址,以確定該頂點所應采用的紋理像素顏色值。

常用紋理地址模式有:包裹模式(Wrap)  鏡像模式(Mirror)  夾子模式(Clamp)。

技術分享

紋理映射

定義:使用uv坐標將紋理像素(texel)映射到屏幕像素(pixel)的過程。 

技術分享

 

紋理過濾

 

由於相機不一定正對着物體,以及透視投影為非正交投影,紋理並不會1:1的投影到物體表面並最終呈現到實際的屏幕像素上。

當最后呈現到屏幕中的尺寸比紋理實際尺寸大的時候,此時需要對紋理進行放大(Texture Magnification),反之需要縮小(TextureMinification)。

紋理放大采樣的時候如果不經處理,則會出現馬賽克等方塊等情況,如果紋理縮小采樣的時候不經處理,那么就會產生紋理鋸齒。因此,紋理過濾就變得非常必要。 

技術分享

從上圖像素點被縮放的程度上看,當屏幕像素(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的差別了

 

參考

http://blogs.msdn.com/b/shawnhar/archive/2009/09/14/texture-filtering-mipmaps.aspx

http://blogs.msdn.com/b/shawnhar/archive/2009/09/08/texture-filtering.aspx

http://blogs.msdn.com/b/shawnhar/archive/2009/09/24/texture-filtering-anisotropy.aspx

http://m.blog.csdn.net/blog/u013467442/44466069


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM