Vykreslování s využitím GPU
|
Note
|
Principy OpenGL, souřadnicové prostory (prostor objektu, prostor světa, prostor kamery, ořezávací prostor a normalizovaný prostor zařízení). Typy shaderů a jejich použití ve hrách (vertex, fragment, geometry, compute, teselační). Technika stínových map. Principy odloženého stínování. Ambientní okluze v prostoru obrazovky. 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.
— KhronosOpenGL 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.
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. |
- 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 / ořezávací prostor
-
OpenGL očekává, že všechno, co bude vykresleno, se po vertex shaderu nachází v jistém objemu — clip space. Souřadnice jsou zde stále homogenní, tedy mají čtyři složky . Primitiva mimo kanonický objem , , jsou ořezána, aby se dál nerasterizovalo nic, co kamera nemůže vidět.
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) / normalizovaný prostor zařízení
-
NDC je clip space po převodu z homogenních souřadnic do kartézských pomocí perspective divide (dělení ). Je to normalizovaný mezikrok nezávislý na konkrétním rozlišení okna.
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.
WarningPočá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
TipFun-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]
- 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)
-
Volitelně umožňuje upravit / dogenerovat data per primitive. Je spuštěn jednou pro celé primitivum a na vstupu typicky dostane bod, čáru nebo trojúhelník včetně jeho vrcholů. Na výstupu může primitivum zahodit, změnit, nebo emitovat nová primitiva, takže se hodí třeba pro billboarding, vizualizaci normál, jednoduché procedurální doplnění geometrie či výběr vrstvy pro renderování do cube mapy. Je flexibilní, ale často pomalejší než specializovanější fáze pipeline, takže se nepoužívá na masivní teselaci.
- Vertex post-processing
-
OpenGL následně: [2]
-
sestaví primitives,
-
ořeže je podle user clip space (nastavené programátorem v VS nebo GS pomocí
gl_ClipDistance), -
provede perspective divide — převede je do NDC:
-
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); -
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,
TipTenhle 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. |
-
Vytvoř shadow mapu — vyrenderuj scénu z pohledu světla a ulož hloubku do Z-bufferu.
-
Stínování — vyrenderuj scénu jako obvykle, ale aplikuj shadow mapu
-
Transformuj aktuální pixel do light-space souřadnic.
-
Porovnej aktuální hloubku s hloubkou v shadow mapě.
-
Změň osvětlení na základě porovnání.
-
-
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).
- 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.
- Soft shadow maps — Percentage-Closer Filtering (PCF)
-
Rozmazává stíny uniformě fixním kernelem. [12]
- 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. [12]
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.
|
Important
|
Výhody:
|
|
Warning
|
Nevýhody:
|
Screen space effects / efekty prostoru obrazu
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.
- Screen-Space Ambient Occlusion (SSAO)
-
Dívá se na okolí daného pixelu (v G-bufferu) a odhaduje tak jeho okluzi.
Obrázek 6. SSAO [10]
Zdroje
-
[5]
glViewport -
[6]
glDepthRange -
[10] LearnOpenGL: SSAO
-
[12] Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021)