Renderování s využitím GPU

Editovat
Note

Principy OpenGL, souřadnicové systémy (prostor světa, prostor kamery, prostor objektů), typy shaderů a jejich použití (vertex, fragment, compute, teselační). Technika stínových map. Principy odloženého stínování a jejich použití. Efekty prostoru obrazu (anti-alias, ambientní okluze).

PV227

OpenGL

API pro (nejen) vykreslování grafiky na GPU.

OpenGL® is the most widely adopted 2D and 3D graphics API in the industry, bringing thousands of applications to a wide variety of computer platforms. It is window-system and operating-system independent as well as network-transparent.

— Khronos

OpenGL je velký state machine, něco jako telefonní ústředna. Má bambilion funkcí, které mění globální stav, a jen několik funkcí (jako jsou glDraw*), které i něco doopravdy dělají. OpenGL je proto poměrně tolerantní k pořadí, v jakém jsou funkce volány.

vph07 switchboard
Obrázek 1. A large Bell System international switchboard in 1943
OpenGL Shading Language (GLSL)

Jazyk, ne nepodobný C, který se používá na psaní shaderů v OpenGL, WebGL a Vulkanu. Programy v něm (většinou) nejsou kompilované dopředu. Teprve za běhu programu jsou skrze OpenGL API ve zdrojové podobě předány GPU driveru, který je zkompiluje a spustí na GPU.

Primitives

Způsob interpretace vertexových dat, která aplikace předává OpenGL.

  • Trojúhelníky (GL_TRIANGLES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN),

  • čáry (GL_LINES, GL_LINE_STRIP, GL_LINE_LOOP),

  • body (GL_POINTS),

  • patche (GL_PATCH) — pro teselaci.

Souřadnicové systémy

Important
Tahle část otázky má značný překryv s otázkou Modelování a projekce.
vph07 coordinate systems
Obrázek 2. Coordinate Systems [3]
Model space / local space / prostor objektu

Každý vykreslený objekt má svůj lokální souřadnicový prostor daný editorem, ve kterém byl vytvořen, nastavením exportu a formátem, ve kterém byl vyexportován: [4]

Editor Handedness

Blender

right-handed

doprava

dopředu

nahoru

3ds Max

right-handed

doprava

dopředu

nahoru

Maya

right-handed

doprava

nahoru

dopředu

World space / prostor světa

Globální prostor, ve kterém se objekty nachází. Měřítko je dáno aplikací.

Z model space do world space převádíme souřadnice pomocí model matice (). Ta nám umožňuje objekt nejen posunout ale i otočit a změnit jeho měřítko.

Camera space / view space / eye space / prostor kamery

Prostor, který je viděn z pozice kamery.

View matice () slouží k otočení, posunutí a případnému zvětšení nebo zmenšení prostoru světa tak, aby se objekty nacházely v prostoru před kamerou.

Clip space

OpenGL očekává, že všechno, co bude vykresleno se nachází v jistém objemu — clip space. Všechny souřadnice musíme do tohoto objemu převést a zároveň (pokud je to žádané) na ně aplikovat nějakou projekci (perspektivní, ortogonální, atd).

Pro převod do clip space slouží projection matice (). Ta nám umožňuje objekt nejen posunout ale i otočit a změnit jeho měřítko. [3]

Tento prostor stále používá 4-dimenzionální homogenní souřadnice.

Normalized Device Coordinates (NDC)

NDC je jako clip space, ale po převodu z homogenních souřadnic do kartézských pomocí perspective divide (dělení ).

V OpenGL je to kostka .

Window / viewport space

Má velikost danou rozlišením okna a glDepthRange. Ve výchozím nastavení je to .

OpenGL převádí NDC do window space pomocí viewport transformace.

Warning
Počátek (origin) viewport space je vlevo dole a má ve výchozím nastavení má souřadnice . [5]
OpenGL handedness

NDC v OpenGL je left-handed. Nicméně v OpenGL panuje konvence, že world space a camera space jsou right-handed (např. s glm). K přechodu dochází překlopením směru osy použitím projekční matice (). [3] V OpenGL tedy platí:

Space Handedness

Local

záleží na modelu

 — 

 — 

 — 

World

