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