Alias či aliasing
Před čtyřmi lety jsem byl čtenáři požádán o článek, který by se podrobněji zabýval anti-aliasingem, ale zároveň byl alespoň trochu srozumitelný pro běžného uživatele. Přestože je to opravdu problematický úkol, pokusil jsem se ho splnit a připravil jsem článek, který na tuto problematiku nahlíží z několika hledisek; skládá se tedy z několika částí: aliasing, typy anti-aliasingu, historie (vývoj) a implementace u různých výrobců.
Alias(ing)
Nebudu jako obvykle začínat „trochou historie“, té se dočkáte později. Pokud máme rozebírat anti-aliasing, je nejprve dobré vědět, co to je alias , který se snažíme potlačit. Aliasing (neboli alias) obecně znamená jakýkoli nežádoucí obrazový (může být i zvukový, ale zde se budeme zabývat pouze obrazem) artefakt, na jehož vznik mělo vliv diskrétní prostředí (neplynulé, omezené nedělitelnou jednotkou). Zde máme na mysli především pixely* v kombinaci se snímkovou frekvencí (framerate).
* Termín pixel lze chápat několika způsoby. Nejobecnější definice je bod (tedy bezrozměrný objekt), kterému je přiřazena určitá barva. Toto je asi nejkorektnější hledisko. Ve článku ale několikrát použiji termín pixel k označení plošky na obrazovce, která nese barvu pixelu. Rozdíl v obou pohledech by se mohl zdát zanedbatelný, ale ve skutečnosti není - bezrozměrný bod a barevný "čtvereček" na obrazovce nezanedbatelných rozměrů jsou opravdu velmi odlišné subjekty a jak sami uvidíte, každý z přístupů má svá silná specifika.
Pro někoho možná bude novinkou, že aliasing neznamená jen zuby na hranách 3D objektů, ale zahrnuje mnohem více různých jevů, které můžeme ve statickém, ale i dynamickém obraze pozorovat.
Rozdíly mezi obrazem s a bez anti-aliasingu jsou hlavně v nižším rozlišení obrovské (3DMark06)
Temporal Aliasing
Nejprve stručně odbudu aliasing vzniklý pouze vlivem snímkové frekvence. Vezměme kupříkladu situaci, kdy máme scénu, ve které letí míček takovou rychlostí, že viditelnou plochu obrazovky přeletí za 1 sekundu. Podívejme se na tuto situaci z reálné stránky: Dnes jsou nejběžněji používány 17' monitory, jejichž viditelné pole bývá široké až 42 cm. Ideální stav by byl takový, že se míček pohybuje plynule. Jsme ale omezeni snímkovou frekvencí. Pokud vezmu v úvahu např. 25 fps, tak bude letící míček na každém následujícím framu posunut o 17 mm oproti framu předchozímu. Téměř dvoucentimetrové „skoky“ znamenají příliš velký rozdíl mezi následnými snímky, aby mohl být obraz vnímán plynule. Zde máme několik možných řešení:
a) snížit viditelnou plochu, čímž snížíme rozdíly mezi jednotlivými snímky (v praxi zobrazovací adaptér s menší úhlopříčkou) - do toho by se asi nikomu nechtělo ;-)
b) zvýšit snímkovou frekvenci (rozdíly mezi jednotlivými snímky pak budou menší a pohyb bude působit plynuleji)
c) použít Temporal anti-aliasing, nazývaný častěji Motion Blur. (dnes se označení Temporal anti-aliasing, zvlášť ve vztahu k ATI používá již pro něco úplně jiného, vysvětlím později)
Z těchto bodů lze snadno vyvodit dva závěry: Chceme-li kvalitnější (plynulejší) obraz, musíme mít rychlejší grafickou kartu; chceme-li použít větší monitor a zachovat subjektivní plynulost obrazu musíme použít rychlejší grafickou kartu. To také vysvětluje, proč v dobách karet typu Voodoo byl za dostačující framerate 30 fps (nejrozšířenější 14" monitory; luxusnější 15palcové), ale později (rozšíření 17" a 19" monitorů) se považovalo za vhodnější 60 fps a více.
Dalším z projevů temporálního aliasingu je třeba efekt rotujícího objektu (což známe i z televize). Objekt (např. kolo auta, vrtule helikoptéry) vlivem nedostatečné snímkové rychlosti vypadá, jakoby se točil např. na opačnou stranu, nebo pomaleji, než se točí ve skutečnosti. Tím bych tuto kapitolu uzavřel, zmínil jsem jí spíše pro zajímavost -aby bylo zřejmé, že pojem aliasing neoznačuje pouze ony "zubaté hrany", kterým je často přisuzován.
Tentokrát se zaměříme na projevy aiasingu, které jsou způsobené omezením pixely.
Spatial Aliasing
Můžeme říct plošný aliasing - prostě ten, který můžeme pozorovat i na jednom jediném snímku. Je způsoben tím, že jsme omezeni pixely - vlastně ploškami (viz výše uvedené definice), jejichž velikost není zdaleka zanedbatelná. Podívejme se, jak aliasing vzniká. Obraz je vytvářen tím způsobem, že pro bod, který je umístěn v centru pixelu, je spočtena barva a ta je poté použita pro celý pixel (standardní rasterizace). Bohužel, barva, která odpovídá středu pixelu, může být velmi vzdálená barvě, která by odpovídala většině plochy pixelu, popř. průměrné barvě pixelu. Tím dochází ke vzniku barevných chyb, které se ve výsledku projevují jako plošný aliasing.
Můžeme se podívat na to, jak rasterizace probíhá (stručně a zjednodušeně). Vezměme příklad, kdy potřebujeme vykreslit barevný trojúhelník, který by v ideálním případě vypadal nějak takto:
Za předpokladu, že jde o vektorový objekt, ho pro zobrazení na monitoru musíme převést na rastr. Rastr jsem znázornil černou mřížkou - každý čtvereček bude odpovídat jednomu pixelu.
Barva pro každý budoucí pixel je získána tak, že je spočten barevný vzorek z centra oblasti, která bude pixelem a takto získanou barvu použije pro celý pixel (jednoduše řečeno barvu, která je uprostřed čtverce, bude mít celý pixel, který zde bude umístěn)
Na výsledném obrázku vidíme několik nedokonalostí, nepřesností, zkrátka několik typů aliasingu. Podle toho, jak konkrétní artefakty vznikají a vypadají, můžeme rozlišit několik typů aliasingu, které zařazujeme do dvou skupin: Ta první zastupuje projevy aliasu na hranách polygonů a druhá na texturách.
Aliasing na hranách
se objevuje v několika základních podobách:
-jaggies (=stair steps)
-crawling
-pixel popping
-(sub)pixel flickering
Zubaté hrany a další nepěkné vady
Jaggies
Také jagged edges, stair-steps, česky známo pod termínem zubaté hrany. Toto je asi nejznámější a nejnepříjemnější projev aliasu. Zubaté hrany objektů známe všichni. Pojďme se podívat, jak tento defekt vzniká. Máme např. barevný (zelený) polygon a bílé pozadí. Každý čtverec vyznačený na obrázku znamená budoucí pixel.
detail hrany zeleného polygonu + bílé pozadí
červeně je označen střed pixelu; pro tento bod je spočtena barva, která je pak použita pro celý pixel
a takto vypadá výsledek
Pokud pozice středu pixelu leží na ploše polygonu (zde zelená plocha), je pro pixel použita zelená barva, v opačném případě pak barva bílá. Jak je vidět, přesnost a věrnost obrazu není zdaleka ideální. Např. takový pátý pixel zprava: teoreticky by měl být tvořen z takových 45% zelenou barvou, ale výsledná barva je čistě bílá. Naopak vedlejší pixel by měl být jen nepatrně tmavší, ale protože pozice, pro kterou je spočten barevný vzorek, již odpovídá ploše polygonu, je tento pixel plně zelený. Tyto prudké barevné skoky jsou vlastně zmíněnými "zuby", neboli jaggies.
Crawling
Neboli posuv jaggies na hranách objektů. Protože se objekty ve 3D prostředí pohybují, dochází k jejich posuvu vůči rastru. Představte si např., že byste okraje zelené plochy (v předcházejícím obrázku) jakýmkoli způsobem posunuli. Je velmi pravděpodobné, že se "zub" objeví o nějaký ten pixel jinde. V praxi je to patrné jako zuby jedoucí po hraně objektu. Crawling efekt je viditelný jen při animaci, takže obrázek tentokrát nebude (můžete si zkusit spustit Nature test ze 3D Marku 2001 a pozorovat horní hranu střechy domku).
Pixel Popping (~ Polygon Popping)
Tohle je již trošku složitější případ. Vezměte v úvahu situaci, kdy velikost polygonů (či celých objektů) zhruba odpovídá velikosti pixelu renderovaného rastru. Pak pohyb těchto objektů (či polygonů) způsobí, že zatímco v jednom snímku může být objekt navzorkován do dvou pixelů, pak na jiném snímku může být navzorkován do jednoho pixelu a na dalším snímku se může objekt "vměstnat" mezi pozice, odkud je vzorek odebírán - a pak není ve scéně objekt vůbec viditelný. Celá animace pak vypadá, jakoby byl objekt (či polygon) chvíli větší, chvíli menší, mizel, měnil tvar atp.
původ: SuperSampling Whitepaper (3Dfx/Beyond 3D; Dave Barron / Kristof Beets)
Na schématu máme znázorněnou situaci, kde dochází k posuvu objektů ve scéně a následné rasterizaci (první je horní snímek (a), následuje spodní snímek (b) ). Všimněte si, že posun barevných polygonů je oproti spodnímu obrázku minimální (zlomek pixelu), ale výsledek je diametrálně odlišný. Zajímavě se jeví i modrý objekt, který je znázorněn pouze v horním obrázku. Tento objekt velikosti pixelu může být (podle své pozice vůči rastru) zobrazen čtyřmi různými způsoby, z nichž ani jeden nezachycuje jeho skutečný tvar a polohu (pravý obrázek).
Subpixel Flickering
(poblikávání) Z názvu je celkem patrné, že půjde o něco obdobného, jako je Pixel Popping. Termínem Subpixel Flickering (či jen Flickering) bývá ale označována situace, kdy je pracováno s nějakým objektem, jehož jeden rozměr bývá menší (popř. srovnatelný) s velikostí pixelu. To si můžeme v praxi představit jako třeba sloup v dálce, prostě cokoli, co je tenčí, než polygon. Řekněme tedy sloup (znázorněn hnědě):
(A: ideální obraz; B: odebrání vzorků; C: výsledný obraz)
Pokud je vzdálenost sloup-pozorovatel dostatečná, dojde k situaci, kdy je sloup "tenčí", než pixel, na který by měl být zobrazen. Podívejte se na situaci číslo I.: Sloup je v takové pozici vůči rastru, kdy vůbec nezasahuje do místa, odkud je odebrán vzorek (červený puntík), takže ve výsledném obraze není sloup vidět!!! Když se ale pozorovatel nepatrně posune (situace II.), dostane se do pozice, ze které jsou odebrány vzorky pro barvu pixelu a sloup nejen že ve výsledné scéně bude vidět, ale zároveň bude vypadat širší, protože bude zobrazen přes šířku pixelu, i když ve skutečnosti by měl být užší. Pokud bychom se podívali na výsledný obraz v pohybu, bude se sloup objevovat a mizet (poblikávat) - podle toho, v jaké pozici vůči pozorovateli bude. Nabízím reálný obrázek:
Scéna, jak by měla vypadat; všimněte si dvou tenkých stožárů.
Původ: Quantum 3D - RGSS Whitepaper
Tři snímky z animace - na prvním a třetím není jeden stožár vidět, na druhém dokonce chybí oba. V případech, kdy je stožár viditelný, je zobrazen silnější, než by měl být
Blikání subpixelů a nespojité linie
Subpixel flickering v této popsané podobě není v běžných hrách zase až tak často k vidění (v porovnání s předchozími defekty). Zmiňován ale bývá velice často v souvislosti s profesionálními a armádními simulátory, kde je zapotřebí, aby se z obrazu dala odhadnout pozice a rozměry objektu - a to v případě objektu, který je "postižen" subpixel flickeringem (poblikává, mizí), není možné.
Unconnected Lines (nespojité linie)
Pokud dojde na situaci, kdy se všechny zmíněné defekty "sejdou", nevypadá to opravdu nijak dobře. Typickou ukázkou je úkaz, který se projevuje na objektech, které jsou velmi tenké a nejsou rovnoběžné s horizontálou, vertikálou, popř. jsou zvlněné. Dojde totiž k situaci, kdy část objektu je viditelná část ne. Lepší bude názorná ukázka.
2x zvětšeno bez převzorkování
Původ: Unreal Tournament
Tento výřez ze scény Unreal Tournament zobrazuje stožár, na kterém je dobře vidět několikanásobné přerušení. Problém vzniká následovně:
Stožár je tenčí než pixel, takže některé jeho části nejsou navzorkovány. Poslední praktickou ukázkou uzavírám kapitolu aliasing na hranách...
Snímek je v původním rozlišení (1024*768)
Původ: Painkiller
Lucerny visící ze stropu chrámu - typická ukázka nespojitých linií
Aliasing na texturách a ostatních částech 3D scény
Situace na texturách je poněkud jiná, i když leckeré typy zkreslení mohou být obdobné jako v předchozí kapitole. Nejpodstatnější rozdíl je v tom, že textury jsou samy o sobě rastry. Jejich další rasterizace může dělat neplechu - obzvlášť v případě, kdy velikost pixelu textury odpovídá velikosti pixelu renderovaného obrazu. V případě, že textura nese nějakou pravidelnou a jemnou kresbu, pak často vzniká tzv. moire. Začněme ale výčtem:
-moire
-jaggies (=stair steps)
-unconnected lines
Moire (hi-frequency noise)
Jak jsem již zmínil, moire vzniká rasterizací textury s více-méně pravidelnou kresbou. Tomu ještě pomáhá, že textura je sama o sobě rastr. Pokud by se rastr textury přesně promítl na rastr renderovaného obrazu, k žádnému defektu by samozřejmě nedošlo. Taková situace je ale velice vzácná. Na vznik moire má podstatný vliv i rozlišení a způsob filtrace textur. Čím je textura ostřejší, tím je náchylnější. Vykreslovat zde, jak zde moire vzniká pixel po pixelu, by bylo velice náročné a názornost by byla minimální. Obrázek řekne víc:
Pole opravdu neosel opilý traktorista. Původně šlo o jednoduchou pravidelnou texturu.
Původ: Quantum 3D - RGSS Whitepaper
Silné moire na snímku (pole). Jiná ukázka: Schodiště ze hry Painkiller...
Schodiště nese texturu s pravidelnou kresbou (horní obrázek), což při určité vzdálenosti od pozorovatele vede ke vzniku silného zkreslení (moire, druhý obrázek). Z toho je dobře vidět, že velmi záleží na poměru vzdálenosti pozic vzorků a vzdálenosti jednotlivých segmentů (zde čárek na schodišti) na textuře objektu. Pokud je tento poměr menší, než 1:1 (v praxi - linie čárky je tenčí, než je velikost pixelu rastru, na který bude zobrazen), pak je textura k moire náchylnější. Vzdáleností pozorovatel-textura se mění právě výše zmíněný poměr, což je vidět na následujícím snímku (pletivo v zábradlí):
Vzniku tohoto problému lze částečně předcházet již při vývoji hry. Např. eliminovat textury s jemnou a zároveň pravidelnou kresbou, neumožnit pozorovateli, aby mohl dosáhnout kritické vzdálenosti od textury (může být problém, závislost na rozlišení). Řešení by bylo více, ale většinou by s sebou nesla snížení kvality, nebo problematickou implementaci (méně ostrá textura, speciální mipmapy...). Intenzita zkreslení je závislá i na schopnostech hardwaru. Čím vyšší rozlišení textur HW zvládá, tím je náchylnost vyšší; také závisí na způsobu filtrace textur...
Unconnected lines
Nespojité linie se mohou vyskytnout i na texturách. Stačí, aby linie na textuře byla dostatečně tenká (či vzdálená) a její část se "promítla" mezi pozice odebíraných vzorků (stejná situace, jako zde). Typická ukázka:
Původ: Tomshardware
Další projevy aliasu a co vás čeká příště
Ostatní případy na texturách
„Zbytek“ si dovolím shrnout do jedné kapitolky. Na texturách se můžeme setkat i s jaggies (zubaté hrany na kresbě textury), ale to již patří minulosti. Stačí totiž, aby autor aplikace textury vhodně připravil (anti-aliasing) a není problém. Také pomůže filtrace textur.
Zajímavostí jsou případy, kdy nejsou použity mipmapy (tím myslím použití textur v maximálním rozlišení – s čímž se dnes již nesetkáme), popř. je použitý nevhodný LOD pro textury/mipmapy. S tím se už můžeme setkat poměrně běžně.
Problém může nastat ve dvou případech: První případ je problém aplikace, která si nastaví mipmap LOD (do záporných hodnot) tak, že hranice pro mipmapy je posunuta „dále“, takže pro většinu scény je použito vyšší rozlišení textur. Detaily textury se pak rozměrově blíží velikosti (či rozteči) pixelů a výsledkem je šum („shimmering“) či moire.
Důvody, proč někteří vývojáři tyto „prasárny“ dělají, jsou dva: Nemají velkou důvěru v uživatele a předpokládají, že si nezapne anizotropní filtraci (případně že ani neví, k čemu je dobrá) a textury se mu budou zdát neostré. Jejich krok pak způsobí problém všem ostatním uživatelům. Druhá možnost je neznalost samotného vývojáře - ač se to může zdát rozporuplné, objeví se čas od času člověk, který je sice výborným programátorem, ale nemá ponětí o základních principech FSAA nebo anizotropní filtrace a kvalitu obrazu řeší nekorektně po svém.
Druhý případ neleží na bedrech vývojáře hry, ale vývojáře ovladačů. Určitě si vzpomenete na kauzu GeForce 7 + shimmering, kdy Nvidia v rámci výkonnostních optimalizací sice použila při anizotropní filtraci korektní LOD, ale samotná filtrace byla "zjednodušena" a vycházela z menšího množství vzorků, než by měla. Pak se stalo, že některé detaily na texturách navzorkovány byly, jiné ne a při pohybu mizely a znovu se objevovaly, což vytvářelo známé chvění či šum na texturách.
Snímek je v původním rozlišení
(aliasing na textuře)
Původ: Unreal Tournament
Zkreslená textura podlahy ve větší vzdálenosti - projev textur o příliš vysokém rozlišení. Způsobů řešení problému je několik: Samozřejmě menší textury, nebo jejich kvalitnější filtrace (pokud je k dispozici). Tento problém je již dávno minulostí, ale z vizuálního hlediska je velmi blízký známému shimmeringu.
Dále alias na texturách rozebírat nebudu; obvykle jde o problém související s filtrací textur a ta by ho také měla řešit. FSAA by měl řešit jen specifické případy...
Aliasing ostatního typu
Jednou jsem již zmínil, že existují i jiné případy aliasu, než na okrajích polygonů a na samotných texturách. Tím může být aliasing na okrajích stínů. To je problém poměrně složitý; mnoho způsobů řešení není. Na druhou stranu technik, kterými se dají vytvářet stíny, je více a zdaleka ne všechny trpí tímto nedostatkem. Abych případ demonstroval obrázkem prošel jsem všechny hry i benchmarky, které mám momentálně nainstalované, ale takový případ, jakou bych potřeboval, jsem nenašel v žádné z nich - takže si opět půjčím tentýž obrázek z Tom's Hardware. Tentokrát se ale zaměřte na obrysy stínů automobilů...
Původ: Tomshardware
Pokud bychom měli tento problém (jaggies na okrajích) vyřešit, nezbývá, než použít techniku Soft Shadows (měkké stíny, obecně reálnější forma stínu, jehož okraje se pozvolna rozplývají (plošný zdroj světla), přičemž plocha stínu není černá, ale zůstává částečně osvětlená (rozptyl světla). Technik pro jejich realizaci je mnoho, ale ty jsou v tomto okamžiku vedlejší.
Snímek je v původním rozlišení
Původ: Painkiller
Jak je vidět, způsobů, jakými se aliasing projevuje, je opravdu hodně (a to jsem zmiňoval je ty základní). Potlačit všechny naráz pomocí způsobů, které jsem u jednotlivých typů zmiňoval, by bylo velice komplikované a mnohdy i neefektivní. Východiskem by bylo řešení, které by bylo univerzální a dokázalo si poradit se vším naráz - a to můžeme nazvat anti-aliasing.
Jak funguje anti-aliasing, jaké metody byly během posledních deseti lety používány, jestli má smysl používat vyšší rozlišení, nebo anti-aliasing a jaké jsou v současné době trendy dalšího vývoje, najdete v příštím dílu našeho článku.