typicky right-handed

doprava

nahoru

dozadu

View

typicky right-handed

doprava

nahoru

dozadu (do kamery)

Clip

left-handed

doprava

nahoru

dopředu

NDC

left-handed

doprava

nahoru

dopředu

Window

left-handed

doprava

nahoru

dopředu

Tip
Fun-fact: ve Vulkanu je NDC . A navíc je right-handed, takže souřadnice je vlevo nahoře, kdežto v OpenGL je vlevo dole. [7]

Pipeline (typy shaderů)

Při zvolání glDraw* se používá OpenGL pipeline, která se skládá z několika fází: [1]

vph07 pipeline
Obrázek 3. Diagram of the Rendering Pipeline [1]
Vertex specification

Fáze, kdy aplikace vytvoří popis vertexových dat, která posléze předá OpenGL. V téhle fázi se uplatňují Vertex Array Objecty (VAO) a Vertex Buffer Objecty (VBO).

Vertex shader (VS)

Umožňuje programátorovi upravit data per vertex. Je spuštěn jednou, paralelně pro každý vertex.

Tesselation

Volitelně umožňuje předaný patch rozdělit na více menších patchů (subdivision). Skládá se z:

  • Tesselation Control Shader (TSC): spuštěn jednou per patch a definuje míru, do jaké je patch rozdělen.

  • Tesselation Evaluation Shader (TES): je pak zodpovědný za interpolaci dat pro každý nový vertex.

Geometry shader (GS)

Volitně umožňuje upravit / dogenerovat (teselovat) data per primitive. Je spušten jednou per primitive. Je mocnější než tesselation, ale tím pádem i méně efektivní.

Vertex post-processing

OpenGL následně: [2]

  1. sestaví primitives,

  2. ořeže je podle user clip space (nastavené programátorem v VS nebo GS pomocí gl_ClipDistance),

  3. provede perspective divide — převede je do NDC:

  4. převede je do window / viewport space:

    void glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
    void glDepthRange(GLdouble nearVal, GLdouble farVal);
    void glDepthRangef(GLfloat nearVal, GLfloat farVal);
  5. předá je do fragment shaderu.

Rasterization

Proces, kdy si OpenGL musí uvědomit, které fragmenty (jeden nebo více pixelů, pokud je zapnutý multisampling) jsou pokryty primitivem.

Fragment shader (FS)

Umožňuje programátorovi nastavit, co se stane s každým fragmentem — nastavit mu barvu, hloubku, atd. Je spuštěn jednou, paralelně pro každý fragment. Data z VS jsou interpolována.

Per-sample operations

Řada operací, která rozhoduje jak a jestli vůbec bude fragment vykreslen. Patří sem:

  • test "vlastnictví" — OpenGL nebude vykreslovat před cizí okna,

  • scissor test — zahodí fragmenty, které nejsou ve vytyčené oblasti,

  • stencil test — zahodí fragmenty, které neprojdou testem na stencil buffer — umožňuje např. implementovat Portal effect,

  • test hloubky — zahodí fragmenty, které jsou zakryty jinými fragmenty,

    Tip
    Tenhle test se nemusí nutně stát až po FS. OpenGL se dá nastavit tak, aby provedlo early depth test před spuštěním FS.
  • color blending a bitwise operace.

Compute shader

Shader, který není součástí vykreslovácí pipeline, neboť neslouží k vykreslování ale obecným výpočtům na GPU.

Shadow mapy

Important
Renderování stínů se věnuje také otázka Pokročilá počítačová grafika.
  1. Vytvoř shadow mapu — vyrenderuj scénu z pohledu světla a ulož hloubku do Z-bufferu.

  2. Stínování — vyrenderuj scénu jako obvykle, ale aplikuj shadow mapu

    1. Transformuj aktuální pixel do light-space souřadnic.

    2. Porovnej aktuální hloubku s hloubkou v shadow mapě.

    3. Změň osvětlení na základě porovnání.

vph07 shadow maps
Obrázek 4. The Shadow Mapping Depth Comparison [12]
  • Jednoduché na implementaci, ale v základu má artefakty, které je potřeba vyřešit.

  • Vyžaduje alespoň dva průchody scénou.

  • Rozlišení shadow mapy limituje kvalitu stínů.

