SSAO v OpenGL / Ravesli
V tomto tutoriálu se podíváme na to, co je SSAO v OpenGL a jak ho používat.
- SSAO
- Načítací buffery
- Normálně orientovaná hemisféra
- Náhodné rotace jádra
- Shader SSAO
- Stínování rozostření pozadí
- Použití stínování pozadí
- Závěr
- Dodatečné zdroje
SSAO
osvětlení pozadí — je fixní světelná konstanta přidaná k celkovému osvětlení scény pro simulaci rozptylování světlo. V reálném světě je světlo rozptýleno všemi směry a s různou intenzitou, takže nepřímo osvětlené části scény by měly mít také různou intenzitu osvětlení. Jedním typem aproximace nepřímého osvětlení je stínování pozadí (zkr. «AO» z angličtiny. «Aokolní Ozávěr»), který se pokouší simulovat nepřímé osvětlení ztmavením záhybů, otvorů a povrchů blízko sebe. Tyto oblasti jsou z velké části blokovány okolní geometrií, což dává světelným paprskům menší šanci uniknout, a proto vypadají tmavší. Podívejte se na rohy a záhyby vaší místnosti – uvidíte, že se tam světlo jeví o něco tmavší.
Níže je uveden příklad scény s ambientní okluzí a bez ní. Všimněte si, že mezi záhyby a v rozích se (ambientní) osvětlení jeví tmavší:

I když tento efekt není tak zřejmý jako ostatní, snímek s ambientní okluzí vypadá mnohem realističtěji díky přítomnosti malých, ale neméně významných světelných detailů, které dodávají celé scéně mnohem větší hloubku.
Výpočtové algoritmy AO jsou poměrně náročné na zdroje, protože musí brát v úvahu okolní geometrii. Na první pohled se zdá, že pro každý bod v prostoru by bylo možné vyslat velké množství paprsků, aby se určila míra ambientní okluze, ale tento proces by velmi rychle narazil na výkonnostní omezení řešení v reálném čase. V roce 2007 Crytek ve své hře s názvem krize použil techniku známou jako SSAO (z angličtiny. «Sobrazovka-Stempo Aokolní Ozávěr»). Místo použití skutečných geometrických dat k určení míry stínování pozadí výše uvedená metoda používá hloubková vyrovnávací paměť scény v souřadnicích prostoru obrazovky. Ve srovnání s konvenční AO je tento přístup výpočetně neuvěřitelně rychlý a produkuje realistické výsledky, což z něj činí de facto standard pro simulaci ambientní okluze v reálném čase.
Základy metody SSAO jsou poměrně jednoduché: pro každý fragment na „obdélníku obrazovky“ vypočítáme koeficient stínování, na základě hodnot hloubky obklopujících fragment. Tento faktor se poté použije k redukci nebo vynulování stínící složky fragmentu. Stínící faktor se získá odebráním více vzorků hodnot hloubky z nějakého sférického okolí (jádra vzorku) daného fragmentu a porovnáním hodnoty v každém vzorkovacím bodě s aktuální hodnotou hloubky fragmentu. Počet vzorkovacích bodů, které mají vyšší hodnotu hloubky než hloubka fragmentu, se nazývá stínící faktor.

Jak je vidět z obrázku, každý vzorkovací bod hloubky (šedý), který se nachází uvnitř nějakého geometrického objektu, přispívá ke konečné hodnotě faktoru stínování; čím více vzorkovacích bodů je uvnitř objektu (objektů), tím méně osvětlení pozadí by měl fragment nakonec obdržet.
Je zřejmé, že kvalita a přesnost efektu přímo souvisí s počtem použitých vzorkovacích bodů. Pokud jich je příliš málo, přesnost metody prudce klesá a dostáváme artefakt v podobě určitého pruhování/segmentace obrazu, tzv. pruhování (z angličtiny. «páskování»); pokud je vzorků příliš mnoho, výkon algoritmu klesá. Požadavek na počet použitých vzorků můžeme snížit zavedením určité náhodnosti do jádra vzorku. Náhodným otáčením jádra vzorku každého fragmentu můžeme získat vysoce kvalitní výsledky s mnohem menším počtem samotných vzorků. Tato náhodná složka však zavádí znatelnou obrázek hluku, což budeme muset opravit rozmazáním získaných výsledků. Níže je obrázek (s laskavým svolením Johna Chapmana), demonstrující efekt pruhování a vliv náhodné složky na konečný výsledek:

Jak vidíte na obrázku vlevo, při použití SSAO s nedostatečným počtem vzorkovacích bodů dochází k znatelnému efektu pruhování. Zavedením náhodné složky rotace a aplikací rozmazání na konečný výsledek efekt pruhování zcela odstraníme.
SSAO, vyvinutý společností Crytek, měl osobitý vizuální styl. Protože použité vzorkovací jádro bylo koule, ploché stěny se jevily šedě, protože polovina vzorkovacích bodů z jádra skončila uvnitř okolní geometrie. Níže je obrázek Crysis v režimu stupňů šedi z SSAO, který jasně ilustruje tento efekt:

Z tohoto důvodu nepoužijeme sférické jádro, ale polokulové jádro orientované podél normálového vektoru plochy.

Provedením výběrů v rámci výše uvedeného normálně orientovaná hemisféra, při výpočtu koeficientu stínování se zbavujeme nutnosti výpočtu stínící složky vnášené fragmenty ležícími pod přilehlým povrchem. Díky tomu se zpravidla dosahuje realističtějších výsledků.
Načítací buffery
Protože použití SSAO vyžaduje výpočet koeficientu stínování fragmentů, budeme potřebovat následující data:
vektor pozice každý fragment;
vektor normály každý fragment;
barva albedo každý fragment;
vzorek jádra;
vektor libovolná rotace pro každý fragment použitý k otočení jádra.
Pomocí polohy každého fragmentu (v souřadnicích zorného prostoru) můžeme orientovat polokulové vzorkovací jádro kolem (v souřadnicích zorného prostoru) normály povrchu fragmentu a použít toto jádro k vzorkování hodnot z textury vyrovnávací paměti pozice s různými ofsety. Pro každý bod fragmentu vzorkovaný ze vzorkovacího jádra porovnáme jeho hodnotu hloubky s hodnotou hloubky ve vyrovnávací paměti pozice, abychom určili množství stínování. Tento faktor stínování se poté použije k omezení finální AO složky. Navíc použitím rotačního vektoru pro každý fragment můžeme výrazně snížit počet potřebných vzorků:

Protože SSAO je metoda využívající prostor obrazovky, vypočítáváme její vliv na každý fragment obdélníku obrazovky. To znamená, že nemáme žádné geometrické informace o scéně. Co bychom mohli udělat, je vykreslit geometrická data každého fragmentu do textur v prostoru obrazovky, které pak odešleme do shaderu SSAO, abychom měli přístup ke geometrickým datům každého fragmentu. To je velmi podobné nastavení G-pufry odložené vykreslování. Z tohoto důvodu je použití SSAO ideálně kombinováno s metodou odloženého vykreslování, protože v G-bufferu již máme vektory polohy a normály.
Poznámka: V tomto tutoriálu implementujeme SSAO nad mírně zjednodušenou verzí odloženého vykreslování z tutoriál o odloženém stínování v OpenGL.
Informace o poloze každého fragmentu a odpovídajícím normálovém vektoru jsou k dispozici z objektů scény, a proto fragment shader Geometrický průchod je následující: