Zkratka proAmbient Occlusionembient okluzeTakéAO, SSAO, okluze okolního světlaPokročilý
Definice
Ambient occlusion je technika stínování, která u každého bodu povrchu odhaduje, jak velká část okolní polokoule oblohy je zastíněna blízkou geometrií, a podle toho ztlumí rozptýlené okolní světlo. Výsledkem jsou tmavší kouty, spáry, záhyby a místa dotyku objektů, díky nimž scéna působí prostorově a objekty vypadají skutečně položené na podložce.
Proč holé okolní světlo vypadá ploše
Klasické osvětlovací modely nahrazují všechno nepřímé světlo jedinou konstantou, takzvanou ambientní složkou. Ta přičte stejnou hodnotu ke každému pixelu bez ohledu na to, jestli jde o volnou stěnu nebo o roh mezi třemi plochami. Scéna pak vypadá jako vystřižená a nalepená: nábytek se vznáší nad podlahou, spáry mezi panely mizí. Ambient occlusion tuhle konstantu moduluje faktorem viditelnosti oblohy, takže sevřená místa dostanou méně světla než odkryté plochy.
Co se počítá
Pro bod na povrchu se nad jeho normálou uvažuje polokoule a měří se, jaká část paprsků vyslaných do ní narazí na geometrii dřív, než uletí zvolenou maximální vzdálenost. Poměr volných paprsků je faktor okluze v rozsahu 0 až 1. Vzdálenost je klíčový parametr: kdyby byla nekonečná, uvnitř uzavřené místnosti by vyšla nula všude. Přesnější varianty navíc paprsky váží kosinem úhlu vůči normále, protože difuzní povrch přijímá nejvíc energie kolmo.
Ambient occlusion je záměrně nefyzikální aproximace. Skutečné nepřímé osvětlení závisí na tom, odkud světlo přichází a jakou barvu má odražené prostředí; AO to redukuje na jediné číslo nezávislé na směru pohledu i na poloze světel. Právě proto se dá předpočítat a je levné.
Screen space versus paprsky
Herní enginy nejčastěji používají SSAO a jeho následovníky (HBAO, GTAO). Ty pracují až nad hotovým G-bufferem: vzorkují okolní pixely v hloubkové mapě a odhadují okluzi z rozdílů hloubek. Cena nezávisí na složitosti scény, ale technika vidí jen to, co je na obrazovce, takže objekt mimo záběr nebo skrytý za jiným stín nepřidá. Typické artefakty jsou tmavé lemy kolem siluet a blikání okluze při otáčení kamery.
Offline renderery a moderní hybridní pipeline počítají RTAO, kde se paprsky opravdu vystřelí do scény (viz Ray tracing). Výsledek je korektní i pro geometrii mimo obraz, cenou je šum, který se musí odstranit denoiserem. Třetí cestou je zapéct AO do textury nebo do vertexových atributů: to se hodí pro statické prostředí a pro assety, kde se okluze modelu nemění.
Jak se AO správně použije v shaderu
Mapa okluze patří pouze na nepřímou difuzní složku. Násobit jí i přímé světlo z bodového zdroje je chyba, protože stín od takového zdroje už řeší shadow mapa a výsledek se zdvojí do špinavě šedého obrazu. U zrcadlových odrazů se místo obyčejného AO používá specular occlusion odvozená z drsnosti materiálu, jinak by lesklé kovy zčernaly v místech, kde odraz reálně vidí ven.
V PBR workflow bývá AO uložená v samostatném kanálu texturové sady, typicky v červeném kanálu společně s roughness a metalness. Umělecké přehnání okluze je nejčastější důvod, proč modely působí zašle: faktor by měl tlumit, ne kreslit obrysy.
Příklady z praxe
SSAO nad G-bufferem v realtime enginu
Fragment shader vezme hloubku a normálu aktuálního pixelu, rozmístí kolem něj sadu vzorků v polokouli a spočítá, kolik z nich je podle hloubkové mapy zakrytých. Výsledek se rozmaže bilaterálním filtrem, aby zmizel šum z malého počtu vzorků, a teprve pak se jím násobí ambientní složka. Kernel má obvykle 8 až 32 vzorků, protože cena roste lineárně s jejich počtem.
float occlusion = 0.0; for (int i = 0; i < SAMPLE_COUNT; ++i) { vec3 samplePos = fragPos + TBN * kernel[i] * radius; vec4 clip = projection * vec4(samplePos, 1.0); vec2 uv = (clip.xy / clip.w) * 0.5 + 0.5; float sceneDepth = texture(gDepth, uv).r; float rangeCheck = smoothstep(0.0, 1.0, radius / abs(fragPos.z - sceneDepth)); occlusion += (sceneDepth >= samplePos.z + bias ? 1.0 : 0.0) * rangeCheck; } float ao = 1.0 - occlusion / float(SAMPLE_COUNT);Zapečení AO mapy pro herní asset
Modelář v Blenderu vytvoří high-poly verzi bedny s frézovanými hranami a nýty, rozbalí low-poly verzi do UV a nechá okluzi zapéct do textury 2048 × 2048. V enginu pak stačí jedno čtení textury místo desítek vzorků za snímek. Nevýhoda se projeví, jakmile se bedna otevře nebo rozpadne: zapečená okluze zůstane přilepená na původní tvar a víko si nese stín, který už nikam nepatří.
Časté omyly
- MýtusAmbient occlusion je vlastně levný stín od slunce.
- Ve skutečnostiAmbient occlusion nezná polohu ani směr žádného světla. Popisuje pouze míru zastínění okolní polokoule geometrií a modeluje tak nepřímé osvětlení; stíny od konkrétních zdrojů řeší shadow mapy nebo stínové paprsky.
- MýtusKdyž je AO zapnutá, scéna má korektní global illumination.
- Ve skutečnostiAmbient occlusion je hrubá aproximace jediného aspektu nepřímého osvětlení: zastínění. Neřeší barevné přelévání mezi plochami, odražené světlo ani směrovost oblohy, takže plnohodnotné GI nenahradí.
- MýtusSilnější AO znamená realističtější obraz.
- Ve skutečnostiPřehnaný faktor okluze vytvoří tmavé lemy kolem objektů a šedavý nádech všude, kde by mělo být čisté světlo. Realističtější je jemné ztlumení v kontaktních místech než výrazné obtahování obrysů.
Časté dotazy
- Kolik výkonu ambient occlusion stojí v realtime renderingu?
- Ambient occlusion ve screen space typicky spotřebuje jednotky procent až nižší desítky procent času snímku, podle rozlišení, počtu vzorků a poloměru. Náklady určuje hlavně počet čtení z hloubkové mapy a následné rozmazání, nikoli složitost scény. Levnější varianty počítají AO v poloviční rozlišení a výsledek upsamplují. Verze založená na sledování paprsků je řádově dražší, protože ke každému pixelu je potřeba vyslat několik paprsků do akcelerační struktury a výsledek zbavit šumu, obvykle s pomocí temporální akumulace přes více snímků.
- Do kterého kanálu textury patří AO mapa v PBR materiálu?
- AO mapa je jednokanálová hodnota, takže se skoro vždy balí do jedné složky RGB textury společně s dalšími skalárními mapami. Rozšířená konvence označovaná ORM ukládá okluzi do červeného kanálu, roughness do zeleného a metalness do modrého; jiné pipeline pořadí prohazují, proto je nutné držet se dokumentace konkrétního enginu. Data okluze jsou lineární, ne sRGB, takže se textura musí načítat bez gama převodu, jinak vyjde okluze příliš světlá.
- Proč SSAO bliká a kolem objektů vznikají tmavé lemy?
- SSAO pracuje jen s informací viditelnou na obrazovce. Když se objekt dostane mimo záběr nebo za jinou geometrii, jeho příspěvek k okluze zmizí a osvětlení se skokově změní. Tmavé lemy vznikají u siluet, kde hloubková mapa hlásí velký skok a algoritmus ho vyhodnotí jako blízké zastínění. Pomáhá menší poloměr, kontrola rozsahu vzdálenosti mezi vzorky, temporální filtrace přes několik snímků a přechod na variantu s horizon-based odhadem nebo na paprskové řešení.
- Kdy dává smysl AO zapéct do textury místo počítání za běhu?
- Zapečená AO se vyplatí u statické geometrie a u modelů, jejichž tvar se během hry nemění: architektura, kulisy, propy s jemnými detaily z high-poly modelu. Náklad je jedno čtení textury a kvalita je vyšší než u screen space, protože se počítá offline s mnoha paprsky. Zapékání ale nefunguje u deformovatelných postav, u destruovatelné geometrie a u objektů, které se vzájemně přesouvají, protože kontaktní okluze mezi nimi vzniká až za běhu. Řada projektů obě metody kombinuje.
Zdroje
- Ambient occlusion(otevře se v novém okně)
- Blender Manual(otevře se v novém okně)
- OpenGL Registry(otevře se v novém okně)
- Direct3D 12 graphics documentation(otevře se v novém okně)