Shadow acne

Problém shadow map, kdy objekty mylně vrhají stíny samy na sebe.

Řeší se vykreslováním jen back-sided polygonů (glCullFace(GL_FRONT)), a nebo biasem — srovnáním hloubky s malým biasem / posunem (obvykle epsilon).

vph07 shadow acne
Peter Panning

Když to s tím biasem přeženeme a objekty se začnou vznášet.

No tak, trošku jsem si zapřeháněl.

— Učitel
Vyšetřování ztráty třídní knihy (1967)
Aliasing

Stíny mají "schodovité" hrany.

Warping

Když shadow mapy nejsou samplovány uniformně, ale tak aby místa blíže ke kameře byla pokryta hustěji.

Cascaded Shadow Maps

Pokrývají blízké oblasti scény více texely pomocí textur s různými rozlišeními, ve snaze bojovat proti aliasingu.

vph07 cascaded shadow maps
Soft shadow maps — Percentage-Closer Filtering (PCF)

Rozmazává stíny uniformě fixním kernelem. [13]

vph07 soft shadows pcf
Soft shadow maps — Percentage-Closer Soft Shadows (PCSS)

Počítá šíři penumbry pomocí velikosti světla, odhadu vzdálenosti blockeru (světlo-blokujícího objektu) od světla, a vzdálenosti mezi recieverem (objektem na který světlo dopadá) a blockerem. [13]

vph07 soft shadows pcss

Deferred shading / odložené stínování

Místo renderování přímo na obrazovku, vykreslíme scénu nejprve do textur (geometry pass), které označujeme jako G-buffer — pozice, normály, barvy atd. Osvětlení je počítáno v odděleném průchodu (lighting pass) a vykresleno na obrazovku. [8]

Tuto techniku použijeme např. když máme ve scéně fakt hodně světel.

vph07 deferred shading
Important

Výhody:

  • osvětlení je počítáno jen jednou pro každý pixel,

  • můžeme mít více světel,

  • vyhodnocujeme méně různých kombinací materiálů a světel,

  • hodí se i na další post-process efekty.

Warning

Nevýhody:

  • vzdáváme se multisamplingu (resp. musíme nejprve použít edge detection, aby multisampling fungoval správně),

  • ztěžuje implementaci průhledných materiálů,

  • vyžaduje více paměti,

  • materiály nesmí být příliš komplikované kvůli omezeným možnostem paměti.

Screen space effects / efekty prostoru obrazu

Anti-aliasing

Aliasing

Aliasing vzniká, když je sample rate nižší než Nyquist frequency. Projevuje se jako nová nízko-frekvenční informace, která v obrazu neexistuje. Při renderování se projevuje jako "schody" na hranách objektů.

vph07 aliasing
Obrázek 5. Aliasing [9]
Anti-aliasing

Anti-aliasing jsou techniky, které zvyšují "samplovací frekvenci" renderování, a tak pomáhání eliminovat aliasing.

Super sample anti-aliasing (SSAA)

Vyrenderujeme scénu v mnohem vyšším rozlišení a pak ji downscalujeme. Nevýhodou je, že počítáme mnohem více fragmentů.

Multisample anti-aliasing (MSAA)

Pro každý pixel máme 2/4/8/…​ subsamply. Každý fragment počítáme jen jednou, ale podle toho, kolik subsamplů ho pokrývá, ho blendujeme s již existují barvou.

vph07 msaa
Obrázek 6. MSAA [9]

Ambient occlusion

Ambient occlusion approximuje, jak moc je objekt vystaven ambientním světlu. Jinými slovy jak moc by měl být objekt v daném místě tmavý kvůli okolním objektům. Pokud používáme ray-tracing máme ambient occlusion "zadarmo", jelikož paprsky narazí na okolní objekty. Pokud nemáme ray tracing, můžeme použít nějakou fintu.

vph07 ambient occlusion
Obrázek 7. NVidia HBAO+
Screen-Space Ambient Occlusion (SSAO)

Dívá se na okolí daného pixelu (v G-bufferu) a odhaduje tak jeho okluzi.

vph07 ssao
Obrázek 8. SSAO [11]