3Dfx 22-bit postfiltering, FSAA 4x -> 22bit output



    Jistě jste se už někdy setkali s informací, že 3Dfx karty podporují tzv. 22-bit výstup, což umožňuje dosáhnout vyšších kvalit obrazu, než při běžném 16-bit režimu. V tomto článku se pokusím vysvětlit, o co se jedná a k čemu je to skutečně dobré.

Akcelerátory 3Dfx používají interně 24bit rendering, ale pouze 16-bit frame buffer (frame buffer je část grafické paměti, kam se ukládají části obrazu během vykreslování, a když je hotový celý snímek, převede ho RAMDAC do analogové podoby, a pak je zobrazen na monitoru). Použití 16-bit frame bufferu má dvě zásadní výhody. Jednak zabere v paměti méně místa za druhé méně vytíží paměťovou sběrnici.

Při převodu 24-bit obrazu na 16-bitový je použit tzv. dithering. Pokud víte, oč jde, můžete tuto část přeskočit a pokračovat prvním podnadpisem. Dithering je metoda používaná tam, kde potřebujeme zobrazit více barevných odstínů, ale máme k dispozici jen několik (málo) barev. Ukázka:

   

Na levém obrázku je znázorněn barevný přechod (truecolor, až 16,7 mil. barev), kdežto na pravém je znázorněn tentýž obrázek, ale je složen pouze ze dvou barev. Tomu rozptýlení, které je na obrázku patrné, a které má za úkol způsobit vizuální dojmem barevného přechodu, se říká dithering. Druhá ukázka je trochu zajímavější:

   

Na levém obrázku je zobrazena opět tatáž situace, ale je použito 16 barev (pozor, 16 barev, ne 16-bit barvy!) + dithering (floyd-steinbergův). Pravý obrázek také používá 16 barev, ale bez ditheringu - je na něm patrný tzv. banding (=pruhy; znáte třeba z některých 16bit textur). Je velice dobře patrné, že levý obrázek (dithering) se podobá původnímu více, než pravý. Pokud byste si dostatečně odsedli od monitoru (případně použili velmi vysoké rozlišení), přestaly by být jednotlivé "tečky" patrné a vizuálně by splynuly v jeden barevný přechod. Při hrách si ale od monitoru neodsedáváme, takže mnohdy jsou samotné defekty ditherignu příliš výrazné a žádaný efekt (vizuální splynutí) není dostačující.

Reverze ditheringu

Jak jsem již zmínil, 3Dfx praktikovalo 24-bit rendering s výsledným obrazem převedeným na 16-bit s využitím ditheringu 2x2 (tj. v úsecích velkých 2x2 pixely). Samotný dithering ale může být v obraze příliš patrný až rušivý, a tak 3Dfx přistoupilo ke kroku, jehož cílem byla jakási inverze ditheringu; zkrátka opětovné rozšíření barevného spektra před zobrazením na monitor.

3Dfx používalo dithering 2x2, což sice není ideální způsob (kvalitnější formy byly implementovány hardwarově až o několik let později), ale poměrně se hodí pro realizaci postfilteringu. Vezměme si jako příklad barevný přechod dvou odstínů modré v 16-bitech a ditheringu 2x2 pixely. Může nastat celkem těchto pět situací:

 - 4:0 (všechny 4 pixely tmavě modré)
 - 3:1 (tři tmavé, jeden světlý)
 - 2:2 (dva tmavé, dva světlé)
 - 1:3 (jeden tmavý, tři světlé)
 - 0:4 (všechny světlé)

Myšlenka 22-bit postfilteringu spočívá v tom, že každý pixel nahradíme barevným průměrem:

Pixel (vyznačený světle šedě) nahradíme barevným průměrem čtyř pixelů (těch orámovaných - 2x2). Tady ale narážíme na jeden limit. Pokud bychom obraz tímhle způsobem přefiltrovali, byly by výsledkem rozmazané detaily, rozostřené hrany objektů atp. Aby se tomuto zamezilo, 3Dfx použila adaptivní filtraci, která funguje následujícím způsobem:

