Mottó:
Mi a textúraszűrés?
Mipmapszintösszemosás.
Nem. Mipmapszintösszevisszamosás.
Túlragozod.
Nézd meg az anizotróp szűrést aztán rájössz, hogy nem.
A textúrázás már régóta elengedhetetlen követelmény a 3D játékok körében. Azonban, mint mindennek ennek is ára van. Szerencsére már a korai videokártyákák óta létezik az ún. TMU (texture mapping unit) vagyis texturázó egység, amelyeket kimondottan a textúrázás gyorsítására fejlesztettek ki. Ezek régebben külön processzorban kaptak helyet, ma már egybeépítik a GPU-val.
A TMU-nak két nagy feladata vannak a hagyományos (szín komponenseket tároló POT méretű) textúrák esetében - texture addressing (textúra címzés) és a texture filtering(mintavételezés) - amelyek elvégzése után szolgáltatja a mintavételezés eredményét.
Texture addressing
Ekkor történik a textúra koordináták textúra címekké való transzformálása, amelyet úgy képzelhetünk el a legkönnyebben, mintha a koordinátákat a mintavételezéshez szükséges 0.0 és 1.0 tartományba szorítaná be (clamp) az eljárás, amely mechanizmusból az idő során sokféle variáció keletkezett.
- GL_REPEAT: ez legelső technikák egyike. Ilyenkor a koordináták egészrészét elhagyva viszi át a céltartományba az értékeket vagyis későbbiekben a textúra az adott irányban ismétlődni fog.
- GL_CLAMP: ez is szintén korai technika. Lényege, hogy a koordinátákat nem hagyja ismétlődni, mert az 1-nél nagyobbi számokhoz 1-t rendel míg a negatív számokhoz 0-t.
- GL_CLAMP_TO_EDGE: az előbbi technika fejlesztett változata. A kettő közötti különbségről később szólunk.
- GL_CLAMP_TO_BORDER: ez is hasonlít ez előző kettőhöz a különbség annyi, hogy a negatív és 1-nél nagyobb tartomány mintavételezéséhez a keret színét használja fel és nem a textúrát.
- GL_MIRRORED_REPEAT: mint ahogy a neve is mutatja egyfajta tükrözésről van szó. A GL_REPEAT-től annyiban különbözik, hogy a páratlanadik ismétléskor a 0.0 - 1.0 tartományt 1.0 - 0.0 tartományba viszi át.
- GL_MIRROR_CLAMP: hasonló az előzőhöz, de a tükrözést csak az első páratlanadik esetben végzi el
- GL_MIRROR_CLAMP_TO_EDGE és GL_MIRROR_CLAMP_TO_BORDER: ezek a megfelelő technikák kombinálásának eredménye
Miután megszületett a textúra cím, akkor azon a helyen (vagy környékén) történik (történnek) a mintavételezés(ek) az előzőleg beállított szűrési paramétereknek megfelelően.
Arról sajnos nincs tudomásom, hogy több mintavételezés esetén a textúra címzés vizsgálata mindegyik textúra koordinátára is lefut-e. Mindenesetre a GL_CLAMP és GL_CLAMP_TO_EDGE típusok közötti különbség erre enged következtetni mivel utóbbi esetben (általában) nem történik túlcímzés a szomszédok mintavételezésekor. Gyakorlatban ez egy zavaró, egysoros texelcsík megjelenését eredményezi a textúrák szélein.
Texture filtering
A textúraszűrés lényege, hogy nem egy, az aktuális címről történt mintavételezés eredménye lesz a visszaadott érték. Ennek akkor a legszembetűnőbb a hatása amikor a textúra felhasználása során eltérő sűrűséggel veszünk belőle mintát. Alacsony a mintavételezési sűrűség (alulmintavételezés) akkor amikor a textúrát nagyítjuk ("pixeles" lesz a kép). Magas a mintavételezési frekvencia (túlmintavételezés), amikor a textúrát kicsinyítjük ("zizeg" a kép). Ezen esetekre kínál megoldást a szűrés, amelynek három lehetséges variánsa van: textúrán belüli, textúrák közötti, anizotróp.
A textúrán belüli szűrést már említettük. Amennyiben ezt bekapcsoljuk a mintavételezés a szomszédos címekről történik és a súlyozott átlagértékük (itt két lineáris interpolációról (bilinear) beszélhetünk; innen a neve LINEAR) lesz az eredmény. Ez kicsinyítéskor és nagyításkor lehetséges. Ha ezt nem kapcsoljuk be, akkor a textúra koordinátából számított legközelebbi textúracímről (NEAREST) történik a mintavételezés.
Textúrák közötti szűrés akkor lehetséges, ha azok egy mipmap készlet részei. Ilyenkor két, különböző mipmap szinthez tartozó textúrán belüli szűrés után a két kapott eredmény súlyozott átlaga lesz a végeredmény. Ez a szűrés típus csak kicsinyítéskor lehetséges mivel az alap mipmap szinttől nincs részletesebb textúra a készletben. Azt, hogy a mipmap készlet melyik két textúráját használja fel a TMU a mintavételezés frekvenciájából dönti el. A választását mi megváltoztathatjuk a GL_TEXTURE_LOD_BIAS segítségével.
Az itt elmondott variációk alapján a következő szűrések lehetségesek:
- GL_NEAREST - 1 mintavételezés
- GL_LINEAR - 4 mintavételezés
Amennyiben a textúrák közötti szűrést is bekapcsoljuk:
- GL_NEAREST_MIPMAP_NEAREST - 2 mintavételezés
- GL_LINEAR_MIPMAP_NEAREST - 5 mintavételezés
- GL_NEAREST_MIPMAP_LINEAR - 5 mintavételezés
- GL_LINEAR_MIPMAP_LINEAR. - 8 mintavételezés
Némely esetnek létezik közkeletű neve is. A GL_LINEAR eset másik neve (mipmap nélküli)bilineáris szűrés. A GL_LINEAR_MIPMAP_NEAREST másik neve (mipmap-elt) bilineáris szűrés. A GL_LINEAR_MIPMAP_LINEAR közkeletű neve pedig a trilineáris szűrés.
Megjegyzendő, hogy a textúrák közötti szűrés bár általában sok mintavételezést igényel mégis gyorsabb a mai GPU-kon, mint a textúrák közötti szűrés nélküli megoldások. Ennek az a fő oka, hogy az esetek nagy hányadában egy kisebb textúrából kell mintavételeznie a TMU-nak.
Alapesetben minden bilineáris szűrés azonos távolságokból történik vagyis a textúra minden területe egyenletes szűrés alá kerül, amely sokszor nem kívánatos látványt nyújt. Ezt a hibát hivatott javítani az anizotróp szűrés, amely független az előzőektől és implementáció függő a megvalósítása. A technika lényege, hogy a szomszédok mintavételezéséhez adaptívan választja meg a szűrési távolságokat.
A legszebb textúraszűrés beállításához a nagyítást GL_LINEAR-ra, kicsinyítést GL_LINEAR_MIPMAP_LINEAR-ra, az anizotróp szűrést maximumra érdemes állítani.
Második menetben a speciális textúra esetekkel fogok foglalkozni. Az egyik a NPOT méretű textúra és a mélységi textúra.