在計算機圖形學中,紋理過濾或者說紋理平滑是在紋理采樣中使采樣結(jié)果更加合理,以減少各種人為產(chǎn)生的穿幫現(xiàn)象的技術(shù)。紋理過濾分為放大過濾和縮小過濾兩種類型。對應于這兩種類型,紋理過濾可以是通過對稀疏紋理插值進行填充的重構(gòu)過濾(需要放大)或者是需要的紋理尺寸低于紋理本身的尺寸時(需要縮小)的一種抗鋸齒過濾。
簡單來講,紋理過濾就是用來描述在不同形狀、大小、角度和縮放比的情況下如何應用紋理。根據(jù)使用的過濾算法的不同,會得到不同等級的模糊、細節(jié)程度、空域鋸齒、時域鋸齒和塊狀結(jié)果。根據(jù)使用環(huán)境的不同,過濾可能是在軟件或者專用硬件中完成,也可能是在軟件和專用硬件中共同完成。對用大多數(shù)常見的可交互圖形應用,現(xiàn)代的紋理過濾是使用專用的硬件進行完成。這些硬件通過內(nèi)存緩沖和預提取技術(shù)優(yōu)化了內(nèi)存讀寫,并且實現(xiàn)了多種可供用戶和開發(fā)者選擇的過濾算法。
有多種紋理過濾方法,不同的方法在計算復雜度、內(nèi)存帶寬和圖像質(zhì)量上分別有不同的權(quán)衡。
什么是紋理過濾器?
紋理過濾器是一種用于計算圖像紋理的算法,它通過對圖像進行計算和處理,可以在游戲中減少紋理鋸齒、失真和模糊等問題。紋理過濾器主要分為幾種類型,包括最鄰近、雙線性、三線性和各向異性過濾器等等。
紋理過濾器對游戲的影響:
1. 提高畫質(zhì)
紋理過濾器可以有效地減少游戲中出現(xiàn)的鋸齒和模糊等問題,使得游戲圖像更加清晰細膩,從而提高游戲的畫質(zhì)。
2. 增強穩(wěn)定性
通過使用紋理過濾器,可以在游戲中減少圖像的閃爍和失真現(xiàn)象,從而增強游戲的穩(wěn)定性。
3. 減少GPU的使用
使用紋理過濾器可以有效地減少GPU的負擔,提高游戲的運行效率和性能表現(xiàn)。
為什么需要紋理過濾?
對于任意的3D表面在紋理映射過程中,需要進行紋理查找來找到屏幕上的一個像素對應于紋理上的哪個位置。紋理映射的過程會根據(jù)目標點離相機的遠近,占用屏幕上不同大小的范圍的像素,例如一個三角面在距離相機20m時占用100個屏幕像素,當三角面離相機更遠時會看起來更小,此時可能占用20個屏幕像素,但是在兩種情況下這個三角面使用的紋理貼圖的大小是不變的。換句話說,由于紋理化表面可以相對于觀察者處于任意距離和朝向,因此一個像素通常不直接對應于一個紋理像素。必須應用某種形式的濾波來確定像素的最佳顏色。濾波不足或不正確將在圖像中顯示為偽像(圖像中的錯誤),例如“阻塞”,鋸齒狀或閃爍。
屏幕的一個像素與它在對應的紋素之間可以存在不同類型的對應關(guān)系。這取決于紋理化表面相對于觀察者的位置,并且在每種情況下都需要不同形式的過濾。給定映射到世界中的正方形表面的正方形紋理,在某個觀看距離處,一個屏幕像素的大小與一個紋理像素完全相同。當觀察者靠近時,紋素(紋理上一個顏色點)大小大于屏幕像素,需要適當放大 - 這一過程稱為紋理放大。更遠時,每個紋素大小小于一個像素,因此一個像素覆蓋多個紋素。在這種情況下,必須通過紋理縮小來基于所覆蓋的紋理元素拾取適當?shù)念伾?。圖形API如OpenGL允許程序員為縮小和放大過濾設(shè)置不同的過濾方案。
注意,即使在像素和紋素是完全相同的大小的情況下,一個像素也不一定完全匹配一個紋素。它們可能未對齊或發(fā)生旋轉(zhuǎn),一個像素可能覆蓋多達四個相鄰紋素的部分。因此,仍然需要某種形式的過濾。
Mipmapping是一種標準技術(shù),用于保存紋理縮小過程中所需的一些過濾工作。它對緩存一致性也非常有益- 沒有它,從遠距離紋理采樣期間的存儲器訪問模式將表現(xiàn)出極差的局部性,即使沒有執(zhí)行濾波也會對性能產(chǎn)生不利影響。
在紋理放大時,需要為任何像素查找的紋素的數(shù)量總是四個或更少; 然而,在縮小時,隨著紋理多邊形移動得更遠,潛在地整個紋理可能落入單個像素中。這將需要閱讀所有它的紋素和它們的值組合以正確地確定像素顏色,這是一個非常昂貴的操作。Mipmapping通過預先過濾紋理并將其以較小的尺寸存儲到單個像素來避免這種情況。隨著紋理表面移動得更遠,應用的紋理切換到預過濾的較小尺寸。mipmap的不同大小被稱為“級別”,級別0是最大的級別(最接近觀看者),并且隨著距離增加,對應要增加mipmap等級。
過濾方法
下面列出了幾種最常見的過濾方法,按照順序,越靠后的運算開銷越大,但采樣結(jié)果效果也更好。
最近點插值法(Nearest-neighbor interpolation )
最近點插值法是最簡單的紋理過濾方法 — 使用最接近采樣點紋素作為采樣結(jié)果的顏色。簡單的代價就是會產(chǎn)生很多人為現(xiàn)象 - 在放大觀察時會有明顯色塊(馬賽克),而縮小時會有閃爍和鋸齒現(xiàn)象。這種方法在放大的情況下非??欤窃诳s小時開銷卻極高,因為屏幕上相鄰的像素點,可能對應于紋理上距離很遠的兩個點,而這會破壞紋理采樣時的內(nèi)存連續(xù)性,導致L1或者L2緩存的命中率極低,使得紋理采樣性能大大降低。
最近點插值+mipmap的方式
這種方式在最近點插值的基礎(chǔ)上,引入了mipmap,當距離相機很近時,使用miplevel0,此時和最近點插值完全一樣。當距離下相機很遠時,使用更高的miplevel等級,此時使用最近點插值采樣更小尺寸的紋理。因此可以緩解縮小時的閃爍和鋸齒現(xiàn)象,并且能夠充分利用紋理采樣時的內(nèi)存連續(xù)性,使得紋理采樣性能提高。但是在紋理放大時,不能解決產(chǎn)生的色塊現(xiàn)象。
加了mipmap之后可以看到噪點消失,但是遠處紋理明顯模糊,而且不同mipmap過渡處有明顯分界,而近處的紋理有明顯鋸齒
線性過濾+mipmap
OpenGL和其他圖形API提供在單獨的mipmap層級的貼圖上進行最近點采樣,但是會對兩個相鄰的mipmap等級的采樣結(jié)果進行插值,作為最終結(jié)果。該方法很少使用
雙線性過濾(Bilinear filtering)
雙線性過濾對于鋸齒問題會有一個很明顯的提升。該方法中,采樣目標點附近的4個紋素,并且根據(jù)權(quán)重(距離中心點的距離)進行加權(quán)平均。這種方法使得放大紋理時的色塊現(xiàn)象得以消失,因為此時兩個相鄰像素之間是平滑過度的。當縮小紋理時可以結(jié)合mipmap進行使用,盡管當縮小很多時,依然會有和最近點過濾方法一樣的鋸齒和閃爍現(xiàn)象,但是對于大部分合理的縮小比例,可以作為一種開銷較少的有硬件加速的紋理超采樣方案。
相比最近點采樣,可以看到近處紋理空間的鋸齒明顯消失,但是不同mipmap等級間的分界依然明顯
三線性過濾(Trilinear filtering)
三線性過濾是對雙線性過濾中當紋理距離相機的距離剛好處于兩個mipmap等級的交界處時的明顯的一個過渡現(xiàn)象的解決方案。通過對兩個相鄰的mipmap等級的紋理進行雙線性過濾采樣,并對兩個采樣結(jié)果線性插值得到最終的顏色。這樣當紋理到相機的距離逐漸增加時,可以得到平滑的一個過渡,而不是突兀的變化。當然,對于足夠近的紋理,因為使用miplevel0這個等級,因此和雙線性過濾完全一致。
三線性過濾解決了mipmap過渡中的分界問題,但是對角方向上的紋理依然很奇怪,并且異常模糊
各向異性過濾(Anisotropic filtering)
到目前為止我們討論的都是各向同性過濾方法,也就是說在紋理采樣時,不考慮紋理的xy軸與屏幕的xy軸的角度,認為在任何角度時采樣結(jié)果都是應該一致的(各向同性)。事實上,各向異性過濾是當前消費級顯卡中的最高質(zhì)量的過濾方法。各向同性方案只使用了正方形的mipmap來應用于雙線性或三線性紋理過濾(各向同性是指在所有方向上都相同,用來描述所有的mipmap貼圖都是方形而不是在某一個軸向上有壓縮的長方形或者其他形狀)。
當一個物體的表面和相機有很大的夾角時,紋理在屏幕上的對應填充區(qū)域就不是方形的。例如一個地板,距離相機遠的地方,填充區(qū)域的寬高是不對等的,此時方形的紋理貼圖就不是很合適了,此時就會導致模糊或者閃爍或者兩者皆有。各向異性過濾通過采樣一個非方形紋理解決了這個問題。
使用各向異性過濾之后,紋理清晰度得到了很大的提升
上圖三線性過濾和各向異性過濾的區(qū)別,可以看到遠處的地面明顯清晰很多。
其他紋理過濾方法
其他紋理過濾方法,因為硬件支持不廣泛,很多算法中使用的是軟件實現(xiàn),因此Unity引擎默認沒有支持,不再詳述。