Grafická pipeline: jak se tvoří obraz II
23.2.2015, Pavel Šantrůček, článek
Minule jsme si ukázali, jak nám grafická pipeline vůbec vzniká. Naší poslední zastávkou byl KMD (Kernel Mode Driver) a dnes se porozhlédneme, jak se to vlastně všechno v grafické kartě umele tak, abychom scénu z naší hry uviděli na monitoru počítače.
Kapitoly článku:
Pixel Shader (PS)
Primárním úkolem PS je tedy zjistit barvu příslušného pixelu, který mu rasterizér zaslal. Pokud by byla situace ideální, pak všechny barvy pro každý jednotlivý pixel jsou umístěny na příslušné textuře, kterou je objekt „potažen“. Stačilo by tedy přečíst pouze barvu texelu (pixel na textuře) a bylo by hotovo. Bohužel věci tak jednoduché nejsou, objekt může být pokryt vícero texturami, na objekt mohou dopadat různá světla, nebo naopak je před objektem mlha atd. Finální barva pixelu se tedy musí pracně vypočítat z několika zdrojů tak, aby byla v daném prostředí co nejrealističtější. Jak vidíte, někdy je počítání barvy náročné, jindy zase ne. V každém případě pokud PS barvu pro daný pixel určí, pošle ji do následující zastávky s názvem Output Merger.
Output Merger (OM)
Barva pixelu byla díky PS vypočítána a odeslána do OM společně s jeho pozicí (x, y) a vypočtenou hloubkou (z). Ale bude tato barva opravdu reprezentovat daný pixel na obrazovce? Odpověď zní poměrně lakonicky – možná ano a možná také ne. O tom rozhodne právě OM, který bere v úvahu také informace o „hloubce“ pixelů ze Z-bufferu. OM postupuje tak, že porovná hloubku právě zpracovávaného pixelu s hloubkou uloženou na stejné pozici v rastru Z-bufferu. Pokud zjistí, že hodnota hloubky pixelu je nižší než ta v Z-bufferu (aktuální pixel je blíže ke kameře), zapíše barvu aktuálního pixelu a jeho hloubku přepíše v Z-bufferu. V opačném případě je pixel zahozen jako neviditelný.
Barvy pixelů jsou zapisovány do výstupního zásobníku (Render Target) v paměti GPU (VRAM). V tomto zásobníku se pixely (jejich barvy) postupně shromažďují a postupně je tam i vytvářen jeden finální snímek (Frame) scény naší hry.
Poznámka: OM neprovádí pouze test hloubky v Z-bufferu, ale může testovat barvu také proti Stencil Bufferu a provádět Blending. Pro pochopení této problematiky to ale není nijak podstatné a zbytečně by nám to věci komplikovalo. Snad bych jen uvedl, že pomocí Stencil Bufferu se vytváří efekty jako stínování nebo obrysy objektů a pomocí Blending se zase ošetřují částečně průhledné objekty.
V každém případě OM byl poslední částí našeho potrubí a nezbývá nám nic jiného, než si něco málo říci o tom výstupním zásobníku (Render Target), tedy úložišti, kde se nám pixely skládají do finálního snímku.
Jako výstupní zásobník (Render Target) je nejčastěji používán Back Buffer, který je součástí takového podivného uskupení zásobníků s názvem Swap Chain. Tato kolekce bufferů je umístěna v paměti grafické karty a jejím úkolem je dodávat hotové snímky na monitor počítače. Swap Chain se skládá celkem ze tří zásobníků, z nichž jeden je označován jako Front Buffer a zbylé dva jako Back Buffer. Ti zkušenější už asi vědí, jak tyto zásobníky fungují, my si ale o nich podrobněji povíme až příště, kdy budeme řešit monitor spolu s vertikální synchronizací.
Výstupním zásobníkem (Render Target) může být někdy i jiné místo v paměti, než je Back Buffer. Představte si, že bychom mohli hotový snímek shromažďovat v paměti někde bokem, pak z něj vytvořit texturu, kterou bychom mohli aplikovat třeba na objekt zdi. Nepřipomíná vám to jednu hru?
Ale to bylo jen tak mimo, klidně na dynamické vytváření textur zapomeňte, protože my dále budeme počítat s tím, že jediným shromaždištěm našich hotových snímků bude výhradně Back Buffer.
Tak to bychom měli probranou pipeline grafické karty. Vím, že to místy vypadá docela složitě, ale věřte, že ve skutečnosti je to ještě složitější! Cílem našeho letu nad potrubím grafické karty bylo především pochopit samotný princip a ne detaily, takže nezoufejte, pokud jste něco konkrétního z okénka našeho letadla nezahlédli.
Pokud bychom s naším letadlem vystoupali mnohem výše a udělali ještě jeden přelet, jevilo by se nám to všechno přibližně následovně:
- Primitives definované svými vertexy jsou poskládány do 3D prostoru (IA)
- S vertexy je v 3D prostoru postupně nějak manipulováno (VS, TS, GS)
- Je provedena rasterizace do 2D (RA, PS, OM)
- Finální snímek je uložen ve Frame Bufferu
Samozřejmě jako vždy, vaše připomínky či dotazy jsou vítány v diskuzi pod článkem.