Porovnáme barvu zpracovávaného pixelu (vyznačený světle šedě) s barvou oněch sousedních tří (viz obrázek výše), které by měly být započteny do průměru. Mohou nastat dvě situace:

1) barva pixelů se liší pouze o jeden odstín 16-bit spektra, to znamená, že původně byl v tomto místě použit plynulý barevný přechod a je třeba ho obnovit = použije se filtrace, tzn. barva pixelu je nahrazena průměrem celé čtveřice

2) barva testovaného pixelu se výrazně liší od ostatních třech sousedních pixelů, což znamená, že se pravděpodobně pixel nachází na nějaké hraně a filtrace použita není

Tento postfiltering umožní vytvořit další barevné odstíny a zároveň nijak nepoškodí ostré hrany a kontrastní detaily.

Proč zrovna 22-bit barvy?

Odpověď je jednoduchá. Pokusím se to vysvětlit trochu jiným způsobem, než na Beyond3D; (jejich vysvětlení je sice stručnější, ale poněkud kostrbaté a přestože vede ke správnému výsledku, může se zdát na první pohled nekorektní).

Obraz, na který aplikujeme postfiltering, je 16-bitový. V 16-bit spektru je pro červenou barvu je použito 5 bitů, pro zelenou 6 bitů a pro modrou opět 5 bitů (na zelenou je lidský zrak citlivější, dokáže rozlišit více odstínů a bit navíc se používá pro kompenzaci tohoto jevu). Máme tedy R+G+B = 5+6+5 = 16bitů. Abychom získali více barev, musíme 16-bit spektrum rozšířit o další barvy, které získáme speciální filtrací. Kde se tyto barevné odstíny vezmou (a kolik jich bude) se dozvíte v následujících dvou odstavcích; teď se ale vraťme k tomuto obrázku:

Prvořadě musíme brát v úvahu, že tyto dva odstíny modré prezentují dva sousedící odstíny v 16-bitovém barevném spektru (pozn. pro lepší názornost jsem na obrázku zvolil více odlišné odstíny, jinak bychom ve schématu dobře neviděli rozdíly).

Jak už jsme si řekli, pokud by ve čtveřici barev byla byť jediná, která se liší více než o jeden odstín, nebude provedena filtrace a dál nás taková čtveřice vůbec nemusí zajímat. To znamená, že na našem obrázku máme znázorněno všech pět možných situací, kdy je filtrace prováděna. V prvním a pátém případě ale filtrací vznikne tatáž barva, jako byla přítomna před filtrací (tzn. že stále náleží do spektra původní 16-bitové palety), takže opět nedojde k žádné barevné změně a jsme stále v původním 16-bit spektru. Zbývají prostřední tři kombinace. Pokud bychom zprůměrovali jejich barvy, dostáváme tři nové odstíny, které v původní 16-bit paletě nebyly přítomny. To znamená, že na každou barvu původní 16-bit palety připadají tři nové. Znázorním to graficky:

Vypadá to možná trochu komplikovaně, ale vysvětlím. V 16bit RGB je R (červená) vyjádřena 5ti bity, modrá také 5ti a zelená šesti (vrchní část tabulky). Znamená to, že pro červenou je k dispozici 32 odstínů (5 bitů = 2*2*2*2*2 = 32), pro modrou také 32 odstínů a pro zelenou jich je 64 (dvojitě orámovaná část). Kombinace těchto možností (32*32*64), je 65 tisíc barev; klasické 16-bitové spektrum. Díky postfilteringu ale ke každé z jednotlivých barev přibudou tři další: Pro červenou jsme získali 32 nových odstínů vytvořených poměrem 1:3, 32 nových odstínů vzniklých poměrem 2:2 a 32 dalších vzniklým poměrem 3:1. Totéž pro modrou a obdobně pro zelenou, ale ta má díky bitu navíc 64 nových odstínů pro každou z možností. Když možnosti posčítáme, zjistíme, že po provedení postfilteringu máme nyní celkem 128 odstínů pro červenou, 256 pro zelenou a 128 pro modrou. Vynásobeno: 4,2 milionu barev.

