opengl紋理過濾

I.紋理過濾:

當三維空間裏面的多邊形經過座標變換、投影、光柵化等過程,變成二維屏幕上的一組象素的時候,對每個象素需要到相應紋理圖像中進行採樣,這個過程就稱爲紋理過濾。

II.紋理過濾通常分爲2種情況: 
a) 紋理被縮小 GL_TEXTURE_MIN_FILTER 
比如說一個8 x 8的紋理貼到一個平行於xy平面的正方形上,最後該正方形在屏幕上只佔4 x 4的象素矩陣,這種情況下一個象素對應着多個紋理單元。
b) 紋理被放大 GL_TEXTURE_MAG_FILTER 
紋理被放大這種情況剛好跟上面相反,假如我們放大該正方形,最後正方形在屏幕上佔了一個16 x 16的象素矩陣,這樣就變成一個紋理單元對應着多個象素。

III.幾種不同的紋理過濾方式: 
1.最近點採樣 GL_NEAREST
2.線性紋理過濾(雙線性過濾)GL_LINEAR
3.mipmap紋理過濾(三線性過濾) GL_LINEAR_MIPMAP_LINEAR
4.各向異性過濾

a) 最近點採樣
最近點採樣,不進行任何過濾操作的速度最快也最簡單,只是針對每一個象素對最接近它的紋理單元進行採樣,可用於上面兩種情況。但是這種紋理過濾方法的效果最差,在屏幕顯示的圖像會顯得十分模糊。
 

b)雙線性過濾 Bilinear Interpolation 
線性過濾也比較簡單,每個象素要對最接近它的2 x 2的紋理單元矩陣進行採樣,取4個紋理單元的平均值,也可用於上面的兩種情況。這種紋理過濾方法的效果比上面的要好很多。
這是一種較好的材質影像插補的處理方式,會先找出最接近像素的四個圖素,然後在它們之間作差補效果,最後產生的結果纔會被貼到像素的位置上,這樣不會看到“馬賽克”現象。這種處理方式較適用於有一定景深的靜態影像,不過無法提供最佳品質。其最大問題在於,當三維物體變得非常小時,一種被稱爲Depth Aliasing artifacts(深度贗樣鋸齒),也不適用於移動中的物件。
 

c)三線性過濾 Trilinear Interpolation 
三線性過濾相對的比較複雜,它只能用於紋理被縮小的情況,需要先構造紋理圖像的mipmap,mip的意思是“在狹窄的地方里的許多東西”,mipmap就是對最初的紋理圖像構造的一系列分辨率減少並且預先過濾的紋理圖。對於一個8 x 8的紋理來說需要爲它構造4 x 4、2 x 2、1 x 1這三個mipmap。如果正方形被縮小到在屏幕上佔6 x 6的象素矩陣,一個象素的採樣過程就變成這樣,首先是到8 x 8的紋理圖中進行對最接近它2 x 2的紋理單元矩陣進行採樣(也就是上面的線性過濾);其次是到4 x 4的紋理圖中重複上面的過程;接着把上面兩次採樣的結果進行加權平均,得到最後的採樣數據。可以看出整個過程一共進行了三次的線性過濾,所以這種方法叫做三線性過濾,它的效果是三種紋理過濾方法裏面最好的。
這是一種更復雜材質影像插補處理方式,會用到相當多的材質影像,而每張的大小恰好會是另一張的四分之一。例如有一張材質影像是512×512個圖素,第二張就會是256×256個圖素,第三張就會是128×128個圖素等等,總之最小的一張是1×1.憑藉這些多重解析度的材質影像,當遇到景深極大的場景時(如飛行模擬),就能提供高品質的貼圖效果。一個“雙線過濾”需要三次混合,而“三線過濾”就得作七次混合處理,所以每個像素就需要多用21/3倍以上的計算時間。還需要兩倍大的存儲器時鐘帶寬。但是“三線過濾”可以提供最高的貼圖品質,會去除材質的“閃爍”效果。對於需要動態物體或景深很大的場景應用方面而言,只有“三線過濾”才能提供可接受的材質品質。

