紋理過濾(Texture filtering)


在計算機圖形學中,紋理過濾或者說紋理平滑是在紋理採樣中使採樣結果更加合理,以減少各種人爲產生的穿幫現象的技術。紋理過濾分爲放大過濾和縮小過濾兩種類型。對應於這兩種類型,紋理過濾可以是通過對稀疏紋理插值進行填充的重構過濾(需要放大)或者是需要的紋理尺寸低於紋理本身的尺寸時(需要縮小)的一種抗鋸齒過濾。簡單來講,紋理過濾就是用來描述在不同形狀、大小、角度和縮放比的情況下如何應用紋理。根據使用的過濾算法的不同,會得到不同等級的模糊、細節程度、空域鋸齒、時域鋸齒和塊狀結果。根據使用環境的不同,過濾可能是在軟件或者專用硬件中完成,也可能是在軟件和專用硬件中共同完成。對用大多數常見的可交互圖形應用,現代的紋理過濾是使用專用的硬件進行完成。這些硬件通過內存緩衝和預提取技術優化了內存讀寫,並且實現了多種可供用戶和開發者選擇的過濾算法。

有多種紋理過濾方法,不同的方法在計算複雜度、內存帶寬和圖像質量上分別有不同的權衡。

爲什麼需要紋理過濾

對於任意的3D表面在紋理映射過程中,需要進行紋理查找來找到屏幕上的一個像素對應於紋理上的哪個位置。紋理映射的過程會根據目標點離相機的遠近,佔用屏幕上不同大小的範圍的像素,例如一個三角面在距離相機20m時佔用100個屏幕像素,當三角面離相機更遠時會看起來更小,此時可能佔用20個屏幕像素,但是在兩種情況下這個三角面使用的紋理貼圖的大小是不變的。換句話說,由於紋理化表面可以相對於觀察者處於任意距離和朝向,因此一個像素通常不直接對應於一個紋理像素。必須應用某種形式的濾波來確定像素的最佳顏色。濾波不足或不正確將在圖像中顯示爲僞像(圖像中的錯誤),例如“阻塞”,鋸齒狀或閃爍。

屏幕的一個像素與它在對應的紋素之間可以存在不同類型的對應關係。這取決於紋理化表面相對於觀察者的位置,並且在每種情況下都需要不同形式的過濾。給定映射到世界中的正方形表面的正方形紋理,在某個觀看距離處,一個屏幕像素的大小與一個紋理像素完全相同。當觀察者靠近時,紋素(紋理上一個顏色點)大小大於屏幕像素,需要適當放大 - 這一過程稱爲紋理放大。更遠時,每個紋素大小小於一個像素,因此一個像素覆蓋多個紋素。在這種情況下,必須通過紋理縮小來基於所覆蓋的紋理元素拾取適當的顏色。圖形API如OpenGL允許程序員爲縮小和放大過濾設置不同的過濾方案。

注意,即使在像素和紋素是完全相同的大小的情況下,一個像素也不一定完全匹配一個紋素。它們可能未對齊或發生旋轉,一個像素可能覆蓋多達四個相鄰紋素的部分。因此,仍然需要某種形式的過濾。

Mipmapping是一種標準技術,用於保存紋理縮小過程中所需的一些過濾工作。它對緩存一致性也非常有益- 沒有它,從遠距離紋理採樣期間的存儲器訪問模式將表現出極差的局部性,即使沒有執行濾波也會對性能產生不利影響。

在紋理放大時,需要爲任何像素查找的紋素的數量總是四個或更少; 然而,在縮小時,隨着紋理多邊形移動得更遠,潛在地整個紋理可能落入單個像素中。這將需要閱讀所有它的紋素和它們的值組合以正確地確定像素顏色,這是一個非常昂貴的操作。Mipmapping通過預先過濾紋理並將其以較小的尺寸存儲到單個像素來避免這種情況。隨着紋理表面移動得更遠,應用的紋理切換到預過濾的較小尺寸。mipmap的不同大小被稱爲“級別”,級別0是最大的級別(最接近觀看者),並且隨着距離增加,對應要增加mipmap等級。

過濾方法

下面列出了幾種最常見的過濾方法,按照順序,越靠後的運算開銷越大,但採樣結果效果也更好。

最近點插值法(Nearest-neighbor interpolation )