Stále příliš složité? Tak ještě stručněji. (a pouze na modré): měli jsme 32 odstínů modré (tj. 5 bitů), postfiltering nám ke každému odstínu vytvořil tři nové, tzn. nyní máme odstínů 4-násobek (4x32=128). Stejně tak červená (4x32=128) a analogicky zelená (4x64=256). RGB = 128*128*256 = 4,2 milionu = 22bit barvy.

FSAA a 22bit barvy?

Při aktivaci FSAA 4x a 16-bit renderingu na VSA-100 také dochází k expanzi na 22bitů, ale poněkud jinou formou. Vzhledem k tomu, že jsou při FSAA vykresleny čtyři obrazy, které se následně prolnou v jeden, vznikne každý pixel kombinací čtyř 16 bit barev a nastává prakticky podobná situace, kterou jsem popsal pod tabulkou výše. Tento "22bit výstup" je ale určitým způsobem korektnější, než postfiltering. Postfiltering kombinuje barvy okolních pixelů, takže určitým způsobem (i když relativně zanedbatelným) snižuje ostrost na filtrovaných úsecích. Při FSAA nejsou kombinovány barvy sousedících pixelů, ale jen subpixelů (= FSAA) a navíc jsou "upraveny" všechny pixely; nejen úseky (protože jsou použity subpixely a nikoli sousedící pixely, nedochází k rozmazání; naopak detaily více vyniknou).

16bit, 22bit, 24bit, 32bit?

Častá otázka je, jaký je vlastně rozdíl mezi 24bit a 32bit výstupem. Prakticky žádný. Ve své podstatě jde o jedno a totéž. 8 bitů (rozdíl mezi 32-bit a 24-bit) není určeno pro barevné hodnoty a při zobrazování se těchto 8 bitů nepoužívá (tato data obvykle slouží jako alpha kanál, tj. informace o průhlednosti a ta se používá při výpočtech, ale ne při samotném zobrazení.

Nyní bych se malou oklikou vrátil na začátek článku, kde jsem popisoval, že po 24-bit renderingu následuje dithering a obraz je ukládán 16-bitově do frame bufferu. Pak následuje nějaký ten postfiltering a máme 22bitů. A teď bych se chtěl zaměřit na to, kde je vlastně postfiltering realizován. Nebudu z toho dělat vědu; provádí ho digitální část RAMDACu. Shrnuto podtrženo:

Jádro (24bit) -> dithering -> frame buffer (16bit) -> jádro (22bit postfiltering v RAMDACu) ->výstup

Když se na toto schéma podíváte, můžete si všimnout, že 22-bit obraz se vůbec nenachází v grafické paměti (tj.frame buffer), takže pokud si uděláme screenshot, budeme asi dost rozčarováni, protože dojde pouze ke zkopírování obsahu frame-bufferu, ve kterém máme hrubý 16-bit obraz s patrným ditheringem (nebo v případě FSAA 16bit obraz s bandingem). Schůdné řešení je použít pro vytvoření screenshotu utilitku, která dokáže postfiltering emulovat; např. HyperSnap (nutno správně nastavit!). Další chyba je ukládat získaný obrázek v 16-bit formátu. Opět byste přišli o 6-bitů na kvalitě. Použijte vždy standardní 24-bit formát.

V souvislosti s tvorbou screenshotů je tu ještě jeden problém. V ovladačích od 3Dfx je obvykle nastavena gamma correction na 1.4, což je sice při hraní praktické (vidíte dobře ve tmavých koutech), ale pokud srovnáváte screenshoty 3Dfx a konkurence, vypadá obraz od 3Dfx vybledle a nevýrazně, což mnoho autorů dobových recenzí hodnotilo jako velký zápor série Voodoo (rofl - to si neodpustím ;-). Pokud se vám do rukou dostanou již korektně vytvořené screenshoty s postfilteringem, ale s různě nastavenou gammou, existuje snadné řešení. Není to sice úplně korektní, ale je to pořád lepší, než srovnávat nesrovnatelné. Upravte gammu non-3Dfx screenshotu v nějakém editoru (obvykle na 1.4, ale někdy spíš odpovídá hodnota 1.3 nebo 1.35), a pak teprve proveďte srovnání. Možná budete překvapeni.

Postfiltering - více režimů

Postfiltering, který jsem popsal nad odbočkou o FSAA, není jediný, jaký hardware od 3Dfx nabízí. Krom filtru 2x2 totiž existuje ještě režim 4x1 (čtyři pixely v řádku). Ten funguje obdobně; také dojde k testu barvy pixelů a následné filtraci, ale tento režim byl implementován jako první a podporují ho i starší karty (V2). Jeho výhoda spočívá ve snazší HW implementaci (RAMDAC načítá pixely po řádku, takže nedochází k žádné komplikaci) a prakticky nulovému propadu ve výkonu. Nevýhodou tohoto režimu je, že v obraze mohou být tyto vodorovné řádky příliš patrné; obzvlášť při větším monitoru a nižším rozlišení). Novější režim 2x2, který je implementován od Voodoo 3 výše, již tyto artefakty nevytváří, ale také má jednu slabinu. Tím, že je třeba kombinovat barvy pixelů, které jsou na dvou různých řádcích, dochází k mírnému propadu ve výkonu. Udává se 0-5%, já jsem provedl pár testíků a víceméně s tím souhlasím, i když bych se přiklonil spíš k hodnotě kolem 2%.