d)各向異性過濾 Anisotropic Interpolation 
各向異性過濾是最新型的過濾方法,它需要對映射點周圍方形8個或更多的像素進行取樣,獲得平均值後映射到像素點上。對於許多3D加速卡來說,採用8個以上像素取樣的各向異性過濾幾乎是不可能的,因爲它比三線性過濾需要更多的像素填充率。但是對於3D遊戲來說,各向異性過濾則是很重要的一個功能,因爲它可以使畫面更加逼真,自然處理起來也比三線性過濾會更慢。
各異向性紋理過濾不是單獨使用而是和前面所述的其他過濾方法結合一起使用的。它在取樣時候,會取8個甚至更多的像素來加以處理,所得到的質量最好。
假設Px爲紋理在x座標方向上的縮放的比例因子;Py爲紋理在y座標方向上的縮放的比例因子;Pmax爲 Px和Py中的最大值;Pmin爲Px和Py中的最小值。當Pmax/Pmin等於1時,也就是說Px等於Py,紋理的縮放是各同向的;但是如果Pmax /Pmin不等於1而是大於1,Px不等於Py,也就是說紋理在x座標方向和在y座標方向縮放的比例不一樣,紋理的縮放是各異向的,Pmax/Pmin代表了各異向的程度。
舉個例子來說,64 x 64的紋理貼到一個開始平行於xy平面的正方形上,但是正方形繞y軸旋轉60度,最後投影到屏幕上佔了16 x 32的象素矩陣。紋理在x座標方向上縮放的比例因子爲64/16等於4,在y座標方向縮放的比例因子爲64/32等於2,Pmax等於4,Pmin等於 2。縮放的各異向程度爲2。當把各異向性過濾和線性過濾結合起來的時候,應該是對最接近象素的4 x 2的紋理單元矩陣採樣才合理,因爲一個象素在x座標方向上對應了更多的紋理單元(Px > Py)。即使是紋理在一個軸方向上縮小而在另一個軸方向上放大,處理的過程也是一樣的(注意的是如果紋理在一個軸方向上縮小而在另一個軸方向上放大,OpenGL仍然把它當作是紋理被縮小的情況,將採用爲紋理縮小情況設置的過濾方法爲基本過濾方法,然後再加上各異向性過濾)。假設被貼圖的正方形最後在屏幕上佔了一個128 x 32 的象素矩陣,紋理在x座標方向上縮放的比例因子爲64/128等於0.5,在y座標方向縮放的比例因子爲64/32等於2,由於Py > Px 且 Pmax/Pmin等於4,所以當把各異向性過濾和線性過濾結合起來的時候,應該對最接近象素的2 x 8的紋理單元矩陣進行採樣。三線性過濾和各異向性過濾結合的過濾方法的步驟跟前面單獨的三線性過濾方法大致是一樣的,只是前面兩步採用了各異向性過濾和線性過濾結合的方法。
通常情況下采取線性過濾或者三線性過濾就可以得不錯的效果,但是在某些特殊的情況下,特別是把一個都是線狀條紋的紋理圖貼到一個繞x或者是y軸旋轉角度很大的多邊形上的時候,比如將人的頭髮紋理貼到構成人的頭頂的多邊形,即使是三線性過濾的效果也不能令人滿意,只有將各異向過濾方法和三線性過濾或者線性過濾的方法結合起來才能得到完美的效果。

  //用OpenGL實現支持的最大各異向程度設置最大各異向程度參數
  glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, xxx);
  // 注意:這裏的 xxx 代表 各向異性過濾 的異向程度參數
  // 你可以設置爲:4 , 8 , 16 等。這裏也可以在 InitGL() 驅動 OpenGL 函數裏寫上
  int LrgSupAni;
  glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &LrgSupAni);
  那麼 xxx 就得小於或等於 LrgSupAni。


發佈了34 篇原創文章 · 獲贊 115 · 訪問量 33萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章