最近點插值法是最簡單的紋理過濾方法 — 使用最接近採樣點紋素作爲採樣結果的顏色。 簡單的代價就是會產生很多人爲現象 - 在放大觀察時會有明顯色塊(馬賽克),而縮小時會有閃爍和鋸齒現象。這種方法在放大的情況下非常快,但是在縮小時開銷卻極高,因爲屏幕上相鄰的像素點,可能對應於紋理上距離很遠的兩個點,而這會破壞紋理採樣時的內存連續性,導致L1或者L2緩存的命中率極低,使得紋理採樣性能大大降低。
在這裏插入圖片描述
如上圖可以看到大量的噪點,這些噪點在運行時則會表現爲閃爍,因爲噪點基本是隨機的

最近點插值+mipmap的方式

這種方式在最近點插值的基礎上,引入了mipmap,當距離相機很近時,使用miplevel0,此時和最近點插值完全一樣。當距離下相機很遠時,使用更高的miplevel等級,此時使用最近點插值採樣更小尺寸的紋理。因此可以緩解縮小時的閃爍和鋸齒現象,並且能夠充分利用紋理採樣時的內存連續性,使得紋理採樣性能提高。但是在紋理放大時,不能解決產生的色塊現象。
在這裏插入圖片描述

加了mipmap之後可以看到噪點消失,但是遠處紋理明顯模糊,而且不同mipmap過渡處有明顯分界,而近處的紋理有明顯鋸齒

線性過濾+mipmap

OpenGL和其他圖形API提供在單獨的mipmap層級的貼圖上進行最近點採樣,但是會對兩個相鄰的mipmap等級的採樣結果進行插值,作爲最終結果。該方法很少使用

雙線性過濾(Bilinear filtering)

雙線性過濾對於鋸齒問題會有一個很明顯的提升。該方法中,採樣目標點附近的4個紋素,並且根據權重(距離中心點的距離)進行加權平均。這種方法使得放大紋理時的色塊現象得以消失,因爲此時兩個相鄰像素之間是平滑過度的。當縮小紋理時可以結合mipmap進行使用,儘管當縮小很多時,依然會有和最近點過濾方法一樣的鋸齒和閃爍現象,但是對於大部分合理的縮小比例,可以作爲一種開銷較少的有硬件加速的紋理超採樣方案。
在這裏插入圖片描述

相比最近點採樣,可以看到近處紋理空間的鋸齒明顯消失,但是不同mipmap等級見的分界依然明顯

三線性過濾(Trilinear filtering)

三線性過濾是對雙線性過濾中當紋理距離相機的距離剛好處於兩個mipmap等級的交界處時的明顯的一個過渡現象的解決方案。通過對兩個相鄰的mipmap等級的紋理進行雙線性過濾採樣,並對兩個採樣結果線性插值得到最終的顏色。這樣當紋理到相機的距離逐漸增加時,可以得到平滑的一個過渡,而不是突兀的變化。當然,對於足夠近的紋理,因爲使用miplevel0這個等級,因此和雙線性過濾完全一致。
在這裏插入圖片描述

三線性過濾解決了mipmap過渡中的分界問題,但是對角方向上的紋理依然很奇怪,並且異常模糊

各向異性過濾(Anisotropic filtering)

到目前爲止我們討論的都是各向同性過濾方法,也就是說在紋理採樣時,不考慮紋理的xy軸與屏幕的xy軸的角度,認爲在任何角度時採樣結果都是應該一致的(各向同性)。事實上,各向異性過濾是當前消費級顯卡中的最高質量的過濾方法。各向同性方案只使用了正方形的mipmap來應用於雙線性或三線性紋理過濾(各向同性是指在所有方向上都相同,用來描述所有的mipmap貼圖都是方形而不是在某一個軸向上有壓縮的長方形或者其他形狀)。

在這裏插入圖片描述

上圖各向異性mipmap圖片存儲模式(左),和普通mipmap存儲模式

當一個物體的表面和相機有很大的夾角時,紋理在屏幕上的對應填充區域就不是方形的。例如一個地板,距離相機遠的地方,填充區域的寬高是不對等的,此時方形的紋理貼圖就不是很合適了,此時就會導致模糊或者閃爍或者兩者皆有。各向異性過濾通過採樣一個非方形紋理解決了這個問題。

在這裏插入圖片描述

使用各向異性過濾之後,紋理清晰度得到了很大的提升

在這裏插入圖片描述

上圖三線性過濾和各向異性過濾的區別,可以看到遠處的地面明顯清晰很多。

其他紋理過濾方法

其他紋理過濾方法,因爲硬件支持不廣泛,很多算法中使用的是軟件實現,因此Unity引擎默認沒有支持,這裏列舉如下,歡迎補充:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章