Jak si postfiltering nastavit?

V ovladačích Voodoo 3/4/5 je v sekci Direct 3D i OpenGL/Glide položka "3D filter quality" a u ní tři možnosti:

automatic (ponechá na volbě aplikace, obvykle vypnutý)
normal (filtr 4x1) - tj. ten starší režim, bez ztráty výkonu, možné čárkovité vodorovné artefakty
high (filtr 2x2) - novější (V3/4/5), ztráta výkonu kolem 2%, bez artefaktů.

Pokud zapínáte postfiltering, doporučuje se nastavit položku "alpha blending" na hodnotu "sharper".

16-bit + postfiltering = 22-bit, ale co 32-bit + postfiltering?

Používáte-li V4/5, pak tuto možnost sice máte; teoreticky by měla vést na 40-bit výstup, ale ten RAMDAC neumí, takže si nijak nepomůžete. Při 32-bit renderingu ve vyšších rozlišeních (1024*768) navíc režim 2x2 způsobuje dost citelný pokles výkonu (změřil jsem kolem 10% na V4). Nezapomeňte tedy při 32-bit vykreslování postfiltr vypnout.









V článku jsem použil některé obrázky z archivovaného 3DConcept.de na http://www.archive.org a dále několik informací ze série článků na http://www.beyond3d.com.

Jestli si chcete stáhnout korektně provedené screenshoty Voodoo3 (22bit) vs. TNT (16bit) vs. TNT (32bit), jsou k dispozici např. zde (stahujete z beyond3d; halflife, 912kb), ale pro objektivní porovnání je třeba provést gamma correction, jak jsem popsal výše.

Pokud by vám bylo cokoli nejasné, nebo byste našli nějakou nesrovnalost, obraťte se na fórum. Kolem těchto témat je příliš mnoho nezodpovězených otázek, takže jakákoli informace, zkušenost nebo upřesnění mohou být prospěšné.











© no-X 2005
akt. 29-05-2005
hlavní stránka
diskusní fórum