Transpiled SZMGR content to markdown
The tool is called "downdoc"
This commit is contained in:
parent
01beaa369a
commit
8450eb5b8d
@ -34,13 +34,83 @@ export default defineConfig({
|
||||
],
|
||||
sidebar: [
|
||||
{
|
||||
label: 'SZMGR',
|
||||
autogenerate: {
|
||||
directory: "szmgr"
|
||||
}
|
||||
label: "General",
|
||||
items: [
|
||||
{ link: "/szmgr", label: "Home" },
|
||||
{ link: "/szmgr/guidelines", label: "Guidelines" }
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'Společný základ programu',
|
||||
items: [
|
||||
"szmgr/szp01_algoritmy",
|
||||
"szmgr/szp02_numericke_metody",
|
||||
"szmgr/szp03_statistika",
|
||||
"szmgr/szp04_3d_modelovani",
|
||||
"szmgr/szp05_krivky_a_povrchy",
|
||||
"szmgr/szp06_strojove_uceni",
|
||||
"szmgr/szp07_grafy",
|
||||
"szmgr/szp08_modelovani_a_projekce",
|
||||
"szmgr/szp09_zpracovani_obrazu",
|
||||
"szmgr/szp10_analyza_obrazu",
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Vývoj počítačových her',
|
||||
items: [
|
||||
"szmgr/vph01_graficke_principy_ve_vyvoji_her",
|
||||
"szmgr/vph01_pokrocila_grafika",
|
||||
"szmgr/vph02_fyzikalni_principy_ve_vyvoji_her",
|
||||
"szmgr/vph02_graficke_a_fyzikalni_principy",
|
||||
"szmgr/vph03_herni_design_i",
|
||||
"szmgr/vph04_herni_design_ii",
|
||||
"szmgr/vph05_vyvoj_her",
|
||||
"szmgr/vph06_ai_ve_hrach",
|
||||
"szmgr/vph07_gpu_rendering",
|
||||
"szmgr/vph08_modelovani_3d_postav",
|
||||
]
|
||||
},
|
||||
{
|
||||
label: 'Počítačová grafika a vizualizace',
|
||||
items: [
|
||||
"szmgr/pgv01_zaklady_vizualizace",
|
||||
"szmgr/pgv02_metody_vizualizace",
|
||||
"szmgr/pgv03_zaklady_pocitatcove_grafiky",
|
||||
"szmgr/pgv04_geometricke_algoritmy",
|
||||
"szmgr/pgv05_deleni_prostoru_a_sceny",
|
||||
"szmgr/pgv06_vykreslovani_objemovych_dat",
|
||||
"szmgr/pgv07_modely_osvetleni",
|
||||
"szmgr/pgv08_real_time_rendering",
|
||||
"szmgr/pgv09_minimalizace_energie",
|
||||
"szmgr/pgv10_zpracovani_obrazu_pomoci_pde",
|
||||
"szmgr/pgv_zpracovani_obrazu_intro",
|
||||
|
||||
|
||||
]
|
||||
},
|
||||
|
||||
],
|
||||
}),
|
||||
],
|
||||
});
|
||||
// PGV01_zaklady_vizualizace.md
|
||||
// PGV02_metody_vizualizace.md
|
||||
// PGV03_zaklady_pocitatcove_grafiky.md
|
||||
// PGV04_geometricke_algoritmy.md
|
||||
// PGV05_deleni_prostoru_a_sceny.md
|
||||
// PGV06_vykreslovani_objemovych_dat.md
|
||||
// PGV07_modely_osvetleni.md
|
||||
// PGV08_real_time_rendering.md
|
||||
// PGV09_minimalizace_energie.md
|
||||
// PGV10_zpracovani_obrazu_pomoci_PDE.md
|
||||
// PGV_zpracovani_obrazu_intro.md
|
||||
// VPH01_graficke_principy_ve_vyvoji_her.md
|
||||
// VPH01_pokrocila_grafika.md
|
||||
// VPH02_fyzikalni_principy_ve_vyvoji_her.md
|
||||
// VPH02_graficke_a_fyzikalni_principy.md
|
||||
// VPH03_herni_design_i.md
|
||||
// VPH04_herni_design_ii.md
|
||||
// VPH05_vyvoj_her.md
|
||||
// VPH06_ai_ve_hrach.md
|
||||
// VPH07_gpu_rendering.md
|
||||
// VPH08_modelovani_3d_postav.md
|
@ -5,6 +5,13 @@ description: Notes (mostly in Czech) from the Faculty of Informatics of Masaryk
|
||||
|
||||
Notes (mostly in Czech) from the [Faculty of Informatics of Masaryk University](https://www.fi.muni.cz) in Brno. Source files are available on GitHub. Contributions are welcome!
|
||||
|
||||
# Contents
|
||||
|
||||
> [!NOTE]
|
||||
> Work in progress!
|
||||
|
||||
- [SZMGR Státní zkouška (magisterský studijní program)](/szmgr)
|
||||
|
||||
## Thesis Checklist
|
||||
|
||||
> [!TIP]
|
||||
|
@ -1,6 +0,0 @@
|
||||
---
|
||||
title: MGR State exam
|
||||
description: A reference page in my new Starlight docs site.
|
||||
---
|
||||
|
||||
# SZMGR
|
190
src/content/docs/szmgr/PGV01_zaklady_vizualizace.md
Normal file
190
src/content/docs/szmgr/PGV01_zaklady_vizualizace.md
Normal file
@ -0,0 +1,190 @@
|
||||
---
|
||||
title: "Základy vizualizace"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Základní metriky pro hodnocení kvality vizualizace, vizuální proměnné. Základní vizualizační techniky pro 1D, 2D, 3D a 4D data. Objemová data – vizualizace explicitních a implicitních povrchů. Geovizualizace – choropletové mapy, kartogramy.
|
||||
|
||||
_PV251, PA214_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
Neexistuje jednotná definice vizualizace, ale může to být například "Proces předávání dat grafickou formou", nebo "Nástroj, který umožňuje uživateli vhled do dat".
|
||||
|
||||
## Základní metriky pro hodnocení kvality vizualizace
|
||||
|
||||
Pro hodnocení kvality vizualizace můžeme použít následující metriky, které se snažíme maximalizovat.
|
||||
|
||||
### Efektivita (Effectiveness)
|
||||
|
||||
Efektivita je vysoká, pokud je
|
||||
|
||||
1. Správně a rychle interpretována
|
||||
2. Rychle vyrenderována
|
||||
|
||||
$M_{eff} = \frac{1}{1 + \text{interpret} + \text{render}}$, kde $0 \leq M_{eff} \leq 1$.
|
||||
|
||||
Pokud je $M_{eff} \sim 1$, pak je čas na interpretaci a renderování krátký.
|
||||
|
||||
### Expresivita (Expressiveness)
|
||||
|
||||
$M_{exp} = \frac{\text{displayed information}}{\text{information to be expressed}}$, kde $0 \leq M_{exp} \leq 1$.
|
||||
|
||||
- Pokud je $M_{exp} = 1$, pak je expresivita ideální.
|
||||
- Pokud je $M_{exp} < 1$, pak zobrazujeme méně informací, než jsme zamýšleli.
|
||||
- Pokud je $M_{exp} > 1$, pak zobrazujeme více informací, než bychom měli.
|
||||
|
||||
## Vizuální proměnné
|
||||
|
||||
Vizuální proměnné se snaží maximalizovat efektivitu a expresivitu vizualizace. Základní vizuální proměnné definuje Bertin a jsou to:
|
||||
|
||||

|
||||
|
||||
### Pozice
|
||||
|
||||
Best case: Každý bod má jednoznačnou pozici.\
|
||||
Worst case: Všechny body se překrývají.
|
||||
|
||||
Lineární vs. logaritmická škála
|
||||
|
||||
### Velikost
|
||||
|
||||
Bývá problematické rozlišit velikost, pokud je rozdíl malý.
|
||||
|
||||
### Tvar
|
||||
|
||||
Může být použit pro kategorické proměnné. Tvar zahrnují i písmena, typy čar, atd.
|
||||
|
||||
### Jas (value)
|
||||
|
||||
Podobně, jako u velikosti je obtížné rozlišit jas, pokud je rozdíl malý.
|
||||
|
||||
### Barva (hue)
|
||||
|
||||
Lze použít pro kategorické i numerické proměnné.
|
||||
|
||||
**Numerické proměnné:**
|
||||
|
||||
Je důležité vybrat správnou barevnou škálu. Důležité je myslet na čitelnost i pro barvoslepé.
|
||||
|
||||

|
||||
|
||||
Ve zdravotnictví se často používá "Rainbow color scale", která ale může vytvářet neexistující rozhraní kolem některých barev, neboť není "perceptually uniform".
|
||||
|
||||

|
||||
|
||||
**Kategorické proměnné:**
|
||||
|
||||
Je důležité vybrat vhodnou paletu barev, která bude snadno rozlišitelná. Více, jak cca 12 barev je v podstatě nemožné spolehlivě rozlišit.
|
||||
|
||||
### Orientace
|
||||
|
||||
### Textura
|
||||
|
||||
### Pohyb
|
||||
|
||||
Někdy se přidává k základním 7 vizuálním proměnným. Lze ho připojit k jakékoli z vizuálních proměnných.
|
||||
|
||||
## Základní vizualizační techniky prostorových dat
|
||||
|
||||
<dl><dt><strong>💡 TIP</strong></dt><dd>
|
||||
|
||||
V téhle otázce se autor pravděpodobně maličko jinak kouká na to, co znamená dimenze dat, než je uvedeno ve slidech z PV251. Zde se dimenze dat chápe jako počet proměnných, nikoliv jako počet prostorových dimenzí. Zde uvedená 1D prostorová data mají tedy 2 a více dimenzí, 2D prostorová data mají 3 a více dimenzí a 3D prostorová data mají 4 a více dimenzí.
|
||||
|
||||
</dd></dl>
|
||||
|
||||
### 0D (neprostorová) data
|
||||
|
||||
Množina hodnot, které nemají žádnou prostorovou interpretaci.
|
||||
|
||||
**Numerické proměnné:**
|
||||
|
||||
- **Histogram** (seskupíme hodnoty do intervalů a zobrazíme počet hodnot v každém intervalu)
|
||||
|
||||
**Kategorické proměnné:**
|
||||
|
||||
- **Bar chart** (každá kategorie má svůj sloupec, nebo pruh)
|
||||
- **Pie chart** (kruhový graf, kde každá kategorie má svůj podíl na celku)
|
||||
|
||||
### 1D prostorová data
|
||||
|
||||
Sekvence jednodimenzionálních dat s jednou proměnnou.
|
||||
|
||||
- **Graf**
|
||||
- **Barevný pruh**
|
||||
|
||||

|
||||
|
||||
Pro více proměnných lze použít **Juxtapositioning = Postavení vedle sebe** (více grafů vedle sebe, např. více barevných pruhů pod sebou) a **Superimpositioning = Překrývání** (více dat v jednom grafu, např. více různobarevných čar v jednom grafu).
|
||||
|
||||
### 2D prostorová data
|
||||
|
||||
- **Scatter plot** (body rozmístěné ve 2D prostoru, proměnné zobrazujeme barvou, tvarem, velikostí, ...)
|
||||
- **Mapa** (podobně, jako scatterplot, jen používáme jako podklad mapu a skutečné geografické souřadnice, navíc může používat nejen body, ale i čáry a plochy)
|
||||
- **Obrázek** (proměnné se mapují na barvu / jas v obrázku, hodnoty mezi datovými body interpolujeme)
|
||||
- **Cityscape** (3D bar chart, kde výška sloupce reprezentuje hodnotu proměnné)
|
||||
- **Vrstevnice, izobary** (pro zobrazování 2D povrchů)
|
||||
|
||||

|
||||
|
||||
Pro více proměnných:
|
||||
|
||||
- Juxtapositioning: naskládáme na sebe více 2D vizualizací, takže vytvoříme 3D vizualizaci
|
||||
- Superimpositioning: Překrýváme 2D vizualizace, např. pomocí barvy
|
||||
|
||||
2D data je často třeba zjednodušit, např. pomocí agregace, nebo pomocí vizualizace hustoty (histogram).
|
||||
|
||||
### 3D prostorová data
|
||||
|
||||
- Vizualizace explicitních povrchů (seznam vrcholů, hran a ploch)
|
||||
- Implicitní povrchy (zero-contour funkce, která definuje, kde je "uvnitř" a "vně" objektu, chceme vykreslit povrch tam, kde je funkce nulová)
|
||||
- Volumetrické vizualizace
|
||||
|
||||
## Volumetrické vizualizace
|
||||
|
||||
Využíváme voxely (3D datové body), kde každý voxel má hodnotu (nebo více hodnot).
|
||||
|
||||
Pokud nejsou datové body na mřížce, použijeme tzv. **Resampling** (převzorkování) - interpolace hodnot mezi body.
|
||||
|
||||
### Slicing
|
||||
|
||||
Použijeme rovinu (nebo více rovin), pomocí které provedeme řez objektem. Efektivně tím snižujeme počet dimenzí. Jednotlivé řezy potom můžeme znovu zobrazit ve 3D, připadně umožnit uživateli s nimi interagovat.
|
||||
|
||||

|
||||
|
||||
### Isosurface
|
||||
|
||||
Vytvoříme povrch, kde hodnota je konstantní. Na vytvoření isosurface můžeme použít algoritmy jako Marching Cubes.
|
||||
|
||||
### Direct volume rendering
|
||||
|
||||
Vykreslíme objemová data přímo. Můžeme použít různé techniky, jako např. ray casting, nebo splatting.
|
||||
Detailní fungování je popsané v otázce [PGV06](../PGV06_vykreslovani_objemovych_dat).
|
||||
|
||||
## Geovizualizace
|
||||
|
||||
Mohou zobrazovat nejen body, ale i čáry a plochy.
|
||||
|
||||
### Choropletové mapy
|
||||
|
||||
Zobrazení hodnoty pro jednotlivé plochy (státy, okresy, ...). Barva plochy reprezentuje hodnotu proměnné. Barva může být buď numerická, nebo kategorická (i kategorizovaná numerická).
|
||||
|
||||
Problémem mohou být malé oblasti, které jsou na výsledné mapě tak malé, že z nich nic nevyčteme (například hustě osídlené oblasti).
|
||||
|
||||

|
||||
|
||||
### Kartogramy
|
||||
|
||||
Snaha potlačit problémy choroletových map. Měníme velikost regionu v závislosti na hodnotě proměnné.
|
||||
|
||||
Kartogramy jsou několika typů:
|
||||
|
||||
1. **Nekontinuální (Noncontinuous) kartogramy** - Nezachovávají topologii, regiony jsou naškálované uvnitř původních oblastí, které omezují maximální zvětšení
|
||||
2. **Nesouvislé (Noncontiguous) kartogramy** - Škálujeme polygony na požadovanou velikost, polygony tak nezachovávají globální topologii a sousednost
|
||||
3. **Kontinuální (Continuous) kartogramy** - Zachovávají topologii, mění tvar regionů, ale zachovávají sousednost. Ze všech kartogramů nejlépe zachovávají globální topologii.
|
||||
4. **Kruhové (Circular) kartogramy** - Každý region je nahrazen kruhem, jehož velikost reprezentuje hodnotu proměnné
|
||||
5. **Obdélníkové (Rectangular) kartogramy** - Každý region je nahrazen obdélníkem, jehož velikost reprezentuje hodnotu proměnné, snaha umístit obdélník co nejblíž původní pozici.
|
||||
|
||||

|
137
src/content/docs/szmgr/PGV02_metody_vizualizace.md
Normal file
137
src/content/docs/szmgr/PGV02_metody_vizualizace.md
Normal file
@ -0,0 +1,137 @@
|
||||
---
|
||||
title: "Metody vizualizace"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Vizualizace multidimenzionálních dat – scatterplot matrix, paralelní souřadnice, skládání dimenzí. Vizualizace hierarchických struktur – treemaps, radiální techniky. Základní třídy interakčních technik, techniky používané v prostoru obrazovky, objektu, dat, datových struktur.
|
||||
|
||||
_PV251, PA214_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
## Vizualizace multidimenzionálních dat
|
||||
|
||||
Vizualizace multidimenzionálních dat řeší, jak vizualizovat data, která pro jediný datový záznam obsahují více informací (např. výška, váha, velikost bot).
|
||||
|
||||
### Scatterplot matrix
|
||||
|
||||
Scatterplot matrix zobrazuje scatterplot pro každé dva zaznamenané parametry v tabulce.
|
||||
|
||||
Scatterplot je graf, který zobrazuje hodnoty dvou proměnných v souřadnicovém systému. Na diagonále jsou typicky zobrazeny histogramy jednotlivých proměnných, nebo jejich popis. Ve scatterplot matrixu je každý scatterplot zobrazený dvakrát, pouze překlopený podle hlavní diagonály.
|
||||
|
||||

|
||||
|
||||
### Paralelní souřadnice
|
||||
|
||||
Paralelní souřadnice je vizualizační technika, která umožňuje zobrazit vícerozměrná data v rovině. Jednotlivé dimenze jsou zobrazeny jako osy, které jsou rovnoběžné. Jednotlivé záznamy jsou zobrazeny jako čáry, které spojují hodnoty jednotlivých dimenzí.
|
||||
|
||||
U paralelních souřadnic je důležité seřazení dimenzí. Při špatném seřazení jsou data velmi špatně čitelná. Chceme co nejvíce clusterů čar, které vedou podobným směrem.
|
||||
|
||||

|
||||
|
||||
### Skládání dimenzí
|
||||
|
||||
Skládání dimenzí je technika, která umožňuje zobrazit vícerozměrná data v rovině. Při skládání dimenzí vybereme dvě dimenze, které položíme v mřížce na osy X a Y. Do každého pole v této mřížce nyní provedeme stejnou operaci pro další dvě dimenze. Tento proces opakujeme, dokud nejsou zobrazeny všechny dimenze (vyjma jedné závislé). Poslední závislá dimenze je zobrazena jako barva.
|
||||
|
||||

|
||||
|
||||
## Vizualizace hierarchických struktur
|
||||
|
||||
Některá data mohou být hierarchicky uspořádána. Vizualizace hierarchických struktur se snaží zobrazit tuto hierarchii. (např. souborový strom, kategorie a podkategorie).
|
||||
|
||||
### Treemaps
|
||||
|
||||
Rekurzivně rozdělujeme obdélník střídavě horizontálními a vertikálními čarami podle hodnoty daného parametru. Obdélníky v treemapách je možné "zhranatit", nebo nechat podlouhlé.
|
||||
|
||||

|
||||
|
||||
### Sunburst
|
||||
|
||||
Způsob zobrazení hierarchie, kde uprostřed jsou kořenové prvky a okolo nich jsou zanořené prvky. Každé úroveň je zobrazena jako nezikruží rozsekané na menší kousky. "Tloušťka" každé výseče určuje hodnotu parametru.
|
||||
|
||||

|
||||
|
||||
### Další techniky
|
||||
|
||||
Node-link diagram, Tree (Klasické zobrazení), Radial Tree (Sunburst, ale strom), Cone Tree (3D), ...
|
||||
|
||||
## Interakční techniky
|
||||
|
||||
### Základní kategorie
|
||||
|
||||
- **Navigace**\
|
||||
změna pozice kamery, škálování, rotace; automatická, nebo ovládaná uživatelem
|
||||
- **Výběr**\
|
||||
výběr objektů, oblasti (laso, klikání, vyhledávání) a následná interakce (zvýraznění, smazání, skrytí)
|
||||
- **Filtrování**\
|
||||
redukce množství zobrazených objektů (slidery, skrývání sloupců, ...); filtrace je nepřímá (před vykreslením dat), výběr je přímý (přímo ve vizualizaci)
|
||||
- **Rekonfigurace**\
|
||||
změna mapování dat na grafické atributy (řazení sloupců); snížení počtu dimenzí pomocí PCA (principal component analysis), MDS (multidimensional scaling), ...; Snaha zachovat vztahy mezi daty při snížení dimenzí
|
||||
- **Změna kódování**\
|
||||
tweaking grafických atributů atributů (barvy, velikosti, tvaru, ...); více pohledů na stejná data
|
||||
- **Spojení**\
|
||||
interakce napříč více pohledy (společný výběr pro více vizualizací, filtrování napříč vizualizacemi, ...)
|
||||
- **Abstrakce/specifikace**\
|
||||
změna detailnosti zobrazení (lupa na specifickou část dat, zkreslení [distortion])
|
||||
- **Hybridní techniky**\
|
||||
kombinace více technik
|
||||
|
||||
Tyto interakce můžeme aplikovat na různé operandy. Operand interakce je prostor, na který interakci aplikujeme.
|
||||
|
||||
<dl><dt><strong>💡 TIP</strong></dt><dd>
|
||||
|
||||
Rozdělení mi není úplně 100% jasné, takže budu rád za opravy. Celé slidy čerpají z knihy Interactive Data Visualization: Foundations, Techniques, and Applications, Second Edition (dostupné z [Anna’s Archive](https://annas-archive.org/md5/0bf49e061a8b82167d0e05a5d2b50476))
|
||||
|
||||
</dd></dl>
|
||||
|
||||
### Techniky pro prostor obrazovky (Pixely)
|
||||
|
||||
- **Výběr pixelů**\
|
||||
Vybíráme jednotlivé body obrazovky (obdélník, laso, ...)
|
||||
- **Zkreslení**\
|
||||
Mapování pixelů na jiné pixely (zoom, lupa, ...) $(x', y') = f(x, y)$. Zkreslení mohou způsobit kolizi pixelů, nebo naopak díry, které musíme vyřešit interpolací.
|
||||
- **Rybí oko**\
|
||||
Zvětšení jednoho místa na obrazovce, v podstatě "odstrkujeme pixely" od vybraného bodu $(c_x, c_y)$ logaritmicky podle vzdálenosti od tohoto bodu a síly zkreslení $d$.
|
||||
|
||||

|
||||
|
||||
### Techniky pro prostor hodnot
|
||||
|
||||
Aplikujeme transformaci hodnot na jednotlivé proměnné.
|
||||
|
||||
- **Filtrování**\
|
||||
Skrývání některých datovách záznamů, nebo celých dimenzí.
|
||||
- **Řazení**
|
||||
- **Zkreslení (transformace)**\
|
||||
Například škálování, posun. $(d_0', d_1', \dots, d_n') = (j_0(d_0), j_1(d_1), \dots, j_n(d_n))$
|
||||
|
||||

|
||||
|
||||
### Techniky pro datové struktury (Organizace dat)
|
||||
|
||||
Měníme pouze organizaci dat, nikoliv data samotná.
|
||||
|
||||
- **Zoom**\
|
||||
Načtení detailnějších dat místo manipulace s pixely.
|
||||
- **Výběr**\
|
||||
Výběr celých sekcí (např. jedna větev)
|
||||
- **Filtrování**\
|
||||
Podle struktury dat (jen konkrétní větev stromu, konkrétní čas, ...)
|
||||
- **Řazení**\
|
||||
Typicky problematické u paralelních souřadnic, kde špatné řazení může způsobit, že data nebudou čitelná. Může být buď plně manuální, nebo algoritmické (pak je třeba najít měřítko vhodnosti).
|
||||
|
||||
### Techniky pro prostor atributů
|
||||
|
||||
- **Filtrování**\
|
||||
Skrývání některých atributů, nebo jejich zvýraznění
|
||||
- **Změna kódování**\
|
||||
Úprava barevné škály, barev, ...
|
||||
|
||||
### Techniky pro objekt (3D povrch)
|
||||
|
||||
- **Navigace**\
|
||||
Otáčení, kamera, ...
|
||||
- **Perspective walls**\
|
||||
Vizualizační metoda pro navigaci ve velkém množství dat.
|
385
src/content/docs/szmgr/PGV03_zaklady_pocitatcove_grafiky.md
Normal file
385
src/content/docs/szmgr/PGV03_zaklady_pocitatcove_grafiky.md
Normal file
@ -0,0 +1,385 @@
|
||||
---
|
||||
title: "Základy počítačové grafiky"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
OpenGL blokový diagram, GLSL – vertex a fragment shader. Vytvoření GLSL programu. Základní typy vstupních a výstupních proměnných. Druhy grafických primitiv. Vertex Buffer Objects a Vertex Array Objects. Princip rasterizace, framebuffer. Textury: mapování, filtrování, syntéza.
|
||||
|
||||
_PB009, PA010, PV112, PV227_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
## OpenGL blokový diagram
|
||||
|
||||

|
||||
|
||||
Blokový diagram je abstraktní, high-level popis fungování OpenGL [pv112](#pv112).
|
||||
|
||||
- **_Evaluators_** - aproximace křivek a povrchů
|
||||
- **_Per-vertex operations_** - operace prováděné nad každým vrcholem - transformace, projekce z [model space do camera space](../modelovani-a-projekce), osvětlení jednotlivých vrcholů
|
||||
- **_Primitive assembly_** - sestavení primitiv (body, čáry, trojúhelníky) z vrcholů, projekce do screen space a ořezání
|
||||
- **_Rasterization_** - převod primitiv na fragmenty (2D obdélníky s informací o barvě, hloubce, ...) a interpolace hodnot mezi vrcholy
|
||||
- **_Per-fragment operations_** - operace prováděné nad každým fragmentem a jejich uložení do frame bufferu - osvětlení, texturování, blending, testy (scissor, alpha, stencil, depth)
|
||||
- **_Pixel operations_** - operace nad pixely (škálování, konverze barev, ...), typicky se neprovádí při samotném renderu, ale při přípravě textur
|
||||
- **_Texture memory_** - po provedení pixel operations se výsledek uloží sem
|
||||
|
||||
Operace se provádějí paralelně na GPU a využívá se tzv. pipeliningu, kdy se jednotlivé operace provádějí postupně a nezávisle na sobě (_jakmile se uvolní místo v některém okýnku, můžou do něj přijít další data_).
|
||||
|
||||
## GLSL - vertex a fragment shader
|
||||
|
||||

|
||||
|
||||
Části původní pipeline můžeme nahradit Vertex a Fragment shadery. Shader je malý program, který se kompiluje a spouští na GPU. Výsledkem je, že můžeme upravit chování OpenGL pipeline podle svých potřeb.
|
||||
|
||||
- **_Vertex shader_** - program, který se spouští nad každým vrcholem. Můžeme zde provádět transformace, osvětlení, deformace, ...
|
||||
- **_Fragment shader_** - program, který se spouští nad každým fragmentem. Můžeme zde provádět osvětlení, texturování, blending, ...
|
||||
|
||||
GLSL shadery dohromady tvoří GLSL program, který se kompiluje a spouští na GPU. Paralelně lze spustit pouze jeden program na více vrcholech nebo fragmentech.
|
||||
|
||||
Každý shader může odsahovat jedinou funkci `main`, která se spustí nad každým vrcholem nebo fragmentem.
|
||||
|
||||
## Vytvoření GLSL programu
|
||||
|
||||
Vytvoření GLSL programu se skládá z několika kroků:
|
||||
|
||||
1. Vytvoření shaderových objektů
|
||||
- `glCreateShader`
|
||||
- Specifikujeme typ shaderu (`GL_VERTEX_SHADER`, `GL_FRAGMENT_SHADER`, `GL_GEOMETRY_SHADER`, `GL_TESS_CONTROL_SHADER`, `GL_TESS_EVALUATION_SHADER`, `GL_COMPUTE_SHADER`)
|
||||
- Dostaneme identifikátor shaderu
|
||||
- _Koupíme si flashdisk_
|
||||
2. Načtení zdrojového kódu shaderů
|
||||
- `glShaderSource`
|
||||
- Předáme identifikátor shaderu a zdrojový kód
|
||||
- _Nahrajeme zdrojáky na flashdisk_
|
||||
3. Kompilace shaderů
|
||||
- `glCompileShader`
|
||||
- Předáme identifikátor shaderu
|
||||
- _Zkompilujeme zdrojáky na flashdisku_
|
||||
4. Vytvoření programu
|
||||
- `glCreateProgram`
|
||||
- Dostaneme identifikátor programu
|
||||
- _Koupíme si počítač_
|
||||
5. Připojení shaderů k programu
|
||||
- `glAttachShader`
|
||||
- Předáme identifikátor programu a identifikátor shaderu
|
||||
- _Připojíme flashdisk k počítači_
|
||||
6. Linkování programu
|
||||
- `glLinkProgram`
|
||||
- Předáme identifikátor programu
|
||||
- _Nakopírujeme zkompilované programy ze všech připojených flashdisků na počítač_
|
||||
7. Cleanup
|
||||
- Po tomhle kroku už můžeme odpojit a smazat shadery
|
||||
- `glDetachShader`, `glDeleteShader`
|
||||
- _Odpojíme flashdisky a smažeme je_
|
||||
8. Informování OpenGL, že chceme použít tento program
|
||||
- `glUseProgram`
|
||||
- Předáme identifikátor programu
|
||||
- _Spustíme program na počítači_
|
||||
|
||||

|
||||
|
||||
## Základní typy vstupních a výstupních proměnných
|
||||
|
||||
### Podle způsobu předávání dat
|
||||
|
||||
- **_Vertex shader_**
|
||||
- `in` - vstupní proměnné, které se předávají z aplikace do shaderu
|
||||
- `out` - výstupní proměnné, které se předávají z vertex shaderu do fragment shaderu
|
||||
- `uniform` - konstantní proměnné, které se předávají z aplikace do shaderu
|
||||
- **_Fragment shader_**
|
||||
- `in` - vstupní proměnné, které se předávají z vertex shaderu do fragment shaderu
|
||||
- `out` - výstupní proměnné, které se předávají z fragment shaderu do framebufferu
|
||||
- `uniform` - konstantní proměnné, které se předávají z aplikace do shaderu
|
||||
|
||||
### Podle datového typu
|
||||
|
||||
- `float`, `double`, `int`, `uint`, `bool` - skalární typy
|
||||
- `vec2`, `vec3`, `vec4` - vektorové typy
|
||||
- `$vec2`, `§vec3`, `$vec4` - kde `$` je `b`, `i`, nebo `u` - vektory s boolean / celočíselnými / uint složkami
|
||||
- `mat2`, `mat3`, `mat4` - matice
|
||||
- `sampler1D`, `sampler2D`, `sampler3D`, `samplerCube` - textury
|
||||
- struktury, pole, ...
|
||||
- **Přístup k jednotlivým složkám vektoru**
|
||||
- `v.x`, `v.y`, `v.z`, `v.w`
|
||||
- `v.r`, `v.g`, `v.b`, `v.a`
|
||||
- `v.s`, `v.t`, `v.p`, `v.q`
|
||||
- `v[0]`, `v[1]`, `v[2]`, `v[3]`
|
||||
|
||||
Můžeme použít také tzv. swizzling, kdy můžeme vytvořit nový vektor z existujícího
|
||||
|
||||
`v.xy`, `v.zw`, `v.xxyy`, `v.zzzz`, ...
|
||||
|
||||
- **Struktury**
|
||||
|
||||
```glsl
|
||||
struct Light {
|
||||
vec3 position;
|
||||
vec3 color;
|
||||
float intensity;
|
||||
};
|
||||
```
|
||||
|
||||
Pozor na zarovnání struktur, které může způsobit problémy při předávání dat z CPU na GPU. Vždy definujeme standard, kterým se struktury zarovnávají:
|
||||
|
||||
```glsl
|
||||
struct Light {
|
||||
vec3 position;
|
||||
vec3 color;
|
||||
float intensity;
|
||||
};
|
||||
|
||||
layout(binding = 0, std140) uniform Lights {
|
||||
Light lights[10];
|
||||
};
|
||||
```
|
||||
|
||||
- **Pole**
|
||||
|
||||
```glsl
|
||||
float data[10];
|
||||
```
|
||||
|
||||
## Druhy grafických primitiv
|
||||
|
||||
- **_Body_** - `GL_POINTS`
|
||||
- **_Čáry_** - `GL_LINES`, `GL_LINE_STRIP`, `GL_LINE_LOOP`
|
||||
- **_Trojúhelníky_** - `GL_TRIANGLES`, `GL_TRIANGLE_STRIP`, `GL_TRIANGLE_FAN`
|
||||
|
||||

|
||||
|
||||
Typ primitivu nastavíme funkcí `glDrawArrays` nebo `glDrawElements` až při renderu.
|
||||
|
||||
## Vertex Buffer Objects a Vertex Array Objects
|
||||
|
||||

|
||||
|
||||
### Vertex Buffer Object (VBO)
|
||||
|
||||
VBO je místo v paměti GPU, kam ukládáme data vrcholů. VBO sám o sobě neobsahuje informace o struktuře dat, ale pouze data samotná.
|
||||
|
||||
### Vertex Array Object (VAO)
|
||||
|
||||
VAO je objekt, který obsahuje informace o struktuře dat v paměti GPU. VAO propojuje 1..n VBO a určuje, jak se mají data z VBO interpretovat. _VAO je tedy taková vazební tabulka m..n mezi daty uloženými ve VBO a binding pointy ve Vertex shaderu. Každé VBO může být napojené na libovolné množství VAO, ale každý binding point musí mít právě jeden VBO._
|
||||
|
||||
Na "vstupu" VAO (binding point) můžeme mít několik VBO, které obsahují různé atributy vrcholů (pozice, normály, barvy, ...). U každého vstupu nastavujeme offset a stride, které nás vždy odkáží na začátek dat pro každý jeden vrchol.
|
||||
|
||||
- **Příklad 1**
|
||||
|
||||
Naše data vypadají takto:
|
||||
|
||||
```
|
||||
Buffer 1:
|
||||
|
||||
Vertex 1 Vertex 2 Vertex 3
|
||||
+---+---+---+---+---+---++---+---+---+---+---+---+
|
||||
| X | Y | Z | R | G | B || X | Y | Z | R | G | B | ...
|
||||
+---+---+---+---+---+---++---+---+---+---+---+---+
|
||||
```
|
||||
|
||||
Pak chceme napojit naši strukturu na VBO takto:
|
||||
|
||||
```
|
||||
- Binding 0
|
||||
- Buffer: &buffer1
|
||||
- Offset: 0
|
||||
- Stride: 6 * sizeof(float)
|
||||
|
||||
* Attribute 0
|
||||
* Size: 3
|
||||
* Type: GL_FLOAT
|
||||
* Normalized: GL_FALSE
|
||||
* Offset: 0
|
||||
* Attribute 1
|
||||
* Size: 3
|
||||
* Type: GL_FLOAT
|
||||
* Normalized: GL_FALSE
|
||||
* Offset: 3 * sizeof(float)
|
||||
|
||||
Binding 0 => Attribute 0 (pozice)
|
||||
Binding 0 => Attribute 1 (barva)
|
||||
```
|
||||
|
||||
- **Příklad 2**
|
||||
|
||||
Naše data vypadají takto:
|
||||
|
||||
```
|
||||
Buffer 1:
|
||||
|
||||
Vertex 1 Vertex 2 Vertex n Vertex 1 Vertex 2
|
||||
+---+---+---++---+---+---+ +---+---+---++---+---+---++---+---+---+
|
||||
| X | Y | Z || X | Y | Z | ... | X | Y | Z || R | G | B || R | G | B | ...
|
||||
+---+---+---++---+---+---+ +---+---+---++---+---+---++---+---+---+
|
||||
|
||||
Buffer 2:
|
||||
|
||||
Vertex 1 Vertex 2
|
||||
+---+---++---+---+
|
||||
| U | V || U | V | ...
|
||||
+---+---++---+---+
|
||||
```
|
||||
|
||||
Pak chceme napojit naši strukturu na VBO takto:
|
||||
|
||||
```
|
||||
- Binding 0
|
||||
- Buffer: &buffer1
|
||||
- Offset: 0
|
||||
- Stride: 3 * sizeof(float)
|
||||
|
||||
* Binding 1
|
||||
* Buffer: &buffer1
|
||||
* Offset: 3 * sizeof(float) * n (number of vertices)
|
||||
* Stride: 3 * sizeof(float)
|
||||
* Binding 2
|
||||
* Buffer: &buffer2
|
||||
* Offset: 0
|
||||
* Stride: 2 * sizeof(float)
|
||||
* Attribute 0
|
||||
* Size: 3
|
||||
* Type: GL_FLOAT
|
||||
* Normalized: GL_FALSE
|
||||
* Offset: 0
|
||||
* Attribute 1
|
||||
* Size: 3
|
||||
* Type: GL_FLOAT
|
||||
* Normalized: GL_FALSE
|
||||
* Offset: 0
|
||||
* Attribute 2
|
||||
* Size: 2
|
||||
* Type: GL_FLOAT
|
||||
* Normalized: GL_FALSE
|
||||
* Offset: 0
|
||||
|
||||
Binding 0 => Attribute 0 (pozice)
|
||||
Binding 1 => Attribute 1 (barva)
|
||||
Binding 2 => Attribute 2 (uv souřadnice)
|
||||
```
|
||||
|
||||
## Princip rasterizace
|
||||
|
||||
Z Primitive assembly dostáváme bod, čáru, nebo trojúhelník, který potřebujeme převést na fragmenty (pixely, typicky čtvercové). Každému fragmentu přidělíme barvu a hloubku (Z-value) = fragment’s associated data. Fragment definujeme integerovými souřadnicemi jeho levého dolního bodu (pozor na 0.5 offset).
|
||||
|
||||
- **Bod**\
|
||||
Při rasterizaci bodu vykreslíme čtverec o hraně `gl_PointSize` zaokrouhlený na celé pixely.
|
||||
|
||||

|
||||
|
||||
- **Úsečka**\
|
||||
Při rasterizaci úsečky použijeme Bresenhamův algoritmus [pb009](#pb009). Poslední bod úsečky zůstane nevykreslený (half-open) kvůli návaznosti na další úsečky.
|
||||
|
||||
```cpp
|
||||
// From the solution of PB009
|
||||
|
||||
void Application::bresenham(glm::vec2 start, glm::vec2 end, Raster& raster, Color color) {
|
||||
// delta of exact value and rounded value of the dependent variable
|
||||
int D = 0;
|
||||
|
||||
// slopes
|
||||
const int dx = static_cast<int>(fabs(end.x - start.x));
|
||||
const int dy = static_cast<int>(fabs(end.y - start.y));
|
||||
|
||||
// slope scaling factors to avoid floating points
|
||||
const int dx2 = 2 * dx;
|
||||
const int dy2 = 2 * dy;
|
||||
|
||||
// increment direction
|
||||
const int ix = start.x < end.x ? 1 : -1;
|
||||
const int iy = start.y < end.y ? 1 : -1;
|
||||
|
||||
int x = static_cast<int>(start.x);
|
||||
int y = static_cast<int>(start.y);
|
||||
|
||||
if (dx >= dy) {
|
||||
while (true) {
|
||||
raster.set_pixel_color(x, y, color);
|
||||
if (x == end.x)
|
||||
break;
|
||||
x += ix;
|
||||
D += dy2;
|
||||
if (D > dx) {
|
||||
y += iy;
|
||||
D -= dx2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
while (true) {
|
||||
raster.set_pixel_color(x, y, color);
|
||||
if (y == end.y)
|
||||
break;
|
||||
y += iy;
|
||||
D += dx2;
|
||||
if (D > dy) {
|
||||
x += ix;
|
||||
D -= dy2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- **Trojúhelník**
|
||||
|
||||
Při rasterizaci trojúhelníku můžeme použít Pinedaův algoritmus [pb009](#pb009). Pro každý trojúhelník zjistíme jeho bounding box a pro každý pixel v bounding boxu pomocí edge function zjistíme, zda leží uvnitř trojúhelníku.
|
||||
|
||||
Edge function využívá vlastností dot-productu: $E_{ABP} = (A - B).x * (P - B).y - (A - B).y * (P - B).x$. Výsledek funkce může být kladný, záporný, nebo nulový. Pokud je výsledek kladný, bod leží vlevo od úsečky AB, pokud je záporný, bod leží vpravo od úsečky AB, pokud je nulový, bod leží na úsečce AB. Edge funkci můžeme zkontrolovat pro všechny hrany trojúhelníka a pokud se znaménka rovnají (akceptujeme 0 pro kladná i záporná), bod leží uvnitř trojúhelníka a vykreslíme ho.
|
||||
|
||||

|
||||
|
||||
## Framebuffer
|
||||
|
||||

|
||||
|
||||
Framebuffer definuje, kam se ukládají výsledné pixely. Framebuffer může obsahovat více barevných bufferů, hloubkový buffer, stencil buffer, ... Každý buffer může mít svůj vlastní formát a velikost. Místo framebufferu můžeme nabindovat přímo obrazovku (defaultní framebuffer).
|
||||
|
||||
Framebuffer vypadá navenek velice podobně, jako VAO. Můžeme propojovat binding pointy z fragment shaderu s jednotlivými texturami (tentokrát ale 1..1 [ref?]).
|
||||
|
||||
## Textury
|
||||
|
||||
Textura je obraz, který se aplikuje na povrch objektu. Textura může být 1D, 2D, 3D, nebo cube map. Textura se skládá z texelů (=pixelů textury). U 2D textur se texely souřadnicují pomocí (u, v) souřadnic, kde hodnoty u a v jsou v intervalu [0, 1].
|
||||
|
||||
- **Problémy**
|
||||
- **_Aliasing_** - pokud se texel textury nepřesně mapuje na fragment, může dojít k aliasingu
|
||||
- **_Paměťová náročnost_** - textury mohou být velké a mohou zabírat hodně paměti
|
||||
|
||||
### Mapování
|
||||
|
||||
Textura se mapuje na objekt pomocí texturovacích souřadnic (UV), které se interpolují mezi vrcholy trojúhelníku. Mapování provádíme typicky ve fragment shaderu (interpolace probíhá při rasterizaci).
|
||||
|
||||
### Filtrování
|
||||
|
||||
- `GL_NEAREST` - nejbližší texel, zachovává pixelizaci
|
||||
- `GL_LINEAR` - lineární interpolace mezi texely, vyhlazuje pixelizaci
|
||||
- `GL_$1_MIPMAP_$2` - kde `$1` určuje chování v rámci jedné mipmapy a `$2` chování mezi mipmapami (obě mohou být `NEAREST` nebo `LINEAR`)
|
||||
|
||||
Pokud nepracujeme s pixel-artovou grafikou je ideální použít `GL_LINEAR_MIPMAP_LINEAR`.
|
||||
|
||||
Mipmapy jsou snížené verze textury. Mipmapy zrychlují vykreslování textur a zlepšují kvalitu textur při velkém zmenšení. Lze je vytvořit automaticky (`glGenerateMipmap`) nebo ručně nahráním menších verzí textury.
|
||||
|
||||

|
||||
|
||||
### Syntéza
|
||||
|
||||
Textury lze nahrávat ručně, nebo je generovat "on the fly" pomocí fragment shaderu. Pro generování lze použít např. Perlinův šum, Voronoi diagram, ...
|
||||
|
||||
Výhodami syntetizovaných textur je:
|
||||
|
||||
- malá paměťová náročnost
|
||||
- dobrá návaznost na hranách geometrie, pokud syntetizujeme 3D texturu
|
||||
- parametrizovatelnost
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Není na první pohled jasné, co je zamýšleno pod pojmem "syntéza textur". Pravděpodobně jsou myšleny popsané techniky generování textur pomocí shaderů. Jak ale podotknul Honza Byška, syntéza textur z definice popisuje proces vytváření velké textury z malých fragmentů jiných textur (listnatou louku z jednotlivých listů, kamenou dlažbu z kamenů, ...). Pro více informací koukněte na [synthesis1](#synthesis1) a [synthesis2](#synthesis2).
|
||||
|
||||
</dd></dl>
|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[pv112,1]]] Byška: PV112 Computer Graphics API
|
||||
- [[[pb009,2]]] Byška: PB009 Principles of Computer Graphics
|
||||
- [[[glsl_tutorial,3]]] https://cgvr.cs.uni-bremen.de/teaching/cg2_07/literatur/glsl_tutorial/index.html
|
||||
- [[[synthesis1,4]]] https://en.wikipedia.org/wiki/Texture_synthesis
|
||||
- [[[synthesis2,5]]] https://diglib.eg.org:8443/server/api/core/bitstreams/90ad4c13-45b1-4ec0-8ef2-76075b2c73ae/content
|
282
src/content/docs/szmgr/PGV04_geometricke_algoritmy.md
Normal file
282
src/content/docs/szmgr/PGV04_geometricke_algoritmy.md
Normal file
@ -0,0 +1,282 @@
|
||||
---
|
||||
title: "Geometrické algoritmy"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Konvexní obaly, konstrukce ve 2D a 3D. Voroného diagramy, Delaunayova triangulace, dualita, triangulace, triangulace s omezením. Prostorové vyhledávání (datové struktury, algoritmy).
|
||||
|
||||
_MA017, PA093_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
<dl><dt><strong>💡 TIP</strong></dt><dd>
|
||||
|
||||
Většina algoritmů je výborně popsaná na webu předmětu [MA017 Geometrické algoritmy](https://is.muni.cz/auth/do/sci/UMS/el/geometricke-alg/index.html) včetně interaktivních animací a ukázek.
|
||||
|
||||
</dd></dl>
|
||||
|
||||
## Konvexní obaly
|
||||
|
||||
Konvexní obal je nejmenší konvexní mnohoúhelník, který obsahuje všechny body z dané množiny bodů.
|
||||
|
||||
### Naivní algoritmus
|
||||
|
||||
Pokud hledáme konvexní obal, pak můžeme postupně vyzkoušet všechny dvojice bodů $(p, q)$ a pro každou ověřit, že vlevo od ní (pomocí [edge funkce](../zaklady_pocitacove_grafiky)) neleží žádný bod. Úsečky, pro které toto platí jsou poté součástí konvexního obalu.
|
||||
|
||||
Tento algoritmus je velice hloupý a má složitost $O(n^3)$, kde n je počet bodů.
|
||||
|
||||
### Sweep Line
|
||||
|
||||
Pro hledání konvexního obalu existují efektivnější algoritmy. Jeden z nich je postaven na principu hledání horní a dolní hranice konvexního obalu.
|
||||
|
||||
Seřadíme si všechny body podle vzrůstající souřadnice X. Poté řešíme horní a dolní obálku zvlášť. Oba algoritmy jsou obdobné, proto popíšu postup pouze pro horní obálku:
|
||||
|
||||
Pro horní obálku si vytvoříme prázdný zásobník. Postupně procházíme body a pro každý bod uděláme následující:
|
||||
|
||||
1. Přidáme bod na zásobník.
|
||||
2. Dokud na zásobníku máme alespoň 3 body a tyto tři body netvoří "zatáčku vpravo", odstraníme prostřední bod ze zásobníku. Toto ověříme opět pomocí [edge funkce](../zaklady_pocitacove_grafiky).
|
||||
|
||||
image::./img/pgv04_hull_upperlower_invalid.png[width=400]
|
||||
|
||||
Tento algoritmus má složitost $O(n \log n)$, kde n je počet bodů.
|
||||
|
||||
### Gift wrapping
|
||||
|
||||
Další algoritmus pro hledání konvexního obalu je tzv. _gift wrapping_ (obalování dárku). Algoritmus je založen na tom, že postupně "obalujeme" body konvexním obalem.
|
||||
|
||||
Vybereme bod s nejmenší souřadnicí X a přidáme ho do konvexního obalu. Poté postupně procházíme všechny body a pro každý bod uděláme následující:
|
||||
|
||||
1. Spočítáme úhel mezi posledním bodem v konvexním obalu a všemi zbývajícími body.
|
||||
2. Vybereme bod s největším úhlem (vůči ose Y) a přidáme ho do konvexního obalu.
|
||||
3. Opakujeme, dokud se nevrátíme zpět na začátek.
|
||||
|
||||
Tento algoritmus má složitost $O(n h)$, kde n je počet bodů a h je počet bodů v konvexním obalu. V nejhorším případě může mít složitost $O(n^2)$. Tento algoritmus je výhodný, pokud očekáváme, že konvexní obal bude mít málo bodů (méně, než $O(\log n)$).
|
||||
|
||||
### Další 2D algoritmy
|
||||
|
||||
- **Graham scan** (podobný, jako sweepline, jen seřadíme body podle úhlu, nikoliv podle souřadnice X)
|
||||
- **Incremental algorithm** (na začátku vybereme trojúhelník a ten postupně rozšiřujeme o body, které jsou vně)
|
||||
- **Divide and conquer** (rozdělíme na dvě části, najdeme konvexní obaly pro obě části a spojíme je pomocí společných horních a dolních tečen)
|
||||
|
||||
### Konvexní obal v 3D
|
||||
|
||||
Problém konvexního obalu ve 3D je výrazně komplikovanější (a popravdě se na FI ani v jednom předmětu neučí...). Pro jeho konstrukci můžeme použít například algoritmus _QuickHull_ [so_hull_3d](#so_hull_3d).
|
||||
|
||||
1. Zvolíme trojúhelník 3 bodů
|
||||
- Bod s minimálními souřadnicemi $(x, y, z)$
|
||||
- Nejvzdálenější bod od tohoto bodu
|
||||
- Nejvzdálenější bod od této hrany
|
||||
2. Zbytek algoritmu opět řešíme pro "horní a dolní obálku" zvlášť (body na přední a zadní straně trojúhelníka).
|
||||
3. Najdeme nejvzdálenější bod od aktuálního obalu a pro něj provedeme:
|
||||
- Odstraníme všechny stěny viditelné z daného bodu
|
||||
- Nahradíme je novými stěnami mezi novým bodem a _horizon ridge_ (hranice viditelných stěn)
|
||||
4. Opakujeme, dokud nejsou všechny body uvnitř obalu.
|
||||
|
||||

|
||||
|
||||
Tento algoritmus má složitost $O(n \log n)$, kde n je počet bodů.
|
||||
|
||||
## Voroného diagramy
|
||||
|
||||
Voroného diagram je rozdělení roviny na oblasti podle nejbližších bodů. Každá oblast obsahuje jeden bod a všechny body v této oblasti jsou mu nejbližší.
|
||||
|
||||

|
||||
|
||||
### Naivní algoritmus
|
||||
|
||||
Oblast kolem každého bodu můžeme získat, jako průnik polorovin vytvořených přímkou uprostřed mezi tímto bodem a všemi ostatními body. Složitost nalezení jedné takové oblasti je $O(n \log n)$ (kvůli hledání průniku) a celková složitost je $O(n^2 \log n)$.
|
||||
|
||||
### Inkrementální algoritmus
|
||||
|
||||
Tento algoritmus je založen na postupném přidávání bodů (Doporučuji kouknout na [toto video](https://www.youtube.com/watch?v=By_VJMXKVXk)). Vybereme počáteční bod a postupně přidáváme body. Pro každý bod uděláme následující:
|
||||
|
||||
1. Najdeme polygon, do kterého bod patří.
|
||||
2. Původní polygon rozdělíme na dva podle příčky mezi původním bodem a novým bodem.
|
||||
3. Pro všechny polygony sousedící s novým polygonem uděláme totéž.
|
||||
4. Opakujeme, dokud nejsou všechny body přidány.
|
||||
|
||||
Tento algoritmus má složitost $O(n^2)$.
|
||||
|
||||
### Divide and conquer
|
||||
|
||||
Další možností je rozdělit rovinu na dvě části a pro každou část udělat Voroného diagram. Poté spojit obě části pomocí společné hrany.
|
||||
|
||||
Poloviny určíme podle souřadnice X. Při spojování poté najdeme tzv _separating chain_. Všechny hrany z Vor(L) na pravé straně separating chain a všechny hrany z Vor(R) na levé straně separating chain zahodíme.
|
||||
|
||||

|
||||
|
||||
Separating chain vytvoříme následovně:
|
||||
|
||||
1. Najdeme convex hull pro body z obou polovin.
|
||||
2. Najdeme horní a dolní tečny pro oba konvexní obaly.
|
||||
3. Začneme horní tečnou, vytvoříme kolmici jejím středem směrem dolů a postupujeme, dokud nenarazíme na hranu konvexního obalu.
|
||||
4. Na této hraně zjistíme dva body, v jejichž oblastech budeme pokračovat a vytvoříme další kolmici.
|
||||
5. Opakujeme, dokud se nedostaneme na konec.
|
||||
|
||||
Tento algoritmus má složitost $O(n \log n)$.
|
||||
|
||||
### Sweep Line
|
||||
|
||||
Nejznámnějším algoritmem je Sweep Line. V algoritmu využíváme tzv. Beach line, což je křivka složená z parabol, která se nachází na sweeplinou.
|
||||
|
||||

|
||||
|
||||
Při pohybu sweepline může dojít ke dvěma druhům událostí:
|
||||
|
||||
- **Site event (přechod bodu)**
|
||||
- K této události dojde, pokud sweepline narazí na nový bod
|
||||
- Na beach line vznikne nová parabola, který může rozdělit některé paraboly na dvě křivky
|
||||
- **Circle event (zánik křivky)**
|
||||
- K této události dojde, pokud zaniká jeden ze segmentů paraboly
|
||||
- Pokud se 3 segmenty paraboly protínají v jednom bodě
|
||||
- V tomto bodě vzniká nový vrchol Voroného diagramu
|
||||
|
||||
Detailní popis algoritmu je na webu [Geometrických algoritmů](https://is.muni.cz/auth/do/sci/UMS/el/geometricke-alg/pages/09-diagramy.html). Tento algoritmus má složitost $O(n \log n)$.
|
||||
|
||||
### Převod Delaunayovy triangulace na Voroného diagram
|
||||
|
||||
Pokud již máme k dispozici Delaunayovu triangulaci, můžeme snadno získat Voroného diagram. Stačí pro každů trojúhelník najít střed kružnice opsané a spojit středy těchto kružnic podle sousednosti trojúhelníků.
|
||||
|
||||

|
||||
|
||||
## Delaunayova triangulace
|
||||
|
||||
Delaunayova triangulace je taková triangulace, kde pro každý trojúhelník platí, že kružnice opsaná kolem něj neobsahuje žádný jiný bod, tedy trojúhelníky jsou co nejrovnostrannější. Existuje právě jedna Delaunayova triangulace pro každou množinu bodů.
|
||||
|
||||
Pro ukládání Delaunayovy triangulace se používá tzv. _Active Edge List (AEL)_, kde jsou uložené jednotlivé half edges, jejich následníci a předchůdci, sousedé a sousední rovina.
|
||||
|
||||

|
||||
|
||||
### Lokální výměna
|
||||
|
||||
Můžeme zvolit libovolnou korektní triangulaci a poté se zbavit "ilegálních" hran tzv. lokální výměnou v zámci konvexních čtyřúhelníků.
|
||||
|
||||
Opakujeme, dokud dochází ke změnám:
|
||||
|
||||
1. Najdeme dva trojúhelníky, které tvoří konvexní čtyřúhelník a jejichž společná hrana je ilegální (kružnice opsaná libovolnému z těchto trojúhelníků obsahuje chybějící čtvrtý bod).
|
||||
2. Legalizujeme tuto hranu (_edge flip_) (odstraníme ji a přidáme novou hranu mezi druhými dvěma body).
|
||||
|
||||

|
||||
|
||||
Tento algoritmus má složitost $O(n^2)$.
|
||||
|
||||
### Inkrementální konstrukce
|
||||
|
||||
Další možností je inkrementální konstrukce. Iniciálně zvolíme jednu hranu a postupně přidáváme body. Vždy provedeme následující:
|
||||
|
||||
1. Pro existující hranu najdeme pod s nejnižší Delaunayovou vzdáleností od této hrany (viz dále). Tento bod musí být nalevo od této orientované hrany.
|
||||
2. Tento bod přidáme do triangulace.
|
||||
3. Pokud takový bod neexistuje (jsme na hraně konvexního obalu), obrátíme half-edge a pokračujeme.
|
||||
|
||||
Delaunayova vzdálenost se vypočítá, jako
|
||||
|
||||

|
||||
|
||||
Tento algoritmus má složitost $O(n^2)$.
|
||||
|
||||
### Inkrementální inserce
|
||||
|
||||
Další možností je postupné dělení trojúhelníka. Vytvoříme obrovský trojúhelník, který obsahuje všechny body a postupně ho dělíme na menší trojúhelníky. Vždy vybereme jeden bod a ten do triangulace přidáme. Bod může ležet buď uvnitř trojúhelníku nebo na jeho hraně. Pokud leží uvnitř, vznikají z daného trojúhelníku tři nové trojúhelníky. Pokud leží na hraně, vznikají čtyři nové trojúhelníky. Po vytvoření nových hran musíme všechny hrany rekurzivně zlegalizovat (tedy každou hranu a pokud je potřeba i všechny její sousedy).
|
||||
|
||||

|
||||
|
||||
### Další algoritmy
|
||||
|
||||
- **Divide and conquer**
|
||||
- **Walking method**
|
||||
|
||||
## Dualita
|
||||
|
||||
Delaunayova triangulace a Voroného diagramy jsou (grafově) duální. Mnohoúhelník v jedné struktuře reprezentuje vrchol ve struktuře druhé a naopak. Hrany jsou na sebe tedy "kolmé" (v logickém slova smyslu, nikoli geometrickém).
|
||||
|
||||

|
||||
|
||||
## Triangulace
|
||||
|
||||
Při triangulaci chceme převést mnohoúhelník na množinu nepřekrývajících se trojúhelníků, které dohromady dávají původní mnohoúhelník.
|
||||
|
||||
### Triangulace konverxního mnohoúhelníka
|
||||
|
||||
Pro konvexní mnohoúhelník můžeme triangulaci provést jednoduše. Stačí vybrat jeden bod a spojit ho s každým dalším bodem.
|
||||
|
||||

|
||||
|
||||
### Triangulace monotónního mnohoúhelníka
|
||||
|
||||
Monotónní mnohoúhelník je takový mnohoúhelník, který v dané ose (např. Y) má pouze jeden extrém (maximální nebo minimální hodnotu). Pro triangulaci takového mnohoúhelníka postupujeme následovně:
|
||||
|
||||
1. Rozdělíme hrany mnohoúhelníka na levou a pravou cestu.
|
||||
2. Seřadíme body podle osy Y.
|
||||
3. Vložíme první dva body do zásobníku.
|
||||
4. Pro každý další bod
|
||||
- Pokud je bod na opačné cestě, než je vrchol zásobníku, odebereme ze zásobníku všechny body a vytvoříme ke každému z nich hranu od nového bodu. Vložíme poslední bod zásobníku a nový bod.
|
||||
- Pokud je bod na stejné cestě, odebíráme ze zásobníku body, dokud je lze spojovat s novým bodem (jsou uvnitř mnohoúhelníka), nebo dokud nám nedojdou body. Poslední vyjmutý bod vložíme zpět na zásobník a vložíme nový bod.
|
||||
5. U posledního bodu vytvoříme hrany ke všem bodům na zásobníku.
|
||||
|
||||

|
||||
|
||||
### Triangulace obecného mnohoúhelníka
|
||||
|
||||
Obecný trojúhelník triangulujeme rozdělením tohoto mnohoúhelníka na mnohoúhelníky monotónní a následnou triangulací těchto jeho částí pomocí algoritmu pro triangulaci monotónního trojúhelníka.
|
||||
|
||||
Vrcholy v libovolném mnohoúhelníku se dělí na 5 typů:
|
||||
|
||||

|
||||
|
||||
Abychom získali monotónní mnohoúhelník, potřebujeme se zbavit vrcholů typu Merge a Split. Pro to použijeme sweep line algoritmus (Po Y směrem dolů).
|
||||
|
||||
Pro každou hranu, kterou právě protíná sweepline máme uložený tzv. helper vrchol. Jedná se o nejnižší merge vrchol vpravo od jeho hrany takový, že horizontální spojnice mezi hranou a tímto bodem leží celá uvnitř mnohoúhelníka. Tyto helpery spolu s hranami si držíme vy binárním vyhledávacím stromě.
|
||||
|
||||

|
||||
|
||||
Vrcholy typu split odstraňujeme v okamžiku. kdy jimi prochází zametací přímka. V tomto případě spojíme tento vrchol s pomocníkem zleva nejbližší strany mnohoúhelníka (najdeme pomocí binárního stromu).
|
||||
|
||||

|
||||
|
||||
Odstranění vrcholů typu merge je složitější. Tyto vrcholy neodstraníme, když jimi zametací přímka prochází, neboť v tomto okamžiku neznáme „situaci“ pod zametací přímkou a nemůžeme vrchol spojovat s vrcholy pod ním. K odstranění merge vrcholů dochází zpětně. V každém z procházených vrcholů testujeme, zda pomocník jeho nejbližších stran je typu merge. Pokud ano, spojíme s ním daný vrchol.
|
||||
|
||||

|
||||
|
||||
Po dokončení tohoto algoritmu bychom měli mít samé monotónní trojúhelníky, které dokážeme "dotriangulovat".
|
||||
|
||||
## Prostorové vyhledávání
|
||||
|
||||
### k-D stromy
|
||||
|
||||
k-D strom střídavě dělí prostor (2D nebo 3D) na dvě poloviny podle střídajících se os. Ve uzlech jsou uloženy (typicky) dělící čáry a v listech samotné body.
|
||||
|
||||

|
||||
|
||||
Složitost postavení k-D stromu je $O(n \log n)$.
|
||||
|
||||
Vyhledávání v k-D stromě je maličko zajímavější. Rekurzivně sestupujeme stromem a
|
||||
|
||||
- zahazujeme všechny větve, které jsou mimo náš interval
|
||||
- akceptujeme všechny větve, které jsou uvnitř našeho intervalu
|
||||
- pro větve, které hraničí s intervalem sestupujeme dál, případně musíme ověřit všechny prvky
|
||||
|
||||

|
||||
|
||||
Složitost vyhledávání v k-D stromě je $O(n^{1-\frac{1}{d}} + k)$, kde $d$ je dimenze a $k$ je počet prvků v dané oblasti.
|
||||
|
||||
### Range Trees
|
||||
|
||||
Tyto jsou značně méně probírány, proto jen obecně myšlenka:
|
||||
|
||||
Vytvoříme binární vyhledávácí strom $T$ pro vrcholy podle souřadnice X. Pro každý vrchol $v$ vytvoříme asociovaný vyhledávací strom $T_{ass}(v)$ obsahující pouze vrcholy z podstromnu tohoto bodu $T(v)$. $T_{ass}$ je binární vyhledávací strom podle souřadnice Y.
|
||||
|
||||

|
||||
|
||||
Při vyhledávání v tomto stromě nejprve vyhledáme podle jedné souřadnice a pak pro všechny vhodné podstromy provedeme vyhledávání podle souřadnice druhé.
|
||||
|
||||
Range trees jsou paměťově náročnější, zato jsou rychlejší.
|
||||
|
||||
- Paměť: $O(n \log^{d-1} n)$
|
||||
- Konstrukce: $O(n \log^{d-1} n)$
|
||||
- Vyhledávání: $O(\log^{d} n + k)$
|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[so_hull_3d,1]]] https://stackoverflow.com/a/74968910/22953817
|
160
src/content/docs/szmgr/PGV05_deleni_prostoru_a_sceny.md
Normal file
160
src/content/docs/szmgr/PGV05_deleni_prostoru_a_sceny.md
Normal file
@ -0,0 +1,160 @@
|
||||
---
|
||||
title: "Techniky dělení prostoru a scény"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Datové struktury (oct-, quad-, BSP-, k-d stromy), jejich konstrukce a údržba, používané heuristiky. Objemem ohraničující tělesa a jejich hierarchie, způsob konstrukce a použití. Detekce kolizí, vykreslování.
|
||||
|
||||
_MA017, PA010, PA213_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
Hierarchické reprezentace scény se snaží zefektivnit výpočty kolizí pomocí rozdělení scény na menší části. Díky tomu je možné testovat kolize na méně objektech a navíc na takových, kde je tento výpočet jednodušší.
|
||||
|
||||
Hierarchické reprezentace zjednodušují výpočet, pokud jsou dva objekty daleko od sebe (trivial reject), ale naopak zneefektivňují výpočet, pokud jsou objekty velice blízko sebe.
|
||||
|
||||
Existují dva základní přístupy k tomuto problému:
|
||||
|
||||
## Prostorové dělení scény (Spatial decomposition of the scene)
|
||||
|
||||
_Space-centric:_ Rozdělujeme prostor scény na menší části a udržujeme informace o objektech v těchto částech. Většina těchto algoritmů se používá pro statické scény, neboť jejich aktualizace je velice drahá.
|
||||
|
||||

|
||||
|
||||
### Uniformní dělení prostoru
|
||||
|
||||
Rozdělíme prostor na pravidelnou mřížku stejně velkých buněk. Každá buňka obsahuje informace o objektech, které se v ní nacházejí.
|
||||
|
||||
- **Detekce kolizí**\
|
||||
Zkontrolujeme, že jednu buňku sdílejí dva objekty.
|
||||
- **Prostorová složitost**\
|
||||
Pro 3D scénu s rozlišením $n$ v každé dimenzi potřebujeme $n^3$ buněk.
|
||||
- **Přesnost**\
|
||||
Některé buňky obsahují jen části objektů, při nízkém rozlišení nezjednodušuje výpočet.
|
||||
|
||||
### Octree, Quadtree
|
||||
|
||||
Octree a Quadtree jsou stromové struktury, které rekurzivně dělí prostor na menší části. Octree dělí prostor na osm stejně velkých krychlí, Quadtree na čtyři stejně velké čtverce.
|
||||
|
||||
Každou krychli/čtverec dělíme tak dlouho, dokud není každá krychle/čtverec celý plný/prázdný, nebo není dosažen maximální počet iterací.
|
||||
|
||||

|
||||
|
||||
Složitost vytvoření Octree/Quadtree je $O(n \log n)$. Složitost vyhledávání je $O(\log n)$ (jako v libovolném stromu). Složitost detekce kolizí je v nejhorším případě $O(n)$.
|
||||
|
||||
### k-D stromy
|
||||
|
||||
(Převzato z PGV04 [pgv04](#pgv04)) k-D strom střídavě dělí prostor (2D nebo 3D) na dvě poloviny podle střídajících se os. Ve uzlech jsou uloženy (typicky) dělící čáry a v listech samotné body.
|
||||
|
||||

|
||||
|
||||
Složitost postavení k-D stromu je $O(n \log n)$.
|
||||
|
||||
Vyhledávání v k-D stromě je maličko zajímavější. Rekurzivně sestupujeme stromem a
|
||||
|
||||
- zahazujeme všechny větve, které jsou mimo náš interval
|
||||
- akceptujeme všechny větve, které jsou uvnitř našeho intervalu
|
||||
- pro větve, které hraničí s intervalem sestupujeme dál, případně musíme ověřit všechny prvky
|
||||
|
||||

|
||||
|
||||
Složitost vyhledávání v k-D stromě je $O(n^{1-\frac{1}{d}} + k)$, kde $d$ je dimenze a $k$ je počet prvků v dané oblasti.
|
||||
|
||||
### BSP stromy
|
||||
|
||||
BSP stromy (Binary Space Partitioning) dělí prostor na poloprostory podle rovin. Každý uzel stromu obsahuje rovinu a dva podstromy, které jsou vytvořeny dělením prostoru touto rovinou.
|
||||
|
||||
Roviny jsou v BSP stromě vybírány tak, aby co nejvíce balancovaly počet objektů v obou podstromech a zároveň co nejvíce snižovaly počet průsečíků s objekty.
|
||||
|
||||

|
||||
|
||||
Jedno z využití BSP stromů je pro vykreslování objektů ve scéně správném pořadí. Vždy zkontrolujeme úhel dělící roviny vůči kameře a pak s jistotou víme, který podstrom je celý před kterým.
|
||||
|
||||
Co se týče složitosti, v nejhorším případě může mít jejich konstrukce složitost až $O(n^3)$. Při konstrukci je možné, že dojde k rozdělení jednoho objektu na mnoho menších, což může způsobit exponenciální nárůst počtu objektů (opět až $O(n^3)$).
|
||||
|
||||
## Objemem ohraničující tělesa a jejich hierarchie (Bounding volume hierarchies)
|
||||
|
||||
_Object-centric:_ Každý objekt je aproximován jednodušším objektem (koulí, kvádrem, ...) s jednodušším výpočtem kolizí. Tyto aproximace jsou dále hierarchicky uspořádány. Tento přístup je vhodný pro dynamické scény, kde se objekty pohybují a mění svou pozici.
|
||||
|
||||
- Koule, AABB: rychlý test + horší aproximace → ideální pro rapid prototyping
|
||||
- k-dop, OBB OBB, konvexní obal: pomalejší test + lepší aproximace → používané v praxi
|
||||
|
||||

|
||||
|
||||
### Sphere Bounding Volume
|
||||
|
||||
- Velice jednoduchý a rychlý test kolizí ($(c_1 - c_2) \cdot (c_1 - c_2) \leq (r_1 + r_2)^2$).
|
||||
- Hůře zachytává tvar objektu.
|
||||
- Může být problematické najít správnou kouli pro daný objekt. Jednoduchý (ne optimální, ale rychlý) algoritmus:
|
||||
- Vybereme náhodný bod A
|
||||
- Vybereme nejvzdálenější bod B od bodu A
|
||||
- Vybereme nejvzdálenější bod C od bodu B
|
||||
- Položíme kouli tak, aby procházela body B a A a její poloměr byl $\frac{B-C}{2}$
|
||||
- Pro každý bod v objektu upravíme kouli tak, aby obsahovala i tento bod
|
||||
|
||||

|
||||
|
||||
### Axis-Aligned Bounding Box (AABB)
|
||||
|
||||
- Velice jednoduchý a rychlý test kolizí (porovnání souřadnic).
|
||||
- Velice rychlá konstrukce (minimum a maximum pro každou souřadnici).
|
||||
- Pro objekty položené "na koso" může být velice neefektivní.
|
||||
|
||||
### k-DOP (Discrete Oriented Polytope)
|
||||
|
||||
- Konvexní mnohostěn, který je definován jako průnik pevně otočenými podprostory.
|
||||
- k znamená maximální počet hran mnohoúhelníka / stěn mnohostěnu (= počet různě otočených poloprostorů / polorovin).
|
||||
- Ve 2D 8-dop znamená 8 hran oročených +/- {45, 90, 135, 180} stupňů.
|
||||
|
||||

|
||||
|
||||
### Oriented Bounding Box (OBB)
|
||||
|
||||
- Obdélník, který je otočený v prostoru, aby lépe vystihoval tvar objektu.
|
||||
- Pro vytvoření využijeme vlastní vektory (PCA), což je výpočetně maličko náročnější ($O(n \log n)$ pro jeden objekt, $O(n \log^2 n)$ pro celý strom).
|
||||
- Test kolizí je složitější, ale stále rychlý.
|
||||
|
||||
### Konvexní obaly
|
||||
|
||||
- Nejmenší konvexní mnohostěn, který obaluje daný objekt.
|
||||
- Pro vytvoření využijeme algoritmus QuickHull (složitost $O(n \log n)$).
|
||||
|
||||
### Hierarchie objemových ohraničení
|
||||
|
||||
Myšlenka je vytvořit hierarchii, ve které můžeme vyhledávat. Vytvoříme nějaký obal pro celý objekt, pak pro jeho části a takhle ho postupně dělíme až se dostaneme na jednotlivé trojúhelníky.
|
||||
|
||||

|
||||
|
||||
Hierarchie jsou vhodné pro detekci kolizí, neboť můžeme provést trivial reject na vyšší úrovni a nemusíme tak testovat kolize na všech objektech (především na všech trojúhelnících).
|
||||
|
||||
Snažíme se konstruovat hierarchie tak, aby:
|
||||
|
||||
- pasovaly na objekty co nejpřesněji
|
||||
- testování kolizí bylo co nejrychlejší
|
||||
- bylo třeba je co nejméně aktualizovat
|
||||
|
||||
## Detekce kolizí
|
||||
|
||||
Detekce kolizí je proces, kdy testujeme, zda se dva objekty v prostoru dotýkají. Pro jednoduché objekty (koule, AABB) je tento proces velice rychlý, pro složitější objekty (trojúhelníky) je tento proces složitější.
|
||||
|
||||
- **SAT (Separating Axis Theorem)**\
|
||||
Pro konvexní objekty platí, že pokud existuje osa, podél které se objekty neprotínají, tak se neprotínají vůbec. Pro hledání takové osy se používají normály stěn objektů. Pro zábavnou a hezkou vizualizaci v Minecraftu můžeš kouknout na [SethBlingovo video](https://www.youtube.com/watch?v=EB6NY5sGd08).
|
||||
|
||||

|
||||
|
||||
- **Detekce kolizí v praxi**\
|
||||
Pro jednoduché objekty (koule, AABB) se používají jednoduché vzorce. Pro složitější objekty typicky střelíme několik paprsků uvnitř objektu a pokud se některý z nich dotkne stěny, tak se objekty dotýkají. Tento přístup je méně přesný, ale značně rychlejší.
|
||||
- **Swept sphere volumes**\
|
||||
Po celém povrchu objektu "potáhneme" kouli, která nám vytvoří objem, který můžeme použít pro detekci kolizí. Tento objem je větší než objekt, ale je rychlejší na výpočet.
|
||||
|
||||

|
||||
|
||||
## Vykreslování
|
||||
|
||||
Pro určení pořadí vykreslovaných objektů můžeme také využít hierarchické reprezentace scény. Typicky se pro tento problém využívá BSP stromů.
|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[pgv04,1]]] ../geometricke_algoritmy/
|
206
src/content/docs/szmgr/PGV06_vykreslovani_objemovych_dat.md
Normal file
206
src/content/docs/szmgr/PGV06_vykreslovani_objemovych_dat.md
Normal file
@ -0,0 +1,206 @@
|
||||
---
|
||||
title: "Vykreslování objemových dat"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Rekonstrukce povrchu - kontury, objem, bodový mrak. Algoritmus pochodujících kostek. Přímé vykreslování objemových dat.
|
||||
|
||||
_PB009, PA010, PA213_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
<dl><dt><strong>💡 TIP</strong></dt><dd>
|
||||
|
||||
Většina obsahu převzata z původní otázky VPH01 Pokročilá počítačová grafika
|
||||
|
||||
</dd></dl>
|
||||
|
||||
## Bodový mrak (point cloud)
|
||||
|
||||
Množina bodů v prostoru, které nemají žádnou strukturu. Nejjednodušší přístup k renderování objemu, kdy se nepokoušíme o žádnou rekonstrukci povrchu. Body však mohou mít různé barvy a průhlednost.
|
||||
|
||||
Při renderování bodových mraků je třeba vyřešit několik souvisejících problémů s daty:
|
||||
|
||||
- Data s neuniformním vzorkem.
|
||||
- Chybějící data.
|
||||
- Šum a outlieři.
|
||||
|
||||
Kromě pozic mohou surová data obsahovat také normály, barvy, apod.
|
||||
|
||||
### Vykreslování bodových mraků
|
||||
|
||||
Ze získaných dat se snažíme vytvořit mesh. Ten lze vyrenderovat tradičním způsobem.
|
||||
|
||||
Před samotnou rekonstrukcí je často potřeba provézt ještě předzpracování:
|
||||
|
||||
- Registration - spojení dat z více pohledů dohromady
|
||||
- Filtering - odstranění šumu a outlierů
|
||||
- Segmentation - rozdělení objektů na jednotlivé části
|
||||
|
||||
- **Billboarding**\
|
||||
Vykreslujeme pouze body, nebo obdélníky na místech, kde se body nacházejí. Body mohou být billboardované (otočené ke kameře), nebo využít normálnových dat v bodech (= Splatting).
|
||||
- **Surface Splatting**\
|
||||
Normála povrchu odpovídá normále tečné plochy v každém bodě. Pro každý bod najdeme k bodů v okolí, které minimalizuje vzdálenost těchto bodů od naší roviny $n = \arg \min*{|n| = 1} \sum*{i=1}^k ((p_i - p) \cdot n)^2 $. [pa213](#pa213)
|
||||
|
||||
Pro nalezení normál využijeme PCA (Principal Component Analysis), normála poté odpovídá vlastnímu vektoru s nejmenší vlastní hodnotou. PCA však vrátí nekonzistentně otočené normály, které můžeme opravit buď otočením všech normál ke kameře, nebo iterativně opravováním sousedství.
|
||||
|
||||

|
||||
|
||||
Při samotném vykreslování vytvoříme pro každý takový bod elipsu (podle PCA), která bude průhlednější čím dál od středu. S dostatečným množstvím takových elips můžeme vytvořit dojem plochy. Elipsy můžou být stínované podle vypočítané normály, nebo plynule podle normál jednotlivých bodů.
|
||||
|
||||

|
||||
|
||||
### Rekonstrukce povrchu
|
||||
|
||||
- **Delaunay triangulation**\
|
||||
Vytváří trojúhelníkovou síť, tak že žádný bod se nenáchází ve vepsané kružnici žádného trojúhelníku. Maximalizuje nejmenší úhel trojúhelníků. [delaunay-triangulation](#delaunay-triangulation)
|
||||
|
||||

|
||||
|
||||
Lze použít ve 3D pro rekonstrukci povrchu, ale je třeba odstranit body, které nejsou součástí povrchu. Zároveň delaunay nedovolí vytvořit díry ve výsledném meshi.
|
||||
|
||||
- **Alpha shapes**\
|
||||
Obecnější metoda než delaunay triangulation, která umožňuje vytvářet i díry ve výsledném meshi. Alpha shapes jsou definovány pomocí parametru alpha, který určuje, jak moc se mohou body "vytahovat" z objemu.
|
||||
|
||||
[pa213](#pa213) má hezkou metaforu se zmrzlinou s čokoládovými kousky a sférickou naběračkou. Hodnota parametru alpha určuje, jak velká je naběračka, kterou se snažíme vybírat zmrzlinu tak, abychom se nedotkli čokoládových kousků.
|
||||
|
||||
V podstatě zobecnění delaunay triangulation, kde akceptujeme pouze takové trojúhelníky, které mají opsanou kružnici s poloměrem menším než alpha. [pa213](#pa213)
|
||||
|
||||
**Příklady meshe pro různé hodnoty Alpha**
|
||||
|
||||

|
||||
|
||||
- **Aproximace implicitní funkcí**\
|
||||
Uvažujme implicitní funkci $f(x, y, z)$, která je signed-distance funkcí od našeho daného povrchu (na povrchu = 0, uvnitř < 0, venku > 0). Taková funkce popisuje povrch jako nulovou hladinu.
|
||||
|
||||
Pro definici takové funkce by nám teoreticky stačily body našeho pointcloudu, které všechny nadefinujeme na nulovou hodnotu. Tímto způsobem má však naše funkce trivalní řešení, protože bychom mohli zvolit funkci, která pro všechny body vrací 0. Abochom tomu zabránili, přidáme pro každý bod dva nové body (1 uvnitř a jeden venku) posunuté podél normály. Tímto způsobem získáme funkci, která je nulová na povrchu a má správné znaménko uvnitř a venku.
|
||||
|
||||

|
||||
|
||||
## Objemová data
|
||||
|
||||
- **Voxel**\
|
||||
Voxel je 3D analogií pixelu -- bod v prostoru, který má určitou hodnotu (např. barvu, intenzitu, ...). Voxelová data mohou být získána (např. pomocí CT, MRI, PET, atd.) nebo být také výsledkem simulace (např. simulace proudění tekutin).
|
||||
- **Objemová data**\
|
||||
Objemová data jsou definována nejčastěji jako mřížka voxelů. Mřížky můžou mít různý tvar (pravidelné, nepravidelné, lineární, radiální, ...)
|
||||
|
||||
### Vykreslování objemových dat
|
||||
|
||||
- **Slicing**\
|
||||
Vykreslujeme řezy objemem. Pro každý řez vykreslíme všechny voxely, které řez protíná. Výsledkem je 2D obrazec, který můžeme vykreslit tradičním způsobem. Pro jeden objekt můžeme vytvořit několik řezů a ty pak vykreslit dohromady.
|
||||
|
||||
### Rekonstrukce povrchu (indirect volume rendering)
|
||||
|
||||
- **Iso-kontury**\
|
||||
Na každé vrstvě najdeme kontury 2D obrazců, ty pak mezi vrstvami spojíme. Výsledkem je 3D mesh. Pro nalezení kontur použijeme algoritmy ze zpracování obrazu. Spojení je triviální, pokud provádíme spojení 1:1 (jedna kontura na jedné vrstvě se spojí s jednou konturou na druhé vrstvě). Je třeba speciálně řešit nekonvexní oblasti.
|
||||
|
||||
Pokud chceme provést spojení M:N, je třeba vytvořit mezivrstvu, která bude mít 1 konturu vytvořenou ze všech kontur okolních vrstev spojených dohromady. Tím zajistíme korektní aproximaci této situace.
|
||||
|
||||
- **Marching cubes**\
|
||||
Uvažme prostor, kde každý voxel obsahuje nějakou hodnotu a my chceme vytvořit povrch pro specifickou hodnotu (typicky 0). Pro tento problém můžeme využít následující algoritmy.
|
||||
|
||||
V každém voxelu určí, které jeho rohy jsou uvnitř povrchu a které jsou vně. Takových kombinací existuje 256, ale pouze 16 je unikátních
|
||||
|
||||
**Marching cubes by [Ryoshoru](https://commons.wikimedia.org/wiki/File:MarchingCubesEdit.svg) (16. varianta je, pokud všechny body leží uvnitř)**
|
||||
|
||||

|
||||
|
||||
Díky tomu jsme schopní tyto kombinace předpočítat a pro každý voxel vykreslit odpovídající trojúhelníky. Výsledkem je mesh, který reprezentuje povrch objemu. [marching-cubes](#marching-cubes)
|
||||
|
||||
Je možné tyto předpočítané body interpolovat podél hran, na kterých leží a tím zlepšit výsledný mesh.
|
||||
|
||||
Nevýhodou je tzv. Schodišťový efekt, kdy je výsledný mesh velmi hranatý. Zároveň výsledná mesh obsahuje obrovské množství trojúhelníků, což může být neefektivní.
|
||||
|
||||
- **Marching tetrahedra**\
|
||||
Analogický k marching cubes, ale používá místo krychlí čtyřstěny. Řeší problém s některými nejednoznačnými konfiguracemi v marching cubes, a taky nikdy nebyl patentován (kdežto marching cubes ano). [marching-tetrahedra](#marching-tetrahedra)
|
||||
- **Flying edges**\
|
||||
Optimalizovaný algoritmus pro marching cubes, který prochází každou hranu pouze jednou.
|
||||
- **Surface nets**\
|
||||
Narozdíl od MC vykresluje vrcholy uvnitř voxelů, čímž odstraňuje problém ostrých hran. Výsledný mesh je tedy mnohem hladší.
|
||||
|
||||

|
||||
|
||||
- **Dual contouring**\
|
||||
Z voxelů se stanou vrcholy (tedy využíváme dualního grafu). Tyto vrcholy jsou ale posunuty tak, že povrch může obsahovat jak ostré hrany tak zaoblené plochy. [dual-contouring](#dual-contouring)
|
||||
|
||||

|
||||
|
||||
### Direct volume rendering (přímé renderování objemu)
|
||||
|
||||
Nerekonstruujeme povrch, ale mapujeme data na _optické_ vlastnosti jako je barva a průhlednost. Během renderování se pak využívá path tracing, a tyto vlastnosti se akumulují podél jednotlivých paprsků. [gpugems](#gpugems)
|
||||
|
||||
V realitě tohle chování paprsku popisujeme integrály. V počítačové grafice se ale využívá aproximace pomocí sumy.
|
||||
|
||||
**The Process of Volume Rendering [gpugems](#gpugems)**
|
||||
|
||||

|
||||
|
||||
- **Emmission-absorption model**\
|
||||
Paprsek vstupuje do objemu, kde je absorbován a emitován. Výsledná barva je pak výsledkem akumulace těchto vlastností. V notaci používáme: [pa213](#pa213)
|
||||
|
||||
- $\kappa$ je funkce absorpce,
|
||||
- $q$ je emise.
|
||||
|
||||
- **Optická hloubka / optical depth**\
|
||||
Bezrozměrná veličina $\tau$, která popisuje, jak moc jde "vidět skrz" něco, třeba plyn. Čím větší, tím méně vidíme.
|
||||
|
||||
Z jiné perspektivy je to akumulovaná absorpce na paprsku. Optická hloubka mezi dvěma body $s_1$ a $s_2$ na paprsku je dána jako:
|
||||
|
||||
```math
|
||||
\tau(s_1, s_2) = \int_{s_1}^{s_2} \kappa(s) ds
|
||||
```
|
||||
|
||||
- **Průhlednost / transparency**\
|
||||
Průhlednost popisuje, jak dobře vidíme skrz objem. Upadá exponenciálně s růstem optické hloubky.
|
||||
|
||||
Průhlednost mezi dvěma body $s_1$ a $s_2$ na paprsku je dána jako:
|
||||
|
||||
```math
|
||||
\theta(s_1, s_2) = e^{-\tau(s_1, s_2)}
|
||||
```
|
||||
|
||||
- **Volume rendering integral**\
|
||||
Intenzitu světla $I$ v místě paprsku $s$ počítáme pomocí: [pa213](#pa213)
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
|
||||
I(s) &= I(s_0) \cdot \theta(s_0, s) + \int_{s_0}^s q(s') \cdot \theta(s', s) ds' \\
|
||||
|
||||
&= I(s_0) \cdot e^{-\tau(s_0, s)} + \int_{s_0}^s q(s') \cdot e^{-\tau(s', s)} ds'
|
||||
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
kde:
|
||||
|
||||
- $s_0$ je místo, kde se paprsek dostal dovnitř nějakého světlo-vyzařujícího objemu,
|
||||
- $I(s_0)$ je boundary light, tedy světlo na hranici objemu,
|
||||
- $q(s')$ je emise v bodě $s'$.
|
||||
|
||||

|
||||
|
||||
- **Back-to-front**\
|
||||
Přístup k počítání $I$, kdy paprsky vyhodnocujeme od hranice objemu **dále** od kamery směrem **ke kaměře**.
|
||||
|
||||
Výhoda je, že nemusíme udržovat proměnnou pro průhlednost. Nevyhoda je, že musíme vyhodnotit všechny voxely v cestě paprsku, protože "přepisují" výsledek.
|
||||
|
||||
- **Front-to-back**\
|
||||
Přístup k počítání $I$, kdy paprsky vyhodnocujeme od hranice objemu **blíže** ke kameře směrem **od kamery**.
|
||||
|
||||
Dá se utnout dřív, když víme jistě, že už je výsledek neprůhledný a tedy už se nic nezmění.
|
||||
|
||||
- **Transfer function**\
|
||||
Funkce $T$, která mapuje hodnoty voxelů na barvu a průhlednost. Klasifikuje voxely. [pa213](#pa213)
|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[pa010-2020,1]]] Sochor: PA010 Intermediate Computer Graphics (podzim 2020)
|
||||
- [[[pa213, 2]]] PA213 Advanced Computer Graphics
|
||||
- [[[marching-cubes,3]]] [Marching cubes: A high resolution 3D surface construction algorithm](https://dl.acm.org/doi/10.1145/37402.37422)
|
||||
- [[[marching-tetrahedra,4]]] [Wikipedia: Marching tetrahedra](https://en.wikipedia.org/wiki/Marching_tetrahedra)
|
||||
- [[[dual-contouring,5]]] [Dual Contouring Tutorial](https://www.boristhebrave.com/2018/04/15/dual-contouring-tutorial/)
|
||||
- [[[delaunay-triangulation,6]]] [Wikipedia: Delaunay triangulation](https://en.wikipedia.org/wiki/Delaunay_triangulation)
|
||||
- [[[gpugems,7]]] [GPU Gems: Volume Rendering Techniques](https://developer.nvidia.com/gpugems/gpugems/part-vi-beyond-triangles/chapter-39-volume-rendering-techniques)
|
252
src/content/docs/szmgr/PGV07_modely_osvetleni.md
Normal file
252
src/content/docs/szmgr/PGV07_modely_osvetleni.md
Normal file
@ -0,0 +1,252 @@
|
||||
---
|
||||
title: "Lokální a globální modely osvětlení"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Blinn-Phongův osvětlovací model, BRDF, sledování paprsků, radiosita, fotonové mapy, participující média. Vykreslování založené na fyzikálních modelech (PBR). Osvětlení založené na obrázku (IBL).
|
||||
|
||||
_PB009, PV227, PA010, PA213_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
- **Lokální osvětlení (local illumination) / direct lighting**\
|
||||
Berou v úvahu jen světlo, které dopadá přímo na daný bod/objekt. Neřeší okolní objekty, ani nepřímé osvětlení. Je založený na empirických znalostech o chování světla, spíš než simulaci fyzikálních zákonů.
|
||||
|
||||
Patří sem Blinn-Phong, pomineme-li jeho ambientní složku.
|
||||
|
||||
- **Globální osvětlení (global illumination)**\
|
||||
Řeší nejen přímé osvětlení, ale i odrazy, lomy, průhlednost, stíny, atd.
|
||||
- **Ambient illumination**\
|
||||
Aproximace globálního osvětlení pomocí konstantní ambientní barvy.
|
||||
|
||||
## Blinn-Phongův osvětlovací model
|
||||
|
||||
Blinn-Phongův osvětlovací model je velice jednoduchý model osvětlení, který se skládá ze tří složek: ambientní, difuzní a spekulární. [pb009-io](#pb009-io)
|
||||
|
||||

|
||||
|
||||
### Ambientní osvětlení
|
||||
|
||||
Ambientní světlo dopadá na celý povrch rovnoměrně nerávisle na jeho pozici a orientaci. Pokud vykreslíme pouze ambient, dostáváme siluetu objektu.
|
||||
|
||||

|
||||

|
||||
|
||||
### Difuzní osvětlení
|
||||
|
||||
Difuzní osvětlení je závislé na úhlu $\alpha$ mezi normálou povrchu a vektorem ke světlu (ne na pozici kamery). Čím více je objekt kolmý na světlo, tím je v daném bodě jasnější (tím více světla absorbuje).
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
### Spekulární osvětlení
|
||||
|
||||
Spekulární osvětlení vytváří odlesky na povrchu objektu. Je závislé na úhlu $\beta$ mezi vektorem ke světlu a vektorem ke kameře.
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
### Všechno dohromady
|
||||
|
||||
Pokud spojíme dohromady ambientní složku a pro každé světlo i difuzní a spekulární složku, dostaneme výslednou barvu pixelu.
|
||||
|
||||
$C=A+\sum_{i=1}^{n} (D_i + S_i)$
|
||||
|
||||
A pokud dosadíme i konkrétní vzorce dostaneme následující rovnici:
|
||||
|
||||

|
||||
|
||||
Uvedené podmínky jsou v rovnici pro odstranění odlesků na zadní straně objektu.
|
||||
|
||||
## Bidirectional Reflectance Distribution Function (BRDF)
|
||||
|
||||
Funkce popisující poměr mezi dopajícím a odraženým světlem na povrchu objektu.
|
||||
|
||||
```math
|
||||
f(\vec{l}, \vec{v}) = \frac{\partial L_o(\vec{v})}{\partial E_i(\vec{l})}
|
||||
```
|
||||
|
||||
_Povrch je nasvícen ze směru $\vec{l}$ s ozářením $\partial E(\vec{l})$. $\partial(L_o(\vec{v}))$ je odražená zář ve směru $\vec{v}$._
|
||||
|
||||
Udává pravděpodobnost, že světlo dopadající na povrch ze směru $\vec{l}$ bude odraženo ve směru $\vec{v}$.
|
||||
|
||||
Z pohledu teorie pravděpodobnosti / statistiky to ale není distribuční funkce ale spíš hustota pravděpodobnosti.
|
||||
|
||||
BRDF je řešena pomocí ray tracingu, radiosity, nebo nějakým hybridním řešením.
|
||||
|
||||
## Ray tracing (sledování paprsků)
|
||||
|
||||
Metoda, kdy simulujeme paprsky světla vycházející ze zdroje světla a dopadající na scénu. Používá se jak k lokální tak globální iluminaci. Počítáme však jen to, co vidí kamera, jelikož posíláme paprsky skrze pixely. Pokud se kamera pohne, musíme znovu paprsky zpravidla počítat znovu.
|
||||
|
||||
Obecný postup:
|
||||
|
||||
1. Vystřelíme paprsek z kamery do scény (_primary ray_).
|
||||
2. Detekujeme kolizi s objektem ve scéně.
|
||||
3. V daném bodě vystřelíme paprsky ke každému světlu ve scéně (_shadow ray_).
|
||||
4. Pro každý paprsek zjistíme, jestli protnul nějaký objekt (stín), nebo ne (spočítáme osvětlení, např. pomocí Blinn-Phonga a připočteme ho k akumulovanému světlu, co už máme).
|
||||
5. Z bodu vystřelíme odražený a refraktovaný paprsek (_secondary rays_) a rekurzivně pokračujeme od bodu 2.
|
||||
|
||||

|
||||
|
||||
Typicky se pro realističnost hodnoty po prvním odražení zmenšují. Využívá se k tomu tzv. Fresnel-Schlickova aproximace (viz. dál).
|
||||
|
||||
- **Snellův zákon**\
|
||||
Když světlo přechází z jednoho prostředí do druhého, mění se jeho rychlost a tím i směr. Snellův zákon popisuje, jak se mění úhel světla při průchodu mezi dvěma prostředími.
|
||||
|
||||
Index refrakce $n$ je poměr rychlosti světla ve vakuu a rychlosti světla v daném prostředí. Pro vzduch je to 1, pro vodu 1.33, pro sklo 1.5, atd.
|
||||
|
||||
$frac{\sin \alpha'}{\sin \alpha} = \frac{n_1}{n_2}$
|
||||
|
||||

|
||||
|
||||
## Radiosity (metoda osvětlení)
|
||||
|
||||
Metoda, kdy scénu rozdělíme na malé segmenty plochy a simulujeme "přelévání" světla mezi segmenty. Je vypočetně náročné, ale nezávisí na pozici a směru kamery. Počítáme pouze difuzní osvětlení. Řešíme pomocí soustavy lineárních rovnic iterativně (např. Gauss-Seidel).
|
||||
|
||||
$KB = E$
|
||||
|
||||
Vytvoříme matici $K$, kde $K_{ij}$ je množství světla, které se přelilo z segmentu $i$ do segmentu $j$ (form faktor $K_{ij} = F_{ij}$). Zároveň máme vektor $E$, který určuje emitované světlo v každém segmentu. Výsledný vektor $B$ je vektor světla v každém segmentu.
|
||||
|
||||
Výhodou je, že se dá použít pro scény, kde se pohybuje kamera bez nutnosti přepočítávat. Zároveň funguje pro plošné světelné zdroje. Nevýhodou je obrovská paměťová náročnost a složitost výpočtu. Zároveň vypočítáváme pouze difuzní osvětlení.
|
||||
|
||||

|
||||
|
||||
## Fotonové mapy
|
||||
|
||||
Fotonová mapa je kombinace dvou předchozích metod: ray tracing a radiosity. Nejprve trasujeme fotony od světla (náhodný směr, součet energií by měl odpovídat energii světla) na objekty ve scéně a ukládáme informace o dopadu (_radiosity map_). Poté trasujeme paprsky od kamery, pro každý paprsek hledáme nejbližší foton a podle něj určujeme barvu pixelu.
|
||||
|
||||
Narozdíl od Raytracingu a Radiosity dokáže Photon maping simulovat i náročné efekty, jako je color bleed, nebo _caustics_ (efekt, kdy se svělo lomí typicky na hladině vody, nebo ve sklenici a vytváří místa s intenzivnějším a méně intenzivním světlem).
|
||||
|
||||

|
||||
|
||||
## Participující média
|
||||
|
||||
Participující média jsou média, která nejsou zcela průhledná, ale nejsou ani zcela matná. Jsou to např. mlha, kouř, nebo atmosféra. Osvětlení v participujících médiích je založeno na tom, že světlo se rozptyluje a absorbuje. Výsledná barva je tedy kombinací barvy objektu a barvy média.
|
||||
|
||||
## Physically based rendering (PBR)
|
||||
|
||||
Physically based rendering (PBR) je způsob renderování, který se snaží co nejvíce aproximovat realitu pomocí fyzikálních modelů světla, stínů, materiálů, očí, atd. [pv227-2022](#pv227-2022) Aproximuje efekty jako absorpci světla nebo jeho rozptyl pod povrchem objektů.
|
||||
|
||||
- **Absorption and scattering / absorpce a rozptyl**\
|
||||
Materiály mohou světlo buď absorbovat (v takovém případě jsou alespoň částěčně průhledné) nebo odrážet a rozptylovat (objekty jsou matné). Většina materiálů kombinuje oba efekty. Světlo se může rozpylovat i pod povrchem (subsurface scattering).
|
||||
- **Reflection / odraz světla**\
|
||||
V nejjednodušším případě se úhel odrazu rovná úhlu dopadu. V realitě úhel odrazu však záleží na mnoha faktorech jako je i vlnová délka světla. Toto chování popisují Fresnelovy rovnice. Znamená to, že odraz má barvu. V praxi používáme Schlickovu aproximaci:
|
||||
|
||||
```math
|
||||
F_\text{Schlick}(F_0, L, N) = F_0 + (1 - F_0) \cdot (1 - L \cdot N)^5
|
||||
```
|
||||
|
||||
kde:
|
||||
|
||||
- $F_0$ je Fresnelův odraz při úhlu 0 (dá se dohledat pro daný materiál),
|
||||
- $L$ je vektor směru světla,
|
||||
- $N$ je vektor normály povrchu.
|
||||
|
||||
**Z určitého úhlu se povrchy, které normálně světlo odráží špatně, jeví jako zrcadla ([tanakawho](https://commons.wikimedia.org/w/index.php?curid=2138545))**
|
||||
|
||||

|
||||
|
||||
- **Refraction / lom světla**\
|
||||
Kovy světlo absorbují, v homogenních materiálech (např. sklo) pokračuje v jiném směru, a v heterogenních materiálech (např. kůži) se světlo rozptýlí a pak absorbuje. Lom světla popisuje Snellův zákon:
|
||||
|
||||
```math
|
||||
\frac{\sin \alpha_1}{\sin \alpha_2} = \frac{v_1}{v_2} = \frac{n_2}{n_1}
|
||||
```
|
||||
|
||||
kde:
|
||||
|
||||
- $\alpha_1$ je úhel dopadu (angle of incidence),
|
||||
- $\alpha_2$ je úhel lomu (angle of refraction),
|
||||
- $v_1$ je rychlost šíření vlnění ve vnějším prostředí,
|
||||
- $v_2$ je rychlost šíření vlnění v prostředí objektu,
|
||||
- $n_1$ je index lomu vnějšího prostředí,
|
||||
- $n_2$ je index lomu prostředí objektu.
|
||||
|
||||

|
||||
|
||||
- **Diffuse lighting**\
|
||||
Když všechno (neabsorbované) světlo opustí objekt ze stejného místa, kam dopadlo.
|
||||
|
||||

|
||||
|
||||
- **Subsurface scattering**\
|
||||
Když neabsorbované světlo opustí objekt z jiného místa, než kam dopadlo.
|
||||
|
||||

|
||||
|
||||
- **Microfacets / mikro-plošky**\
|
||||
Ne všechny objekty jsou ploché. Většina má nerovnosti, které jsou menší než pixel, ale větší než vlnová délka dopadajícího světla, proto je modelujeme nějakou pravděpodobností distribucí (např. Gaussovou).
|
||||
|
||||

|
||||
|
||||
Existuje řada modelů chování microfacet, např. Cook-Torrance, Oren-Nayar, Ashnikmin-Shirley, Normalized Blinn-Phong, atd.
|
||||
|
||||
- **Cook-Torrance model**\
|
||||
Cook-Torrance je osvětlovací model založený na mikrofacetách. Materiál má jeden parametr, který určuje, jak moc je povrch hrubý ($0 \leq m \leq 1$).
|
||||
- **Geometrická atenuace**\
|
||||
Postupná ztráta "intenzity" paprsku v důsledku geometrie objektu.
|
||||
|
||||
- **Shadowing** -- facety zastiňují jiné facety.
|
||||
- **Masking** -- facet nejde vidět, protože ho zastiňuje jiný facet.
|
||||
- **Interreflection** -- světlo se odráží mezi facety, než je odraženo zpátky ke kameře.
|
||||
|
||||
### Fyzikální věličiny radiometrie
|
||||
|
||||
- **Radiant energy / energie záření (Q)**\
|
||||
"Energy per one photon."
|
||||
|
||||
Jednotka: Joule (J)
|
||||
|
||||
- **Radiant flux, radiant power / zářivý tok ($\Phi$)**\
|
||||
"Energy per second." Bezva na popisování síly světel jako jsou žárovky, plošná světla, atd.
|
||||
|
||||
```math
|
||||
\Phi = \frac{\partial Q}{\partial t}
|
||||
```
|
||||
|
||||
Jednotka: Watt (W) = J/s
|
||||
|
||||
- **Irradiance / ozářenost, ozáření (E)**\
|
||||
"Flux through area." Světlo dopadající na jednotku plochy. Kvadraticky se zmenšuje s rostoucí vzdáleností od zdroje. Bezva na popis vzdálených zdrojů jako je slunce.
|
||||
|
||||
```math
|
||||
E = \frac{\partial \Phi}{\partial A}
|
||||
```
|
||||
|
||||
Jednotka: Watt per square meter ($\frac{W}{m^2}$)
|
||||
|
||||
- **Radiosity / radiozita (radiometrická veličina) (J)**\
|
||||
Jako irradiance, ale je to světlo _vycházející_ z jednotky plochy.
|
||||
- **Radiance / zář (L)**\
|
||||
"Flux through a cone of directions from an area." a nebo "Flux through an area from a cone of directions." Nezmenšuje se se zvětšující se vzdáleností od zdroje. Tohle měří senzory.
|
||||
|
||||
```math
|
||||
L = \frac{\partial^2 \Phi}{\partial A_\text{proj} \partial \omega}
|
||||
```
|
||||
|
||||
Jednotka: Watt per square meter per steradian ($\frac{W}{m^2 \cdot sr}$)
|
||||
|
||||
## Image-based lighting (IBL)
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Tahle část otázky by si možná zasloužila rozšířit, ale bohužel tomu víc nerozumím :D
|
||||
|
||||
</dd></dl>
|
||||
|
||||
IBL využívá envitornmentálních textur (HDR CubeMap, ...) pro vyhodnocení světla z každého směru scény.
|
||||
|
||||
Pro výpočet difuzního osvětlení musíme matematicky spočítat integrál nad celým povrchem sféry (hemisféry) okolo bodu, který chceme osvětlit a pro každý směr světla z envitornmentální textury spočítat osvětlení. V praxi to provedeme výpočtem několika vzorků a jejich průměrem.
|
||||
|
||||
Pro výpočet spekulárního osvětlení se používá zrcadlový vektor a Fresnelova rovnice. Chování materiálu popisuje Cook-Torrance model materiálu.
|
||||
|
||||

|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[pv227-2022, 1]]] [PV227 GPU Rendering (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PV227/)
|
||||
- [[[pb009-io, 2]]] [Interaktivní osnova PB009 by xrosecky](https://is.muni.cz/auth/el/fi/jaro2023/PB009/index.qwarp)
|
249
src/content/docs/szmgr/PGV08_real_time_rendering.md
Normal file
249
src/content/docs/szmgr/PGV08_real_time_rendering.md
Normal file
@ -0,0 +1,249 @@
|
||||
---
|
||||
title: "Vykreslování v reálném čase"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Ořezávání, techniky založené na viditelnosti, vykreslování s různou úrovní detailů (LOD rendering), vykreslování terénu. Stíny: tvrdé stíny, měkké stíny, techniky vykreslování stínů v prostoru scény a v obrazovém prostoru.
|
||||
|
||||
_PA010, PA213_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
- **Real time rendering**\
|
||||
Snažíme se zlevnit a zrychlit vyrenderování jednoho snímku scény. Můžeme toho docílit typicky zahozením částí, které nejsou vidět a nahrazením drahého renderování vzdálených objektů levnějším.
|
||||
|
||||
## Ořezávání (Culling)
|
||||
|
||||
Snažíme se najít množinu objektů, které můžeme vyřadit z renderování aniž by to (zásadně) snížilo kvalitu renderu.
|
||||
|
||||
### Back Face Culling
|
||||
|
||||
Ořízneme pryč trojúhelníky, které jsou k nám otočené "zády" (tedy jejich trojúhelníky mají normálu od kamery)
|
||||
|
||||
### View Frustum Culling
|
||||
|
||||
Ořízneme pryč objekty, které se nemají šanci nacházet ve view frustu. Využíváme k tomu AABBs jednotlivých objektů, kde testujeme průnik tohoto AABB s view frustem.
|
||||
|
||||
## Analýza viditelnosti
|
||||
|
||||
- **Offline**\
|
||||
Viditelnost je předpočítaná, v každém snímku se pouze podíváme do paměti, které objekty jsou z aktuálního místa kamery viditelné.
|
||||
|
||||
Offline analýzu lze aplikovat pouze na statické scény, je paměťově náročná.
|
||||
|
||||
- **Online**\
|
||||
Viditelnost počítáme v každém snímku.
|
||||
|
||||
Je možné ji používat na dynamické scény, je časově náročná.
|
||||
|
||||
- **Hybridní**\
|
||||
Kombinace předchozích přístupů. Předpočítáme část podpůrných dat pro algoritmus a zbytek počítáme každý snímek.
|
||||
|
||||
### Portal Culling
|
||||
|
||||
Uvažme graf, kde jednotlivé logické celky (například místnosti) představují vrcholy a portály (dveře) mezi těmito místnostmi představují vrcholy, které místnosti propojují. Každý portál má asociovanou geometrii, která odpovídá viditelnému průchodu.
|
||||
|
||||

|
||||
|
||||
geometrie $\pi_{i,j} = \pi_{j,i}$
|
||||
|
||||
Toto všechno je předpočítané.
|
||||
|
||||
**_V každém snímku:_**
|
||||
|
||||
1. Spočítáme, ve které místnosti se nachází kamera
|
||||
2. Vyrenderujeme tuto místnost
|
||||
3. Promítneme všechny portály této místnosti na obrazovku
|
||||
4. Aproximujeme tyto projekce AA bounding obdélníky
|
||||
5. Vypočítáme, které obdélníky protínají obrazovku a zjistíme, kam vedou
|
||||
6. V nových místnostech opět promítneme všechny portály a aproximujeme je
|
||||
7. Zjistíme, které obdélníky protínají předchozí portál a zjistíme, kam vedou
|
||||
8. Opakujeme, dokud máme kam postupovat, nebo jsme dosáhli maximálního počtu iterací.
|
||||
|
||||

|
||||
|
||||
Je možné použít vyhledávací struktury, jako je Octree jak na objekty v místnostech, tak na místnosti samotné (kvůli lokalizaci kamery).
|
||||
|
||||
Pokud je něco na hraně (v portálu), musíme řešit specificky. Je možné rozšířit i o zrcadla, "portály" atd.
|
||||
|
||||
### Occlusion Culling
|
||||
|
||||
Chceme ořezat objekty, které jsou z pohledu kamery určitě celé zakryté ostatními objekty (dohromady = _cumulative oclusion_). Potřebujeme nějakou strukturu, která si bude ukládat kumulativní okluzi: _CumulativeOclusionRep_ -> Typicky Z-buffer.
|
||||
|
||||
Můžeme využívat tzv. Hardware Occlusion Query - tedy toho, že nám GPU řekne, kolik pixelů z daného objektu vyrenderovalo. Pokud je toto číslo pod hranicí viditelnosti víme, že daný objekt nemusíme renderovat. V takovém případě můžeme místo tohoto objektu renderovat pouze jeho bbox (lacinější) a u toho detekovat, když je zase vidět.
|
||||
|
||||

|
||||
|
||||
Problémy při přechodu jsou typicky zanedbatelné. Může nastat "blikání" tam a zpátky, taky zanedbatelné.
|
||||
|
||||
- **Hierarchický Z-buffer**\
|
||||
Je možné vytvořit hierarchii depth map ze Z-bufferu (podobnou, jako jsou mipmapy) a v té potom vyhledávat. Jen tam místo průměru uložíme nejzazší hodnotu. Při kontrole pak můžeme porovnat, jestli bbox vykreslovaného objektu je za (určitě schovaný), nebo před (sestupujeme hlouběji).
|
||||
|
||||
## Detail Culling
|
||||
|
||||
3D objekty mohou být definované mnoha miliony polygony či výpočetně náročnými matematickými funkcemi. Při renderování není třeba je vždy zobrazovat v té největší kvalitě. Pokud jsou objekty typicky daleko, je zbytečné na objektu renderovat tisíce polygonů, když daný objekt zabírá dva pixely obrazovky. K tomu využíváme LOD (level-of-detail)
|
||||
|
||||
Kroky LOD algoritmu:
|
||||
|
||||
1. **Generování** -- Musíme vytvořit jednotlivé modely s různými úrovněmi detailů
|
||||
2. **Výběr** -- Metrika, která určuje, jak moc daný model přispívá celkovému obrazu
|
||||
3. **Přepínání** -- Metoda změny z jednoho modelu na druhý (snažíme se zamezit náhlým změnám)
|
||||
|
||||
### Generování
|
||||
|
||||
Typicky z detailnějšího modelu vytváříme méně detailní
|
||||
|
||||
- Snižováním počtu trojúhelníků (High-poly -> Low-poly -> Billboard -> Prázdný model)
|
||||
- Snižováním kvality osvětlení (Phong -> Gouraud -> Ambient)
|
||||
- Snižováním kvality textur (Všechny textury -> Jen difuzní -> Jen barvy vrcholů)
|
||||
|
||||
### Výběr
|
||||
|
||||
- **Podle vzdálenosti**\
|
||||
Čím dále, tím nižší LOD. Můžeme přidat dead-zones, kde se LOD nemůže měnit -- zabráníme tak častým změnám na určitém místě.
|
||||
- **Podle projekční plochy**\
|
||||
Promítneme objekt, nebo (častěji) nějaký obalující objem (AABB, kouli, ...) na obravovku a zjistíme plochu (nebo třeba průměr koule).
|
||||
- **Další metody výběru**\
|
||||
Podle důležitosti, pohyb, focus, ...
|
||||
|
||||
### Přepínání
|
||||
|
||||
- **Diskrétní modely**\
|
||||
Přepínání mezi třemi nezávislými diskrétními modely je rychlé a efektivní, ale způsobuje "Popping efekt" (kdy se nám objekt náhle změní před očima -- ruší to)
|
||||
- **Alfa LOD**\
|
||||
Jedna úroveň detailů, objekt je čím dál průhlednější až pak v jednu chvíli zmizí a nerenderujeme ho vůbec. Ne příliš efektivní (pořád renderujeme složitý objekt) a navíc potřebuje blending! Nemá ale popping efekt vůbec.
|
||||
- **Blending LODs**\
|
||||
Při přepínání LOD renderujeme chvíli dva modely zároveň, jednomu zvyšujeme průhlednost a druhému snižujeme. Redukujeme tím popping efekt, ale zase neefektivní, protože chvíli renderujeme dva modely místo jednoho, taky blending!
|
||||
- **Kontinuální LODs**\
|
||||
Dynamicky generujeme modely s méně polygony (edge collapse) podle aktuální úrovně. Toto redukuje popping efekt, ale je to velice náročné na implementaci a taky ne každý collapse vypadá dobře (je těžký problém vybrat správné hrany, možná je třeba nadefinovat manuálně).
|
||||
- **Geomorfní LODs**\
|
||||
Nejen, že dynamicky smršťuje hrany, ale dělá to postupně a plynule. Toto úplně potlačuje popping efekt, ale objekty vypadají, že se konstantně mění. Zároveň je implementace velice náročná.
|
||||
|
||||

|
||||
|
||||
## Vykreslování terénu
|
||||
|
||||
Terén může být reprezentován
|
||||
|
||||
- **dlaždicemi (2D, 3D)** -- pro pravidelnou mřížku určují co se nachází na jednotlivých polích
|
||||
- **síťí (mesh)** -- 3D model složený typicky z trojúhelníků
|
||||
- **výškovou mapou (heightmap)** -- 2D obraz, kde barva určuje výšku terénu; nepodporuje převisy, jeskyně, ...
|
||||
- **digitálními vrstevnicemi (digital contours)** -- kontrolní body splajn, za runtime snadno vytvoříme triangle strips
|
||||
- **voxely** -- 3D krychle (typicky), které určují, co se nachází na daném místě
|
||||
|
||||
### Dlaždice
|
||||
|
||||
Často výrazné tvrdé přechody mezi dlaždicemi - můžeme smíchat dohromady více textur na hranách dlaždic.
|
||||
|
||||
- **Texture splatting**\
|
||||
Pro každou dlaždici máme několik textur, které se na ní mohou vyskytovat. Použijeme _alpha mask_, kterou pronásobíme každou texturu a pak je sečteme.
|
||||
|
||||
Pro čtvercové dlaždice existuje jen 32 možných kombinací, takže můžeme tyto textury předpřipravit.
|
||||
|
||||
- **3D**\
|
||||
I ve 3D hrách se často používají dlaždice, kde často bývají vlastně 2D, jen je vykreslujeme ve 3 dimenzích. Tam typicky bereme připravené modely a umístíme je na dané místo.
|
||||
|
||||
### Mesh
|
||||
|
||||
Mesh už je množina trojúhelníků, které prostě vykreslíme na GPU.
|
||||
|
||||
### Heightmap
|
||||
|
||||
U heightmap můžeme rozdělit prostor na quady a každý z nich pak napůl a body umístit do správné výšky (viz obrázek)
|
||||
|
||||

|
||||
|
||||
Může nastat problém s nejednoznačností (_ambiguity_). Ta se většinou ignoruje.
|
||||
|
||||

|
||||
|
||||
Výslednou mesh můžeme vyrenderovat, jako triangle strips.
|
||||
|
||||
### Voxely
|
||||
|
||||
Můžeme buď vyrenderovat krychle, ale to je neefektivní, protože krychle sdílejí strany. Alternativně můžeme vyhladit povrch pomocí Marching cubes, nebo použít raytracing.
|
||||
|
||||
### Výkon a zjednodušení
|
||||
|
||||
Často potřebujeme renderovat obrovské mapy a je zbytečné vzdálené body renderovat s nejvyšší kvalitou. Místo toho můžeme použít několik technik pro jejich odřezání / zjednodušení.
|
||||
|
||||
- **Quadtree**\
|
||||
Máme uložených několik úrovní detailů pro celou mapu. Podle vzdálenosti od kamery určíme, jak hluboko (jak detailně) sestoupíme v našem stromě. Zároveň můžeme strom využít pro aplikaci frustum cullingu. CPU musí upravovat mesh.
|
||||
- **ROAM**\
|
||||
Podobné quadtrees, ale využívá trojúhelníků místo quads. Dynamicky mění úroveň detailů podle vzdálenosti od kamery. CPU musí upravovat mesh.
|
||||
- **Triangle Bintree**\
|
||||
Dělí trojúhelníky víc a víc, čím blíže jsou ke kameře. CPU musí upravovat mesh.
|
||||
|
||||

|
||||
|
||||
- **Geometry Clipmaps**\
|
||||
Chová se k terénu, jako k obrázku s mipmapami. Čím blíže je kamera, tím větší detail. GPU si sám upravuje mesh.
|
||||
|
||||
Je nutné hranice mezi jednotlivými částmi meshů vyhlazovat, aby nebyly vidět.
|
||||
|
||||

|
||||
|
||||
- **Tessellation**\
|
||||
GPU si sám upravuje mesh podle vzdálenosti od kamery. Můžeme využít i geometry shader, který nám umožní upravovat mesh v průběhu renderování.
|
||||
|
||||
## Techniky renderování stínů
|
||||
|
||||
Stíny jsou důležité, jelikož:
|
||||
|
||||
- zvyšují věrohodnost scény,
|
||||
- jsou indikátorem vzdálenosti objektů od sebe -- hloubky scény,
|
||||
- mohou dávat informaci o objektech, které jsou mimo zorné pole kamery nebo ukryté za jinými objekty,
|
||||
- popisují tvar objektu, na který jsou promítány.
|
||||
|
||||
- **Hard shadows / "ostré" stíny**\
|
||||
Rozlišují jen, zda je bod osvětlený nebo ne. Neřeší se, jak moc je osvětlený. Týká se bodových světel.
|
||||
|
||||

|
||||

|
||||
|
||||
- **Soft shadows / "měkké" stíny**\
|
||||
Rozlišují i částečně osvětlené oblasti. Týká se světel, která mají plochu.
|
||||
|
||||

|
||||

|
||||
|
||||
- **Planar shadows**\
|
||||
Vykreslí objekt ještě jednou projektovaný na danou plochu.
|
||||
|
||||
- Použitelné na velké plochy jako je rovná podlaha či stěny.
|
||||
- Blinn (1988)
|
||||
- Jednoduché a rychlé.
|
||||
- Nedá se použít na sebevržené stíny, stíny vržené na jiné objekty, kulaté plochy, atd.
|
||||
|
||||
- **Fake shadows and Projective textures**\
|
||||
Použitelné pro velice málo velmi velkých dopadových objektů.
|
||||
|
||||
1. Vyrenderuj objekt černobíle z pohledu světla a ulož do textury.
|
||||
2. Projektuj tuhle texturu na **každý** objekt, na který má dopadat stín.
|
||||
|
||||
- **Shadow maps**\
|
||||
Renderuje scénu z pohledu světla, ale ukládá si do textury jen hloubku. Při vykreslování scény z pohledu kamery sampleuje texturu a porovnává vzdálenost od světla s hloubkou v textuře. Pokud je větší, je bod ve stínu.
|
||||
|
||||

|
||||
|
||||
**❗ IMPORTANT**\
|
||||
Shadow mapám se důkladně věnuje otázka [Renderování s využitím GPU](../renderovani-s-vyuzitim-gpu/)
|
||||
|
||||
- **Shadow volumes**\
|
||||
Počítá stíny ve 3D. Shadow volume explicitně popisuje objem prostoru ve stínu nějakého polygonu.
|
||||
|
||||
1. Pro každý shadow caster, vyrob shadow volume.
|
||||
2. Pro každý fragment, počítej do kolika objemů paprsek z kamery do fragmentu vstoupí (+1) a z kolika vystoupí (-1). Pokud je výsledek > 0, pak je fragment ve stínu, pokud je 0 tak je osvětlený.
|
||||
|
||||

|
||||
|
||||
Prakticky se používá Stencil Buffer Algorithm, kdy renderujeme pro každý objekt nejprve front faces a pak back faces. Tenhle přístup je problematický, pokud je kamera ve stínu, ale řešitelný pokud obrátíme pořádí objektů -- jdeme od nekonečna ke kameře (Z-fail, Carmack’s reverse).
|
||||
|
||||
- **Soft shadows**\
|
||||
Existuje množství algoritmů. Například shadow mapy s Percentage Closer Filtering (PCF). Jsou ale výpočetně náročnější než hard shadows.
|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[pa010-2021,1]]] Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021)
|
356
src/content/docs/szmgr/PGV09_minimalizace_energie.md
Normal file
356
src/content/docs/szmgr/PGV09_minimalizace_energie.md
Normal file
@ -0,0 +1,356 @@
|
||||
---
|
||||
title: "Zpracování obrazu pomocí minimalizace energie"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Variační filtrování. Aktivní křivky a plochy (geodetický model, Chan-Vese model). Minimalizace pomocí grafových řezů. Variační optický tok.
|
||||
|
||||
_PA166_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
## Variační filtrování
|
||||
|
||||
Variační filtrování neřeší lokálně jednotlivé pixely, ale snaží se minimalizovat enetgii celého obrázku.
|
||||
|
||||
Typickým předpisem takovéhle funkce je
|
||||
|
||||
```math
|
||||
E_f(u) = \int_{\Omega} ( \underbrace{(u - f)^2}_\text{similarity} + \alpha \underbrace{\Psi (| \nabla u |^2)}_\text{smoothness} ) dx
|
||||
```
|
||||
|
||||
Chceme, aby byl obrázek co nejpodobnější původnímu (_data/similarity term_), ale zároveň co nejvíc vyhlazený (_smoothness term/regularizer/penaliser_). Poměr těchto dvou členů určuje parametr $\alpha$. Regularizer $\Psi$ určuje “metodu” vyhlazení:
|
||||
|
||||
| | |
|
||||
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------ |
|
||||
| **_Tikhonov (linear)_** -- identita | $\Psi(\lvert \nabla u \rvert^2) = \lvert \nabla u \rvert^2$ |
|
||||
| **_Charbonnier_** | $\Psi(\lvert \nabla u \rvert^2) = 2 \lambda^2 \sqrt{1 + \lvert \nabla u \rvert^2 / \lambda^2} - 2 \lambda^2$ |
|
||||
| **_Total Variation_** | $\Psi(\lvert \nabla u \rvert^2) = 2\sqrt{\lvert \nabla u \rvert^2} = 2\lvert\nabla u\rvert$ |
|
||||
|
||||
Tuto funkci můžeme minimalizovat dvěma způsoby:
|
||||
|
||||
### Přímé řešení (lineární funkce)
|
||||
|
||||
Provedeme diskretizaci a poté parciálně zderivujeme pro jednotlivé pixely. Tím dostáváme sadu lineárních funkcí položených nule. Tyto poté položíme do matice, kterou řešíme. Matice má hodnoty pouze kolem diagonály, což znamená, že je velmi rychle řešitelná např. pomocí Thomas method.
|
||||
|
||||
Pokud je obraz 2D, bereme všechny pixely jako dlouhou 1D posloupnost a řešíme obdobně.
|
||||
|
||||
Matice je ale obrovská, proto můžeme využít např. Gauss-Seidel metodu, s pomocí které matici řešíme iterativně po řádcích.
|
||||
|
||||
### Nelineární řešení
|
||||
|
||||
Použijeme Variační kalkulus, který dokáže minimalizovat Funkcionály
|
||||
|
||||
- **Funkcionál**\
|
||||
Bere na vstupu funkci a přiřazuje jí nějakou hodnotu $u(x) \Rightarrow \mathbb{R}$.
|
||||
|
||||
Pro řešení můžeme nyní využít Euler-Lagrangeovy rovnice. Pro funkcionál $E_f(u) = \int_{\Omega} ( (u - f)^2 + \alpha \Psi (| \nabla u |^2) ) dxdy$ získáme předpis pro minimalizaci:
|
||||
|
||||
```math
|
||||
0 = u - f - \alpha \text{div}(\Psi'(\lvert \nabla u \rvert^2) \nabla u)
|
||||
```
|
||||
|
||||
Nyní můžeme hezky vidět vztah k difuznímu filtrování (otázka [PGV10](../zpracovani_obrazu_pomoci_PDE)):
|
||||
|
||||
| | |
|
||||
| ------------------------ | ------------------------------------------------------------------------------ |
|
||||
| **_Variační metoda_** | $\frac {u - f}{\alpha} = \text{div}(\Psi'(\lvert \nabla u \rvert^2) \nabla u)$ |
|
||||
| **_Difuzní filtrování_** | $\partial_t u = \text{div}(\Psi'(\lvert \nabla u \rvert^2) \nabla u)$ |
|
||||
|
||||
Přičemž vidíme, že
|
||||
|
||||
- **Tikhonov regulariser** ~ **Linear diffusivity**
|
||||
- $\Psi(\lvert \nabla u \rvert^2) = \lvert \nabla u \rvert^2$
|
||||
- $\Psi'(\lvert \nabla u \rvert^2) = 1$
|
||||
- **Charbonnier regulariser** ~ **Charbonnier diffusivity**
|
||||
- $\Psi(\lvert \nabla u \rvert^2) = 2 \lambda^2 \sqrt{1 + \lvert \nabla u \rvert^2 / \lambda^2} - 2 \lambda^2$
|
||||
- $\Psi'(\lvert \nabla u \rvert^2) = \frac{1}{\sqrt{1 + \lvert \nabla u \rvert^2 / \lambda^2}}$
|
||||
- **Total Variation regulariser** ~ **Total Variation diffusivity** s difusivitou $\frac{1}{\lvert \nabla u \rvert}$
|
||||
- $\Psi(\lvert \nabla u \rvert^2) = 2\lvert\nabla u\rvert$
|
||||
- $\Psi'(\lvert \nabla u \rvert^2) = \frac{1}{\lvert \nabla u \rvert}$
|
||||
|
||||
## Aktivní křivky a plochy
|
||||
|
||||
- **Segmentace**\
|
||||
Chceme rozdělit obrázek podle něčeho (region based, edge based, texture, …)
|
||||
- **Segmentace založená na energii**\
|
||||
Hledáme konturu s minimální energií. Závisí na volbě iniciální křivky - hledá pouze lokální minimum.
|
||||
|
||||
### Hadi
|
||||
|
||||
Působí dvě energie:
|
||||
|
||||
- Vnitřní - tvar a plynulost křivky
|
||||
- Vnější - omezení z obrázku
|
||||
|
||||
Kontura zadaná, jako parametrická křivka $p(s): [0, 1] \rightarrow \mathbb{R}\ \ \ \ p(s) = (x(s), y(s))^T$. Podobně, jako u variačního filtrování, definujeme funkcionál energie, který se snažíme minimalizovat:
|
||||
|
||||
```math
|
||||
E(p) = \int_0^1 E_{int}(p(s)) + E_{ext}(p(s)) ds
|
||||
```
|
||||
|
||||
Kde $E_{int}$ je **vnitřní energie**, kde $\alpha$ a $\beta$ jsou váhy pro délku ($\alpha$) a křivost ($\beta$) křivky:
|
||||
|
||||
-
|
||||
|
||||
```math
|
||||
E_{int}(p(s)) = \alpha(s) \lvert p'(s) \rvert^2 + \beta(s) \lvert p''(s) \rvert^2
|
||||
```
|
||||
|
||||
A $E_{ext}$ je **vnější energie**, kde $P$ je potenciální funkce:
|
||||
|
||||
-
|
||||
|
||||
```math
|
||||
E_{ext}(p(s)) = P(p(s))
|
||||
```
|
||||
|
||||
- **Potenciál**\
|
||||
Potenciál určuje vztah křivky k obrázku. Může být definován různými způsoby:
|
||||
|
||||
- **Hrany** - $P(x, y) = -\lvert \nabla f(x, y) \rvert^2$
|
||||
- **Hrany po rozmazání** - $P(x, y) = -\lvert \nabla (G_{\sigma}(x, y) * f(x, y) )\rvert^2$
|
||||
- **Linie** - $P(x, y) = -f(x, y)$
|
||||
- **Linie po rozmazání** - $P(x, y) = -G_{\sigma}(x, y) * f(x, y)$
|
||||
|
||||
Minimalizaci funkcionálu chceme opět udělat Euler-Lagraneovou rovnicí, tedy:
|
||||
|
||||
```math
|
||||
\alpha p''(s) + \beta p'''(s) - \nabla P = 0 \text{, kde } p(0), p'(0), p(1), p'(1) \text{ jsou zadané}.
|
||||
```
|
||||
|
||||
Na derivace můžeme použít finite differences a přepíšeme výsledek do matice $AX = F_{ext}$. Blbý ale je, že F*{ext} závisí na p a p závisí na F*{ext}. Proto se to řeší iterativně $\frac{\partial p}{\partial t} = F_{int}(p) + F_{ext}(p)\\p(s, 0) = p_0(s)$
|
||||
|
||||
- **Problémy**
|
||||
- Reparametrizace
|
||||
- Body mají tendenci se slévat do míst s nízkou potenciální energií
|
||||
- Musíme jednou za čas rozmístit body pravidelně podél vzniklé křivky
|
||||
- Normalizace (Diskretizace času)
|
||||
- Velikost gradientu není ničím omezena a může nám “vystřelit” body úplně do kša
|
||||
- Místo klasického gradientu vezmeme gradient normalizovaný, tedy jen směr
|
||||
- Diskretizace prostoru
|
||||
- Potenciální funkce je spočítaná pouze v diskrétních bodech, ale křivka může procházet i mimo tyto body
|
||||
- Na dopočítání použijeme například bilineární interpolaci
|
||||
- Problémy předchozí detekce hran
|
||||
|
||||
- Výsledkem detekce hran je často binární obrázek, kde by ale křivka nevěděla, kam se pohybovat - kuličky jsou na rovině
|
||||
- Můžeme obrázek Gaussovsky rozmazat, nebo dopočítat vzdálenost všech bodů od bodů hran (distance function from the edge pixels)
|
||||
|
||||

|
||||
|
||||
- Balonování
|
||||
|
||||
- Kontury mají tendenci se slévat do středu do jednoho bodu, kde zaniknou
|
||||
- Často chceme detekovat něco, kde začneme uvnitř
|
||||
- K externím silám přidáme tzv. balonovou sílu ve směru normály křivky
|
||||
|
||||
$$F_{ext} = k_1 n(s) - k \frac{\nabla P}{|\nabla P|}$$
|
||||
|
||||
- Parametr $k_1$ ovlivňuje, jestli se křivka “nafukuje”, nebo “vyfukuje”, můžeme měnit během iterování
|
||||
|
||||
- GVF Snakes
|
||||
- Kontury mají problém opsat “tvar rohlíku” a nic je nenutí dostávat se do úzkých prostor
|
||||
|
||||

|
||||
|
||||
- Převedeme externí síly na nové pole sil, kterému říkáme Gradient Vector Flow
|
||||
- Chceme v podstatě přidat síly tam, kde nejsou hrany, aby celý prostor k hranám směřoval
|
||||
|
||||

|
||||
|
||||
### Geodetické aktivní křivky
|
||||
|
||||
Hloupé na hadech (to, co jsem popisoval doteď) je, že závisí na parametrizaci (rozložení bodů na křivce). GAC naopak na parametrizaci nezávisí.
|
||||
|
||||
Pro křivku minimalizujeme funkcionál (_Chceme co nejmenší délku křivky && co nejnižší celkový gradient_): +
|
||||
|
||||
```math
|
||||
E_{GAC}(C) = \int_0^1 g(\underbrace{\lvert \nabla G_{\sigma} * I(C(q)) \rvert}_{\text{Vyhlazený obrázek}}) \underbrace{\lvert C'(q) \rvert}_{\text{Délka křivky}} dq
|
||||
```
|
||||
|
||||
Funkce $g$ snižuje vliv délky na energii, pokud leží v místech s vysokým gradientem, protože je nepřímo úměrná rozmazanému gradientu: +
|
||||
|
||||
```math
|
||||
g(\lvert \nabla G_{\sigma} * I(x, y) \rvert) = \frac{1}{1 + \lvert \nabla G_{\sigma} * I(x, y) \rvert}
|
||||
```
|
||||
|
||||
### Chan-Vese model
|
||||
|
||||
Do teď jsme neřešili, co je uvnitř kontur (homogenita), jen co je přímo pod nimi. Chan-Vese model se snaží najít konturu, která rozdělí obrázek na dvě části s různými intenzitami.
|
||||
|
||||
```math
|
||||
E_{CV}(\underbrace{C}_{\text{Křivka}}, \underbrace{c_1}_{\substack{\text{Odhad} \\ \text{popředí}}}, \underbrace{c_2}_{\substack{\text{Odhad} \\ \text{pozadí}}}) =
|
||||
\underbrace{\mu L(C)}_{\text{Délka křivky}} + \underbrace{\lambda_1 \int_{\Omega_1} (f(x) - c_1)^2 dx}_{\text{Odlišnost popředí od odhadu}} + \underbrace{\lambda_2 \int_{\Omega_2} (f(x) - c_2)^2 dx}_{\text{Odlišnost pozadí od odhadu}}
|
||||
```
|
||||
|
||||
- **_Regularity term_** - délka dělící křivky
|
||||
- **_Data term (2x)_** - rozdíl částí (fg,bg; $\Omega_1, \Omega_2$) od konstantního odhadu $c_1, c_2$
|
||||
- Parametry $\mu, \lambda_1, \lambda_2$ určují vyhlazení, variabilitu pozadí a popředí respectively
|
||||
- Pro danou křivku C jsou optimální $c_1, c_2$ s průměrnou hodnotou
|
||||
|
||||
Abychom se zbavili integrálů přes část oblasti, můžeme použít Harveside funkci, která vrací 0 pro nulu a 1 jinak. Tím dostaneme:
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
E_{CV}(C, c_1, c_2) &= \mu \int_{\Omega} \lvert \nabla H (u(x)) \rvert dx &\footnotesize{\text{ Délka křivky}}\\
|
||||
&+ \lambda_1 \int_{\Omega} (f(x) - c_1)^2 H(u(x)) dx &\footnotesize{\text{ Odlišnost popředí od odhadu}}\\
|
||||
&+ \lambda_2 \int_{\Omega} (f(x) - c_2)^2 (1 - H(u(x))) dx &\footnotesize{\text{ Odlišnost pozadí od odhadu}}\\
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
Diskretizujeme a řešíme.
|
||||
|
||||
## Minimalizace pomocí grafových řezů
|
||||
|
||||
Rozdělení metodou minimálního řezu využívá algoritmu pro hledání minimálního řezu v grafech. Uvažme graf, kde každý pixel je jeden vrchol a pro všechny pixely vytvoříme hrany ze zdroje (s) a spotřebiče (t) a hrany mezi sousedy.
|
||||
|
||||

|
||||
|
||||
- **Riemannovy metrické systémy**\
|
||||
Normálně, když počítáme délku mezi dvěma body, počítáme ji, jako $d = \sqrt{u^T \cdot u}$. Můžeme ale přidat tzv. metrický tensor $M$, který může tuto délku upravit v závislosti na směru $d = \sqrt{u^T \cdot M \cdot u}$. Díky tomu potom můžeme měřit nejen euklidovskou vzdálenost, ale třeba:
|
||||
|
||||
- **Euklidovskou vzdálenost** - $M = I$ (identita)
|
||||
- **Geodetickou vzdálenost** - $M = \text{diag}(g(\lvert \nabla I(\cdot) \rvert))$
|
||||
- **Anizotropní vzdálenost** - $M = g(\lvert \nabla I(\cdot) \rvert) \cdot E + (1 - g(\lvert \nabla I(\cdot) \rvert)) \cdot u \cdot u^T$ (kde $u = \frac{\nabla I}{\lvert \nabla I \rvert}$ jednotkový vektor ve směru gradientu a $E$ je identita)
|
||||
|
||||
Pro aproximaxi vah hran v našem grafu můžeme použít Riemannovu metriku:
|
||||
|
||||
```math
|
||||
w_k^R = w_k^{\epsilon} \cdot \frac{\text{det} M}{(u_k^T \cdot M \cdot u_k)^{p}}
|
||||
```
|
||||
|
||||
### Geodetická segmentace
|
||||
|
||||
Můžeme rozdělit obrázek na dvě části pomocí minimálního řezu na dvě části podle geodetické vzdálenosti.
|
||||
|
||||
- **t-linky (hrany do _s_ nebo do _t_)** - nastavíme váhy na 0 vyjma pixelů s omezením (víme, že jsou popředí, nebo pozadí), které nastavíme na nekonečno (nebo velkou konstantu), čímž zabráníme výběr do minimálního řezu
|
||||
- **n-linky (mezi sousedními pixely)** - podle Riemannovy metriky
|
||||
|
||||
### Chan-Vese pomocí minimálního řezu
|
||||
|
||||
Můžeme rozdělit obrázek na dvě části, přičemž o některých pixelech víme, jestli patří do popředí, nebo do pozadí. Podobně, jako u Chan-Vese křivkami máme odhad $c_1, c_2$ pro popředí a pozadí. Nastavme tedy váhy:
|
||||
|
||||
- **t-linky** - $w_{si} = \lambda_2(f(i) - c_2)^2 \text{, } w_{it} = \lambda_1(f(i) - c_1)^2$
|
||||
- **n-linky** - podle Riemannovy metriky
|
||||
|
||||
Bohužel $w_{si}, w_{it}$ jsou závislé na $c_1, c_2$. Typicky řešíme tak, že si tipneme, provedeme iteraci, aktualizujeme a jedem znovu
|
||||
|
||||
## Variační optický tok
|
||||
|
||||
Pro sekvenci obrázků $f(x,y,t)$ chceme získat vektor posunutí $(u(x,y,t),v(x,y,t))^T$ každého místa obrázku.
|
||||
|
||||
Máme **_2 předpoklady_**, které platí pro všechny metody:
|
||||
|
||||
- Zachování jasu (mezi snímky se nám nemění jas obrázku) = **_BCA_** - $f(x+u, y+v, t+1)=f(x,y,t)$ (posunutý pixel se rovná neposunutému)
|
||||
- Malé změny (objekty se posouvají jen o několik málo (třeba 5) pixelů) - Abychom mohli provést linearizaci Taylorovým rozvojem
|
||||
|
||||
Z rovnice pro BCA můžeme linearizací dostat
|
||||
|
||||
```math
|
||||
0 = f(x+u, y+v, t+1) - f(x,y,t) \\
|
||||
\approx f_x(x,y,t)u + f_y(x,y,t)v + f_t(x,y,t)
|
||||
```
|
||||
|
||||
Tím dostáváme nejdůležitější rovnici **linearised optical flow constraint (OFC)
|
||||
$f_x u+f_y v + f_t = 0$ ($\nabla f \cdot (u,v) + f_t = 0$)**
|
||||
|
||||
Problém Apertury = OFC ukazuje jen tok rovnoběžný s gradientem (protože jinak to není vidět)
|
||||
|
||||

|
||||
|
||||
Taky protože $f_x u+f_y v + f_t = 0 \sim \nabla f \cdot (u,v) + f_t = 0$ , tedy máme projekci reálného směru na gradient\
|
||||
-> Nonuniqueness = Můžeme libovolně přidat část toku kolmou na gradient, aniž bychom změnili výsledek
|
||||
|
||||
### Lukas a Kanade (Lokální metoda)
|
||||
|
||||
Přidává 3. předpoklad:
|
||||
|
||||
- Zachování jasu
|
||||
- Malé změny
|
||||
- **Konstantnost toku v okolí $B_\rho$ každého bodu**
|
||||
|
||||
Chceme minimalizovat následující lokální energii (integrál přes okolí)
|
||||
|
||||
```math
|
||||
E(u,v) = \frac{1}{2} \int_{B_\rho(x_0, y_0)} (f_x u + f_y v + f_t)^2 dx dy
|
||||
```
|
||||
|
||||
Parciálně zderivujeme a převedeme na matice
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
0 = \frac{\partial E}{\partial u} &= \int_{B_\rho} f_x(f_x u + f_y v + f_t) dx dy = 0 \\
|
||||
0 = \frac{\partial E}{\partial v} &= \int_{B_\rho} f_y(f_x u + f_y v + f_t) dx dy = 0
|
||||
\end{aligned}
|
||||
\\
|
||||
\begin{pmatrix}
|
||||
\int_{B_\rho} f_x^2 dxdy & \int_{B_\rho} f_x f_y dxdy \\
|
||||
\int_{B_\rho} f_x f_y dxdy & \int_{B_\rho} f_y^2 dxdy
|
||||
\end{pmatrix}
|
||||
\begin{pmatrix}
|
||||
u \\
|
||||
v
|
||||
\end{pmatrix}
|
||||
=
|
||||
\begin{pmatrix}
|
||||
-\int_{B_\rho} f_x f_t dxdy \\
|
||||
-\int_{B_\rho} f_y f_t dxdy
|
||||
\end{pmatrix}
|
||||
```
|
||||
|
||||
Můžeme nahradit integrály za Gaussovské rozmazání, čímž dostaneme "plynulejší okolí"
|
||||
|
||||
```math
|
||||
\begin{pmatrix}
|
||||
G_{\sigma} * (f_x^2) & G_{\sigma} * (f_x f_y) \\
|
||||
G_{\sigma} * (f_x f_y) & G_{\sigma} * (f_y^2)
|
||||
\end{pmatrix}
|
||||
\begin{pmatrix}
|
||||
u \\
|
||||
v
|
||||
\end{pmatrix}
|
||||
=
|
||||
\begin{pmatrix}
|
||||
-G_{\sigma} * (f_x f_t) \\
|
||||
-G_{\sigma} * (f_y f_t)
|
||||
\end{pmatrix}
|
||||
```
|
||||
|
||||
Snadno vyřešíme Cramerovým pravidlem
|
||||
|
||||
Výhody
|
||||
|
||||
- Jednoduché, rychlé
|
||||
- Stačí nám 2 snímky
|
||||
|
||||
Nevýhody
|
||||
|
||||
- Problémové situace, kde neplatí podmínka konstantnosti - rotace, protijedoucí auta, …
|
||||
- Nepočítá husté pole toků (jen tam, kde víme gradient)
|
||||
|
||||
### Horn-Schunck (Globální metoda)
|
||||
|
||||
Pouze dva přepoklady:
|
||||
|
||||
- Zachování jasu - $f_x u+f_y v + f_t = 0$
|
||||
- Malé změny (Gradient vektorového pole je malý) - $\int_{\Omega} ( \lvert \nabla u \rvert^2 + \lvert \nabla v \rvert^2) dx dy$ je malé
|
||||
|
||||
Kombinací dostáváme funkcionál energie optického toku
|
||||
|
||||
```math
|
||||
E_{HS}(u, v) = \int_{\Omega} ((f_x u + f_y v + f_t)^2 + \alpha (\lvert \nabla u \rvert^2 + \lvert \nabla v \rvert^2)) dx dy
|
||||
```
|
||||
|
||||
Tento funkcionál minimalizujeme na jediné globální řešení
|
||||
|
||||
Výhody
|
||||
|
||||
- Jsme schopni řídit smoothness pomocí $\alpha$
|
||||
- Produkuje dense flow fields
|
||||
|
||||
Nevýhody
|
||||
|
||||
- Stále musíme splňovat předpoklad malých změn
|
||||
- Celkem pomalé a drahé
|
194
src/content/docs/szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md
Normal file
194
src/content/docs/szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md
Normal file
@ -0,0 +1,194 @@
|
||||
---
|
||||
title: "Zpracování obrazu pomocí PDE"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Difúzní filtrování (lineární difuze, nelineární izotropní a nelineární anizotropní difuze). Level set metody (pohyb ve směru normály, pohyb řízený křivostí a pohyb ve vnějším vektorovém poli). Fast marching algoritmus.
|
||||
|
||||
_PA166_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
- **Divergence**\
|
||||
Operace, která nám říká, jak moc vektorové pole míří ven z daného bodu. Pokud je $\text{div} j > 0$, pak se v daném bodě hodnota časem snižuje, pokud je $\text{div} j < 0$, pak se hodnota zvyšuje.
|
||||
|
||||
$\text{div} j = \nabla^T j = (\partial_x, \partial_y) \cdot (j_1, j_2) = \partial_x j_1 + \partial_y j_2$.
|
||||
|
||||
- **Laplacian $\Delta$**\
|
||||
Jak se mění teplota v daném místě s časem, proto to odpovídá derivaci teploty podle času.
|
||||
|
||||
Laplacian je vlastně divergence gradientu: $\Delta u = \text{div}(\nabla f) = (\partial_x, \partial_y) \cdot (\partial_x u, \partial_y u) = \partial_{xx} u + \partial_{yy} u = u_{xx} + u_{yy}$.
|
||||
|
||||
## Difuze
|
||||
|
||||
Imituje šíření tepla v 1D tyči / 2D ploše / ... Řídí se také rovnicí pro šíření tepla: $u_t = \Delta u = u_{xx} + u_{yy}$ (kde $\Delta$ je Laplaceův operátor).
|
||||
|
||||
- Teplo se v takové ploše může šířit různými způsoby v závislosti na vlastnostech materiálu. Je možné že:
|
||||
|
||||
1. Celý materiál ve všech směrech vede teplo stejně = **lineární difuze (LD)**.
|
||||
2. Materiál vede v různých místech teplo různě, ale vždy ve všech směrech stejně = **nelineární izotropní difuze (NID)**.
|
||||
3. Materiál vede teplo různě v různých směrech = **nelineární anizotropní difuze (NAD)**.
|
||||
|
||||

|
||||
|
||||
### Lineární difuze
|
||||
|
||||
Pokud aplikujeme lineární difuzi na obrázek, dojde k jeho rozmazání (Gaussovský filtr).
|
||||
|
||||
Pokud vezmeme prostor všech různých Gaussovských rozmazání v různých časem, dostáváme "Gaussovský prostor měřítek" (_Gaussian scale space_). Pro ten platí
|
||||
|
||||
- **_Zachování průměrné hodnoty šedé_**
|
||||
- **_Princip maxima a minima_** - se zvyšujícím se t se maximum jedině snižuje a minimum jedině zvyšuje
|
||||
- **_Řešení je nezávislé na_**
|
||||
- **_Posuvu hodnoty šedé_** - “posun po ose Y”
|
||||
- **_Translaci_** - “posun po ose X”
|
||||
- **_Škálování_**
|
||||
- **_Vlastnost porovnání_** - pokud $u \leq v \rightarrow (T_tu) \leq (T_tv)$
|
||||
- Pro dimenze $\geq 2$ mohou vznikat nové extrémy
|
||||
|
||||
Chceme vypočítat $u_{ij}^{k + 1}$ pomocí aproximace Taylorova rozvoje:
|
||||
|
||||
```math
|
||||
u_t = \frac{u_{ij}^{k + 1} - u_{ij}^k}{\Delta t} + O(\Delta t)\\
|
||||
u_{xx} = u_{i + 1, j}^k - 2u_{ij}^k + u_{i - 1, j}^k + O(\Delta x^2)\\
|
||||
u_{yy} = u_{i, j + 1}^k - 2u_{ij}^k + u_{i, j - 1}^k + O(\Delta y^2)
|
||||
```
|
||||
|
||||
A z této rovnice už vyjádříme $u_{ij}^{k + 1}$. ($\Delta t$ je časový krok, $\Delta x$ a $\Delta y$ jsou prostorové kroky)
|
||||
|
||||
### Nelineární izotropní difuze
|
||||
|
||||
Zobecníme funkci pro difuzi kombinací Fick’s law a Mass preservation: $\partial_t u = \text{div} (g \cdot \nabla u)$, kde $\div$ je divergence.
|
||||
|
||||
- **Lineární**
|
||||
- $g = 1$
|
||||
- Rozmazání ve všech bodech stejně ve všech směrech
|
||||
- **Nelineární izotropní**
|
||||
- $g =$ skalární funkce
|
||||
- Rozmazání stejně ve všech směrech, ale v každém bodě jinak
|
||||
- **Nelineární anizotropní**
|
||||
- $g =$ maticová funkce
|
||||
- Rozmazání v každém bodě a směru jinak
|
||||
|
||||
Pro NID chceme typicky zabránit rozmazání na výrazných hranách. Chceme tedy, aby fce $g$ byla na hranách (tam, kde je velký gradient) co nejmenší a jinde co největší. Existuje několik různých vzorců:
|
||||
|
||||
- **Perona-Malik difuzivita**\
|
||||
$g(\nabla u) = \frac{1}{1 + |\nabla u|^2 / \lambda^2}$.
|
||||
- **Charbonnier difuzivita**\
|
||||
$g(\nabla u) = \frac{1}{\sqrt{1 + |\nabla u|^2 / \lambda^2}}$.
|
||||
- **Exponenciální difuzivita**\
|
||||
$g(\nabla u) = e^\frac{-|\nabla u|^2}{2\lambda^2}$.
|
||||
|
||||
### Nelineární anizotropní difuze
|
||||
|
||||
NID nechával "chlupaté hrany", protože kolem hran nerozmazával vůbec. NAD dokáže kolem hran rozmazat jen v tom správném směru, neboť $g$ je v tomto případě matice.
|
||||
|
||||
- **Symetrická matice**\
|
||||
Reprezentuje otočení, roztažení a otočení zpátky:
|
||||
|
||||
```math
|
||||
A=
|
||||
\begin{pmatrix}
|
||||
u_1 & v_1\\
|
||||
u_2 & v_2
|
||||
\end{pmatrix}
|
||||
\begin{pmatrix}
|
||||
\lambda_1 & 0\\
|
||||
0 & \lambda_2
|
||||
\end{pmatrix}
|
||||
\begin{pmatrix}
|
||||
u_1 & u_2\\
|
||||
v_1 & v_2
|
||||
\end{pmatrix}
|
||||
```
|
||||
|
||||
- Vlastní vektory kolmé na sebe
|
||||
- Vlastní čísla jsou reálná
|
||||
|
||||

|
||||
|
||||
Díky symetrickým maticím můžeme sestavit sami maticky s předem danými vlastními vektory a čísly.
|
||||
|
||||
- **Edge-enhancing difuzivita (difuzivita zvýrazňující hrany)**\
|
||||
My chceme matici, co má následující vlastnosti:
|
||||
|
||||
```math
|
||||
v_1 \parallel \nabla u_\sigma, \lambda_1 = g(|\nabla u_\sigma|^2) \\
|
||||
v_2 \perp \nabla u_\sigma, \lambda_2 = 1
|
||||
```
|
||||
|
||||
Kde funkce $g$ je funkce nepřímé úměry. Tím zajistíme, že rozmazání podél hran bude maximální a v ostatních směrech bude minimální.
|
||||
|
||||
- **Coherence-enhancing difuzivita (difuzivita zvýrazňující koherenci)**\
|
||||
Potřebujeme vypočítat difuzní tenzor a podle něj potom aplikujeme rozmazání. Tenzor je dán jako:
|
||||
|
||||
```math
|
||||
D = \nabla u_\sigma \nabla u_\sigma^T
|
||||
```
|
||||
|
||||
My opět vytvoříme matici s vlastními vektory a čísly. Tentokrát vektory vezmeme z tensoru: Vlastní vektor tensoru s větším vl. číslem vede přes strukturu -> Dáme mu malé číslo blízko nuly; vlastní vektor s menším vl. číslem vede kolmo -> Dáme mu číslo podle rozdílu koherence (pokud je koherentní, nechceme rozmazávat tolik, může to být roh).
|
||||
|
||||

|
||||
|
||||
## Level set metody
|
||||
|
||||
Level set metody využívají implicitní reprezentace křivek.
|
||||
|
||||
- **Implicitní reprezentace**\
|
||||
Představme si funkci, která má uvnitř křivky záporné hodnoty, na křivce nulu a venku kladné hodnoty. Potom můžeme křivku reprezentovat, jako (nulovou) vrstevnici funkce.
|
||||
|
||||
Při takovéto reprezentaci nemáme přístup přímo k hranici, ale můžeme jí získat například pomocí marching squares (cubes) algoritmu. Zároveň musíme mít uloženou hodnotu funkce pro celý obraz, což může být nevýhoda. Výhodou je, že můžeme snadno měnit topologii křivky (přidávat díry, spojovat křivky, ...).
|
||||
|
||||
Toto všechno funguje i ve 3D, kde se ale bavíme o povrchu.
|
||||
|
||||
Vývoj křivky můžeme definovat, jako $\frac{\partial C}{\partial t} = \beta n$ (kde $n$ je normála a $\beta$ řídí rychlost evoluce). Pokud ho chceme definovat v rámci obalující funkce $u$, můžeme ho zapsat, jako $\partial_t u = \beta |\nabla u|$. $\beta$ v této rovnici ovlivňuje směr a rychlost pohybu křivky, $|\nabla u|$ je velikost gradientu.
|
||||
|
||||
**Level set metody se snaží řešit tuto rovnici**.
|
||||
|
||||
- **Typy pohybu**\
|
||||
Existují 3 základní typy pohybu křivky:
|
||||
|
||||
- **_Pohyb ve směru normály_** - $\beta = a$ = dilatace / eroze
|
||||
- **_Pohyb řízený křivostí_** - $\beta = - \epsilon \kappa$ = vyhlazování křivky
|
||||
- **_Pohyb ve vnějším vektorovém poli_** - $\beta = V(x, y, t) \cdot n$, kde $V$ je vnější vektorové pole
|
||||
|
||||

|
||||
|
||||
- **Pohyb ve vnějším vektorovém poli**\
|
||||
$\beta = V(x, y, t) \cdot n$ popisuje pohyb ve vektorovém poli definovaném parametrem $V$. Aproximujeme opět pomocí Taylorova rozvoje.
|
||||
- **Pohyb řízený křivostí**\
|
||||
Chceme, aby se křivka vyhlazovala, protože křivost je vlastně druhá derivace. $\beta = - \epsilon \kappa$ popisuje pohyb křivky ve směru opačném k její křivosti. $\kappa$ je křivost a $\epsilon$ je parametr, který řídí rychlost vyhlazování.
|
||||
- **Pohyb ve směru normály**\
|
||||
Chceme, aby se křivka rozšiřovala, nebo smršťovala. $\beta = a$ popisuje pohyb křivky ve směru normály. $a$ je parametr, který řídí rychlost pohybu.
|
||||
|
||||
Všechny typy pohybu můžeme zapsat do jedné rovnice: $u_t = -V \cdot \nabla u - a |\nabla u| + \epsilon \kappa |\nabla u|$ a aproximovat pomocí Taylorova rozvoje.
|
||||
|
||||
### Fast marching algoritmus
|
||||
|
||||
FMA je specifický případ Level set metody s pouze jedním typem pohybu ve směru normály $\partial_t u = a |\nabla u|$.
|
||||
|
||||
Pro různé případy můžeme volit různé hodnoty $a$.
|
||||
|
||||
- **Euklidovská vzdálenost**\
|
||||
Pro výpočet vzdálenosti od křivky ke všem bodům obrazu zvolíme $a = 1$.
|
||||
- **Geodesická vzdálenost**\
|
||||
Chceme-li změřit vzdálenost od daného bodu uvnitř objektu, zvolíme $a = 1$ uvnitř objektu a $a \rightarrow 0$ venku.
|
||||
|
||||

|
||||
|
||||
- **Segmentace**\
|
||||
Můžeme jednoduše segmentovat obraz, pokud zvolíme $a = g(|\nabla f|)$ (kde $f$ je obraz a $g$ je nějaká funkce, například Perona-Malik). Potom $g$ jde k 0 při vysokém gradientu a k 1 při nízkém gradientu.
|
||||
|
||||
Samotný výpočet algoritmu je trošku složitější, uděláme si 3 množiny
|
||||
|
||||
- Trial (co chceme testovat, init. kontura)
|
||||
- Far (neobjevené, init. všechno krom kontury)
|
||||
- Known (vyřešené, init. prázdná množina)
|
||||
|
||||
Vždy najdeme v Trial nejmenší hodnotu, přehodíme ji do Known a pro její sousedy vypočítáme nový arrival time minimalizací $T_{new} = \tau(v_1, v_2) + v_1 T_1 + v_2 T_2$, kde $\tau$ je časový krok, $T_1, T_2$ jsou hodnoty v Known a $v_1, v_2$ jsou souřadnice bodu X, které chceme minimalizovat ($v_1 + v_2 = 1, v_1, v_2 \geq 0$).
|
||||
|
||||
Konkrétní výpočet je ve slidech, nebo v [notionu](https://xrosecky.notion.site/PA166-Image-analysis-II-b2875a07366c404dabbf20a8b75a6e2e?pvs=74), ale myslím, že je celkem zbytečný.
|
||||
|
||||
Složitost je v řádu $O(n \log n)$, kde $n$ je počet pixelů v obrazu.
|
35
src/content/docs/szmgr/PGV_zpracovani_obrazu_intro.md
Normal file
35
src/content/docs/szmgr/PGV_zpracovani_obrazu_intro.md
Normal file
@ -0,0 +1,35 @@
|
||||
---
|
||||
title: Zpracování obrazu - intro
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>💡 TIP</strong></dt><dd>
|
||||
|
||||
Doporučuju kouknout na shrnutí v [zápiscích z předmětu PA166 od xrosecky](https://xrosecky.notion.site/PA166-Image-analysis-II-b2875a07366c404dabbf20a8b75a6e2e?pvs=74)
|
||||
</dd></dl>
|
||||
|
||||
* **Gradient $\nabla$**\
|
||||
Vektorové pole ve směru největšího nárůstu.
|
||||
|
||||
Standardně ho spočítáme jako derivaci obrazu podle x a y. V praxi ale používáme aproximaci derivace podle Taylorova rozvoje.
|
||||
* **Aproximace derivace**\
|
||||
Taylorův polynom vypadá takto: $f(x + h) = f(x) + hf'(x) + \frac{h^2}{2!}f''(x) + \dots + \frac{h^n}{n!}f^{(n)}(x) + O(h^{n+1})$.
|
||||
|
||||
Z něho můžeme odvodit rovnici pro první derivaci (v našem případě ji nazýváme dopředná diference):
|
||||
|
||||
```math
|
||||
f(x + h) \approx f(x) + hf'(x)\\
|
||||
f'(x) \approx \frac{f(x + h) - f(x)}{h}
|
||||
```
|
||||
|
||||
Tu můžeme dále zpřesnit, pokud si vypíšeme taylorův rozvoj až do druhé derivace včetně (tím získáme centrální diferenci):
|
||||
|
||||
```math
|
||||
h_1 = 1, h_2 = -1\\
|
||||
f(x + h_1) - f(x + h_2) \\
|
||||
f(x + 1) - f(x - 1) \approx f(x) + hf'(x) + \frac{h^2}{2!}f''(x) - f(x) + hf'(x) - \frac{h^2}{2!}f''(x)\\
|
||||
f(x + 1) - f(x - 1) \approx 2hf'(x) \\
|
||||
f'(x) \approx \frac{f(x + 1) - f(x - 1)}{2h}
|
||||
```
|
||||
|
||||
Podobným stylem získáme i druhou derivaci
|
692
src/content/docs/szmgr/SZP01_algoritmy.md
Normal file
692
src/content/docs/szmgr/SZP01_algoritmy.md
Normal file
@ -0,0 +1,692 @@
|
||||
---
|
||||
title: "Algoritmy a datové struktury"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Pokročilé techniky návrhu algoritmů: dynamické programování, hladové strategie, backtracking. Amortizovaná analýza. Vyhledávání řetězců: naivní algoritmus pro hledání řetězců, Karp-Rabinův algoritmus, hledání řetězců pomocí konečných automatů. Algoritmus Knuth-Morris-Pratt.
|
||||
|
||||
_IV003_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
## Pokročilé techniky návrhu algoritmů
|
||||
|
||||
### Dynamické programování
|
||||
|
||||
> I thought dynamic programming was a good name. It was something not even a Congressman could object to. So I used it as an umbrella for my activities.
|
||||
>
|
||||
> — Richard Bellman
|
||||
|
||||
Intutivně je _dynamické programování_ spojením dvou věcí: "rozbalené" rekurze (taky se tomu říká _bottom-up přístup_) a _memoizace_.
|
||||
|
||||
- Je použitelné na problémy, které lze rozdělit na podproblémy.
|
||||
- Obzvlášť vhodné je pak v těch případech, kde se podproblémy překrývají -- dochází k tomu, že se něco počítá víckrát.
|
||||
|
||||
Konkrétněji, dynamické programování je vhodnou technikou, pokud:
|
||||
|
||||
- podproblémů je polynomiální počet,
|
||||
- (optimální) řešení původního problému lze jednoduše spočítat z (optimálních) řešení jeho podproblémů,
|
||||
- podproblémy jde přirozeně seřadit od _nejmenšího_ po _největší_.
|
||||
|
||||
<dl><dt><strong>💡 TIP</strong></dt><dd>
|
||||
|
||||
O tom, že problémů musí být polynomiální počet, přemýšlím intuitivně tak, že se musí dát vyřešit v nějakém vícenásobném `for`-cyklu a uložit do multi-dimenzionálního pole.
|
||||
|
||||
Pokud mám $l$ zanořených cyklů, vyřeším nejvíc $n^l$ podproblémů.
|
||||
|
||||
</dd></dl>
|
||||
|
||||
#### Memoizace
|
||||
|
||||
_Memoizace_ v zásadě není nic jiného než tabulka, pole, `HashSet`, nebo něco podobného, kam si algoritmus ukládá řešení jednotlivých podproblémů.
|
||||
|
||||
**💡 TIP**\
|
||||
V pseudokódu se označuje jako $M$ (asi memory), $A$ (asi array), nebo $C$ (asi cache).
|
||||
|
||||
#### Bottom-up
|
||||
|
||||
Rekurze tradičně řeší problém _zeshora_ -- začně celým problémem, který si rozdělí na podproblémy, a ty na podpodproblémy, atd. Bottom-up approach jde na to obráceně. Začně těmi nejmenšími podproblémy a postupně se prokousává k rešení celku.
|
||||
|
||||
Jediným háček je v tom přijít na to, které podproblémy jsou ty nejmenší a v jakém pořádí je musíme spočítat, aby byly všechny připravené pro výpočet větších podproblémů. Bez tohohle algoritmus nebude fungovat korektně.
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Zjednodušeně jde o to přetransformovat rekurzi na cykly. Pěkný vedlejším efektem je, že je jednodušší určit složitost algoritmu.
|
||||
|
||||
</dd></dl>
|
||||
|
||||
#### Kuchařka
|
||||
|
||||
1. Rozděl problém na (překrývající se) podproblémy.
|
||||
2. Napiš rekurzivní algoritmus nebo alespoň Bellmanův rekurentní vztah (značený $\text{OPT}$ protože dává _optimální_ řešení).
|
||||
3. Urči správné pořadí počítání podproblémů tak, aby se každý počítal právě jednou (bottom-up přístup).
|
||||
4. Pokud je to nutné, sestav z optimální hodnoty její realizaci (třeba cestu nebo něco).
|
||||
5. Sepiš pseudokód.
|
||||
6. Dokaž korektnost rekurentního vztahu, bottom-up pořadí a rekonstrukce (zejména terminace).
|
||||
7. Okomentuj složitost.
|
||||
|
||||
#### Problémy
|
||||
|
||||
- **Weighted interval scheduling**\
|
||||
Z množiny $n$ intervalů (událostí, úkolů, atd.), které se mohou překrývat v čase, a mají určitou váhu $w_i$, vyber takovou množinu intervalů $S$, pro kterou je $\sum_{i \in S} w_s$ maximální.
|
||||
|
||||
- **Řešení**
|
||||
|
||||
Řešení využívá toho, že čas plyne výhradně dopředu, takže se můžeme na podproblémy dívat chronologicky a nebudou se překrývat.
|
||||
|
||||
Nechť $p(j)$ je index takové události $i < j$, že $i$ a $j$ jsou kompatibilní.
|
||||
|
||||
```math
|
||||
\text{OPT}(j) = \begin{cases}
|
||||
|
||||
0 & \text{pokud } j = 0 \\
|
||||
\max \{ \text{OPT}(j-1), w_j + \text{OPT}(p(j)) \} & \text{pokud } j > 0
|
||||
|
||||
\end{cases}
|
||||
```
|
||||
|
||||
- **Parenthesization**\
|
||||
Mějme hromadu matic, které chceme pronásobit. Víme, že maticové násobení je asociativní, takže můžeme zvolit různé pořadí násobení -- různé odzávorkování. Nicméně, není komutativní, takže nesmíme matice prohazovat. Cena násobení matice o velikosti $i \times j$ a $j \times k$ je $i \cdot j \cdot k$. Jaké pořadí zvolit, aby byl výsledný součin co nejlevnější?
|
||||
|
||||
- **Problém**
|
||||
|
||||
Máme matice $A_1, A_2, ..., A_n$, které chceme pronásobit.
|
||||
|
||||
Potřebujeme najít index $k$ takový, že $\textcolor{red}{(A_1 \cdot ... \cdot A_k)} \cdot \textcolor{blue}{(A_{k+1} \cdot ... \cdot A_n)}$ je nefektivnější. To nám problém rozděluje na dva podproblémy: červený a modrý.
|
||||
|
||||
- **Řešení**
|
||||
|
||||
```math
|
||||
\text{OPT}(i, j) = \begin{cases}
|
||||
|
||||
0 & \text{pokud } i = j \\
|
||||
\min_{i \leq k < j} \{ \text{OPT}(i, k) + \text{OPT}(k+1, j) + p_{i-1} \cdot p_k \cdot p_j \} & \text{pokud } i < j
|
||||
|
||||
\end{cases}
|
||||
```
|
||||
|
||||
- **Knapsack**\
|
||||
Mějme batoh s nosností $W$ a $n$ věcí, které bychom do něj rádi naložili. Každá věc $i$ má hodnotu $v_i$ a váhu $w_i$. Jaké věci vybrat, aby byla hodnota naložených věcí co největší, ale batoh je furt unesl?
|
||||
|
||||
- **Řešení**
|
||||
|
||||
Vychází z myšlenky, že batoh, ve kterém už něco je, je _jakoby_ batoh s nižší nosností.
|
||||
|
||||
Procházíme věci postupně přes index $i$ a pro každou řešíme, jestli ji chceme v batohu o nosnosti $w$:
|
||||
|
||||
```math
|
||||
\text{OPT}(i, w) = \begin{cases}
|
||||
|
||||
0 & \text{pokud } i = 0 \\
|
||||
\text{OPT}(i - 1, w) & \text{pokud } w_i > w \\
|
||||
\max \{ \text{OPT}(i - 1, w), v_i + \text{OPT}(i - 1, w - w_i) \} & \text{pokud } w_i \leq w
|
||||
|
||||
\end{cases}
|
||||
```
|
||||
|
||||
### Hladové (greedy) strategie
|
||||
|
||||
> Přijde Honza na pracovní pohovor a budoucí šéf se ho ptá: "Co je vaše dobrá schopnost?"
|
||||
> Honza odpoví: "Umím rychle počítat."
|
||||
> "Kolik je 1024 na druhou?"
|
||||
> "MILION STO TISÍC," vyhrkne ze sebe Honza.
|
||||
> Šéf se chvíli zamyslí a povídá: "Ale to je špatně, výsledek je 1048576!"
|
||||
> A Honza na to: "No sice špatně, ale sakra rychle!"
|
||||
|
||||
Greedy algoritmy nachází řešení globálního problému tak, že volí lokálně optimální řešení. Tahle taktika nemusí vést ke globálně optimálnímu řešení, ale alespoň ho spočítá rychle.
|
||||
|
||||
- Ve výpočtu směřuje bottom-up.
|
||||
- Ideálně funguje na problémy, kde optimální řešení podproblému je součástí optimálního řešení celého problému.
|
||||
- Dobře se navrhuje, špatně dokazuje.
|
||||
|
||||
#### Problémy
|
||||
|
||||
- **Cashier’s algorithm (mince)**\
|
||||
Jak zaplatit danou částku s co nejmenším počtem mincí různých hodnot?
|
||||
|
||||
- **Řešení**\
|
||||
V každé iteraci vol minci s nejvyšší hodnotou, dokud není zaplacena celá částka.
|
||||
|
||||
- **Interval scheduling**\
|
||||
Z množiny intervalů, které mají začátek a konec, **ale mají stejnou hodnotu**, vyber největší podmnožinu intervalů, které se nepřekrývají.
|
||||
|
||||
- **Řešení**\
|
||||
Vybereme ty, které končí nejdřív.
|
||||
|
||||
### Backtracking
|
||||
|
||||
_Inteligentní brute-force nad prostorem řešení._
|
||||
|
||||
Technika hledání řešení problému postupným sestavováním _kandidátního_ řešení. [backtracking](#backtracking)
|
||||
|
||||
- Částečný kandidát může být zavrhnut, pokud nemůže být dokončen.
|
||||
- Můžeme dokonce zavrhnout kompletní řešení, pokud je chceme najít všechna.
|
||||
- Pokud je kandidát zavrhnut, algoritmus se vrátí o kus zpět (backtrackuje), upraví parametry a zkusí to znovu.
|
||||
|
||||
**Porovnání s dynamickým programováním**
|
||||
|
||||
| Dynamické programování |
|
||||
| ------------------------------------------------------------ |
|
||||
| Backtracking |
|
||||
| Hledá řešení _překrývajících se podproblémů_. |
|
||||
| Hledá _všechna_ řešení. |
|
||||
| Hledá _optimální_ řešení. |
|
||||
| Hledá všechna, _libovolná_ řešení, _hrubou silou_. |
|
||||
| Má blíž k BFS -- staví "vrstvy". |
|
||||
| Má blíž k DFS -- zanoří se do jednoho řešení a pak se vrátí. |
|
||||
| Typicky zabírá víc paměti kvůli memoizaci. |
|
||||
| Typicky trvá déle, protože hledá _všechna_ řešení. |
|
||||
| Mívá cykly. |
|
||||
| Mívá rekurzi. |
|
||||
|
||||
#### Problémy
|
||||
|
||||
- **Sudoku**\
|
||||
Hledá řešení tak, že pro pole vybere možné řešení a zanoří se, pokud funguje tak _hurá_, pokud ne, tak backtrackuje a zkusí jinou možnou cifru.
|
||||
- **Eight queens**\
|
||||
Jak rozestavit osm šachových královen na šachovnic tak, aby se vzájemně neohrožovaly?
|
||||
|
||||
## Amortizovaná analýza
|
||||
|
||||
> - **_amortize(v)_**
|
||||
> - _amortisen_ -- "to alienate lands", "to deaden, destroy"
|
||||
> - _amortir_ (Old French) -- "deaden, kill, destroy; give up by right"
|
||||
> - _\*admortire_ (Vulgar Latin) -- to extinquish
|
||||
>
|
||||
> — Online Etymology Dictionary
|
||||
|
||||
Umožňuje přesnější analýzu časové a prostorové složitosti, protože uvažujeme kontext, ve které se analyzovaný algoritmus používá. Určujeme složitost operace v **posloupnosti operací**, **ne samostatně**.
|
||||
|
||||
**Připomenutí**
|
||||
|
||||
**💡 TIP**\
|
||||
Viz bakalářská otázka [Korektnost a složitost algoritmu](../../szb/korektnost-a-slozitost-algoritmu/).
|
||||
|
||||
Základními pojmy analýzy složitosti jsou:
|
||||
|
||||
- **Časová složitost**\
|
||||
Funkce velikosti vstupu $n$ algoritmu. Počítá počet _kroků_ (nějaké výpočetní jednotky) potřebných k vyřešení problému.
|
||||
- **Prostorová složitost**\
|
||||
Funkce velikosti vstup $n$ algoritmu. Počítá počet _polí_ (nějaké jednotky prostoru), která algoritmus potřebuje navštívit k vyřešení problému.
|
||||
- **Asymptotická notace**\
|
||||
Umožňuje zanedbat hardwarové rozdíly. Popisuje, že složitost roste _alespoň tak_, _nejvýš tak_ nebo _stejně_ jako jiná funkce.
|
||||
- **Big O**\
|
||||
Horní mez, složitost v nejhorším případě. Množina funkcí rostoucích stejně rychle jako $g$, nebo **pomaleji**:
|
||||
|
||||
```math
|
||||
\mathcal{O}(g(n)) = \{f : (\exists c, n_0 \in \mathbb{N}^+)(\forall n \geq n_0)(f(n) \le c \cdot g(n)) \}
|
||||
```
|
||||
|
||||
- **Omega**\
|
||||
Spodní mez, složitost v nejlepším případě. Množina funkcí rostoucích stejně rychle jako $g$, nebo **rychleji**.
|
||||
|
||||
```math
|
||||
\Omega(g) = \{f : (\exists c, n_0 \in \mathbb{N}^+)(\forall n \geq n_0)(f(n) \ge c \cdot g(n)) \}
|
||||
```
|
||||
|
||||
- **Theta**\
|
||||
Horní i spodní mez. Množina funkcí rostoucích stejně rychle jako $g$.
|
||||
|
||||
```math
|
||||
\Theta(g) = \mathcal{O}(g) \cap \Omega(g)
|
||||
```
|
||||
|
||||
### Aggregate method (brute force)
|
||||
|
||||
Analyzujeme celou sekvenci operací najednou. Nepoužíváme žádné chytristiky ani fígle.
|
||||
|
||||
**Zásobník (brute force)**
|
||||
|
||||
- **Věta**\
|
||||
Pokud začneme s prázdným zásobníkem, pak libovolná posloupnost $n$ operací `Push`, `Pop` a `Multi-Pop` zabere $\mathcal{O}(n)$ času.
|
||||
- **Důkaz**
|
||||
- Každý prvek je `Pop`nut nejvýše jednou pro každý jeho `Push`.
|
||||
- V posloupnosti je $\le n$ `Push`ů.
|
||||
- V posloupnosti je $\le n$ `Pop`ů (včetně těch v `Multi-Pop`u).
|
||||
- Celá posloupnost má tak nejvýše složitost $2n$.
|
||||
|
||||
### Accounting method (banker's method)
|
||||
|
||||
Používá fígl, kdy velké množství _levných_ operací "předplatí" jednu _drahou_ operaci. Využívá metaforu bankovního účtu.
|
||||
|
||||
- Každé operaci přiřadíme fiktivní _kreditovou_ cenu.
|
||||
- Při realizaci operace zaplatíme _skutečnou_ cenu naspořenými kredity.
|
||||
- Počáteční stav je 0 kreditů.
|
||||
|
||||
Pro každou operaci v posloupnosti:
|
||||
|
||||
- Pokud je _skutečná_ cena nižší než _kreditová_, tak zaplatíme skutečnou cenu a přebývající kredity uspoříme na _účtu_.
|
||||
- Pokud je _skutečná_ cena vyšší než _kreditová_, tak zaplatíme skutečnou cenu a případný nedostatek kreditů doplatíme z úspor na _účtu_.
|
||||
|
||||
**❗ IMPORTANT**\
|
||||
Pokud je po celou dobu provádění operací stav účtu **nezáporný**, pak je _skutečná_ složitost celé posloupnosti operací menší nebo rovna součtu _kreditových_ cen operací.
|
||||
|
||||
**⚠️ WARNING**\
|
||||
Pokud stav účtu **kdykoliv během posloupnosti** klesne pod nulu, pak jsou kreditové ceny nastaveny **špatně**!
|
||||
|
||||
**💡 TIP**\
|
||||
Tato metoda se dá upravit tak, že kredity náleží individuálním objektům ve struktuře místo struktury jako celku. Cena operace se pak platí z kreditů objektů, nad kterým operace probíhá.
|
||||
|
||||
**Zásobník (kredity)**
|
||||
|
||||
| Operace |
|
||||
| --------------- |
|
||||
| Skutečná cena |
|
||||
| Kreditová cena |
|
||||
| `Push` |
|
||||
| 1 |
|
||||
| 2 |
|
||||
| `Pop` |
|
||||
| 1 |
|
||||
| 0 |
|
||||
| `Multi-Pop` |
|
||||
| stem:[\min(k,\ |
|
||||
| S\ |
|
||||
| )] |
|
||||
| 0 |
|
||||
|
||||
- **Invariant**\
|
||||
Počet kreditů na účtu je rovný počtu prvků na zásobníku.
|
||||
- **Důkaz**
|
||||
- Invariant platí pro prádný zásobník.
|
||||
- S `Push` operací se na účet připíše právě 1 kredit. (Čímž se předplatí `Pop` nebo `Multi-Pop`.)
|
||||
- `Pop` a `Multi-Pop` operace spotřebují právě 1 kredit z účtu.
|
||||
- Tedy stav účtu nikdy neklesne pod 0.
|
||||
- Tedy složitost posloupnosti je nejvýše součet kreditových cen, tedy $2n$.
|
||||
|
||||
### Potential method (physicist's method)
|
||||
|
||||
Hraje si s představou toho, že struktura je fyzikální systém s nějakou energetickou hladinou -- potenciálem. Výhodou této metody je, že stačí zvolit _jednu_ funkci, která splňuje dané podmínky. Nevýhodou je, že takovou funkci najít je těžké. Člověk zkrátka buď dostane nápad nebo ne.
|
||||
|
||||
- **Potenciálová funkce**\
|
||||
Funkce $\Phi$, která přiřadí dané struktuře $S$ hodnotu. Platí, že:
|
||||
|
||||
```math
|
||||
\begin{align*}
|
||||
\Phi(S_0) &= 0 \text{, kde } S_0 \text{ je počáteční stav} \\
|
||||
\Phi(S_i) &\ge 0 \text{ pro každou strukturu } S_i
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
- **Amortizovaná cena**\
|
||||
Pokud $c_i$ je _skutečná_ cena operace, pak pro amortizovanou cenu $\hat{c_i}$ platí:
|
||||
|
||||
```math
|
||||
\hat{c_i} = c_i + \Phi(S_i) - \Phi(S_{i-1})
|
||||
```
|
||||
|
||||
- **Potenciálová věta**\
|
||||
Počínaje počátečním stavem $S_0$, celková _skutečná_ cena posloupnosti $n$ operací je nejvýše součet jejich amortizovaných cen.
|
||||
- **Důkaz**
|
||||
|
||||
```math
|
||||
\begin{align*}
|
||||
\sum_{i=1}^n \hat{c_i} &= \sum_{i=1}^n (c_i + \Phi(S_i) - \Phi(S_{i-1})) \\
|
||||
&= \sum_{i=1}^n c_i + \Phi(S_n) - \Phi(S_0) \\
|
||||
&\geq \sum_{i=1}^n c_i \quad\tiny\blacksquare
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
**Zásobník (potenciálová věta)**
|
||||
|
||||
$\Phi(S) = |S|$ (počet prvků na zásobníku)
|
||||
|
||||
| Operace |
|
||||
| ------------------------- |
|
||||
| Skutečná cena |
|
||||
| Amortizovaná cena |
|
||||
| `Push` |
|
||||
| 1 |
|
||||
| stem:[\hat{c_i} = 1 + (\ |
|
||||
| S\ |
|
||||
| + 1) - \ |
|
||||
| S\ |
|
||||
| = 2] |
|
||||
| `Pop` |
|
||||
| 1 |
|
||||
| stem:[\hat{c_i} = 1 + \ |
|
||||
| S\ |
|
||||
| - (\ |
|
||||
| S\ |
|
||||
| + 1) = 0] |
|
||||
| `Multi-Pop` |
|
||||
| stem:[\min(k,\ |
|
||||
| S\ |
|
||||
| )] |
|
||||
| |
|
||||
|
||||
```math
|
||||
\hat{c_i} =
|
||||
\begin{cases}
|
||||
k + (\|S\| - k) - \|S\| = 0 & \text{pokud } \|S\| > k \\
|
||||
\|S\| + (\|S\| - \|S\|) - \|S\| = 0 & \text{pokud } \|S\| \le k
|
||||
|
||||
\end{cases}
|
||||
```
|
||||
|
||||
- **Věta**\
|
||||
Počínaje prázdným zásobníkem, libovolná sekvence operací zabere $\mathcal{O}(n)$ času.
|
||||
- **Důkaz (případ `Push`)**
|
||||
- Skutečná cena je $c_i = 1$.
|
||||
- Amortizovaná cena je $\hat{c_i} = c_i + \Phi(S_i) - \Phi(S_{i-1}) = 1 + (|S| + 1) - |S| = 2$.
|
||||
- **Důkaz (případ `Pop`)**
|
||||
- Skutečná cena je $c_i = 1$.
|
||||
- Amortizovaná cena je $\hat{c_i} = c_i + \Phi(S_i) - \Phi(S_{i-1}) = 1 - 1 = 0$.
|
||||
- **Důkaz (případ `Multi-Pop`)**
|
||||
- Skutečná cena je $c_i = k$.
|
||||
- Amortizovaná cena je $\hat{c_i} = c_i + \Phi(S_i) - \Phi(S_{i-1}) = k - k = 0$.
|
||||
- **Důkaz (závěr)**
|
||||
- Amortizovaná cena všech operací je $\hat{c_i} \le 2$.
|
||||
- Součet amortizovaných cen posloupnosti $n$ operací je pak $\sum_{i=1}^n \hat{c_i} \le 2n$.
|
||||
- Z potenciálnové věty plyne, že skutečná cena posloupnosti je $\le 2n$.
|
||||
|
||||
---
|
||||
|
||||
**Slavné potenciálové funkce**
|
||||
|
||||
- **Fibonnacciho halda**
|
||||
|
||||
```math
|
||||
\Phi(H) = 2 \cdot \text{trees}(H) - 2 \cdot \text{marks}(H)
|
||||
```
|
||||
|
||||
- **Splay trees**\
|
||||
Binární vyhledávací stromy, kde poslední přídané prvky jsou přístupné rychleji. [(zdroj)](https://en.wikipedia.org/wiki/Splay_tree)
|
||||
|
||||
```math
|
||||
\Phi(T) = \sum_{x \in T} \lfloor \log_2 \text{size}(x) \rfloor
|
||||
```
|
||||
|
||||
- **Move-to-front**\
|
||||
Transformace dat používaná při kompresi dat. [(zdroj)](https://en.wikipedia.org/wiki/Move-to-front_transform)
|
||||
|
||||
```math
|
||||
\Phi(L) = 2 \cdot \text{inversions}(L, L^*)
|
||||
```
|
||||
|
||||
- **Preflow-push (push-relabel)**
|
||||
|
||||
```math
|
||||
\Phi(f) = \sum_{v \,:\, \text{excess}(v) > 0} \text{height}(v)
|
||||
```
|
||||
|
||||
- **Red-black trees**
|
||||
|
||||
```math
|
||||
\Phi(T) = \sum_{x \in T} w(x)
|
||||
|
||||
\\
|
||||
|
||||
w(x) = \begin{cases}
|
||||
0 & \text{pokud } x \text{ je červený} \\
|
||||
1 & \text{pokud } x \text{ je černý a nemá žádné červené potomky} \\
|
||||
0 & \text{pokud } x \text{ je černý a má jednoho červeného potomka} \\
|
||||
2 & \text{pokud } x \text{ je černý a má dva červené potomky}
|
||||
\end{cases}
|
||||
```
|
||||
|
||||
## Vyhledávání řetězců (string matching)
|
||||
|
||||
_String matching_ označuje rodinu problémů obsahující třeba:
|
||||
|
||||
- Nalezení prvního přesného výskytu podřetězce (_patternu_) v řetězci (_stringu_ / _textu_).
|
||||
- Nalezení všech výskytů podřetězce v řetězci.
|
||||
- Výpočet vzdálenosti dvou řetězců.
|
||||
- Hledání opakujících se podřetězců.
|
||||
|
||||
Většinou je řetězec polem znaků z konečné abecedy $\Sigma$. String matching algoritmy se ale dají použít na ledacos.
|
||||
|
||||
Vzorek $P$ se vyskytuje v textu $T$ s posunem $s$, pokud $0 \le s \le n - m$ a zároveň $T\lbrack (s+1) .. (s + m) \rbrack = P$. Pro nalezení platných posunů lze použít řadu algoritmů, které se liší složitostí předzpracování i samotného vyhledávání: [iv003-strings](#iv003-strings)
|
||||
|
||||
| Algoritmus |
|
||||
| ----------------------------------- |
|
||||
| Preprocessing |
|
||||
| Searching |
|
||||
| Brute force / naivní |
|
||||
| $0$ |
|
||||
| $\mathcal{O}((n - m + 1) \cdot m)$ |
|
||||
| Karp-Rabin |
|
||||
| $\Theta(m)$ |
|
||||
| $\mathcal{O}((n - m + 1) \cdot m)$ |
|
||||
| finite automata |
|
||||
| stem:[\Theta(m \cdot \ |
|
||||
| \Sigma\ |
|
||||
| )] |
|
||||
| $\Theta(n)$ |
|
||||
| Knuth-Morris-Pratt |
|
||||
| $\Theta(m)$ |
|
||||
| $\Theta(m)$ |
|
||||
| Boyer-Moore |
|
||||
| stem:[\Theta(m + \ |
|
||||
| \Sigma\ |
|
||||
| )] |
|
||||
| $\mathcal{O}((n - m + 1) \cdot m)$ |
|
||||
|
||||
- $T$ nebo $T\lbrack 1..n \rbrack$ -- text.
|
||||
- $P$ nebo $P\lbrack 1..m \rbrack$ -- pattern.
|
||||
- $n$ -- délka textu $T$.
|
||||
- $m$ -- délka vzorku / podřetězce / patternu $P$.
|
||||
- $\Sigma$ -- konečná abeceda, ze které je složen text i pattern.
|
||||
|
||||
### Brute force / naivní
|
||||
|
||||
Prochází všechny pozice v textu a porovnává je s patternem. Pokud se neshodují, posune se o jedno pole dopředu.
|
||||
|
||||
Pokud se text neshoduje už v prvním znaku, je složitost lineární. Avšak v nejhorším případě, kdy se pattern shoduje s textem až na poslední znak, je složitost až kvadratická.
|
||||
|
||||
```csharp
|
||||
int Naive(string text, string pattern)
|
||||
{
|
||||
int n = text.Length;
|
||||
int m = pattern.Length;
|
||||
for (int i = 0; i < n - m + 1; i++)
|
||||
{
|
||||
// NB: Substring creates a new string but let's not worry about that.
|
||||
if (text.Substring(i, m) == pattern)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
```
|
||||
|
||||
- **Složitost**\
|
||||
Cyklus je proveden $n-m+1$-krát. V každé iteraci se provede přinejhorším až $m$ porovnání. (Zanedbáváme složitost `Substring`, která v C# dělá kopii.)
|
||||
|
||||
### Karp-Rabin
|
||||
|
||||
Používá hashování. Vytvoří hash z patternu a hashuje i všechny podřetězce délky $m$ v textu. Nejprve eliminuje všechny pozice, kde se hashe neshodují. Pokud se shodují, porovná je znak po znaku.
|
||||
|
||||
```csharp
|
||||
int KarpRabin(string text, string pattern)
|
||||
{
|
||||
int n = text.Length;
|
||||
int m = pattern.Length;
|
||||
int patternHash = pattern.GetHash();
|
||||
for (int i = 0; i < n - m + 1; i++)
|
||||
{
|
||||
// NB: Assume that `GetHash` is a rolling hash, even though in .NET it's not.
|
||||
if (text.Substring(i, m).GetHash() == patternHash)
|
||||
{
|
||||
if (text.Substring(i, m) == pattern)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
```
|
||||
|
||||
- **Hashování**\
|
||||
Trik spočívá v použití _rolling_ hashovacího algoritmu. Ten je schopný při výpočtu hashe pro $T\lbrack s .. (s + m) \rbrack$ použít hash $T\lbrack s .. (s + m - 1) \rbrack$ s využitím pouze jednoho dalšího znaku $T\lbrack s + m \rbrack$. Přepočet hashe je tedy $\mathcal{O}(1)$.
|
||||
|
||||
Jeden takový algoritmus lze získat použitím Hornerova schématu pro evaluaci polynomu. [horner](#horner) Předpokládejme, že $\Sigma = \{0, 1, ..., 9\}$ (velikost může být libovolná), pak pro hash $h$ platí
|
||||
|
||||
```math
|
||||
\begin{align*}
|
||||
h &= P[1] + 10 \cdot P[2] + 10^2 \cdot P[3] + ... + 10^{m-1} \cdot P[m] \\
|
||||
&= P[1] + 10 \cdot (P[2] + 10 \cdot (P[3] + ... + 10 \cdot P[m] ... ))
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
Pokud jsou hashe příliš velké, lze navíc použít modulo $q$, kde $10 \cdot q \approx \text{machine word}$.
|
||||
|
||||
- **Složitost**\
|
||||
Předzpracování zahrnuje výpočet $T \lbrack 1..m \rbrack$ v $\Theta(m)$.
|
||||
|
||||
Složitost výpočtu je v nejhorším případě $\mathcal{O}((n - m + 1) \cdot m)$, jelikož je potřeba porovnat všechny podřetězce délky $m$ s patternem.
|
||||
|
||||
Tento algoritmus se hodí použít, pokud hledáme v textu celé věty, protože neočekáváme velké množství "falešných" shod, které mají stejný hash jako $P$. V tomto případě je průměrná složitost $\mathcal{O}(n)$.
|
||||
|
||||
### Konečné automaty
|
||||
|
||||
Složitost naivního algortmu lze vylepšit použitím konečného automatu.
|
||||
|
||||
Mějmě DFA $A = (\{0, ..., m\}, \Sigma, \delta, \{0\}, \{m\})$, kde přechodobou funkci definujeme jako:
|
||||
|
||||
```math
|
||||
\delta(q, x) = \text{největší } k \text{ takové, že } P[1..k] \text{ je \textbf{prefix} a zároveň \textbf{suffix} } P[1..q] . x
|
||||
```
|
||||
|
||||
Jinými slovy, $\delta$ vrací delků nejdelšího možného začátku $P$, který se nachází na daném místě (stavu $q$) v řetězci $T$.
|
||||
|
||||
Prakticky by příprava přechodové funkce mohla vypadat takto:
|
||||
|
||||
```csharp
|
||||
int[,] CreateAutomaton(string pattern)
|
||||
{
|
||||
int m = pattern.Length;
|
||||
// NB: Assumes that the alphabet is ASCII.
|
||||
int[,] automaton = new int[m + 1, 256];
|
||||
for (int q = 0; q <= m; q++)
|
||||
{
|
||||
for (int c = 0; c < 256; c++)
|
||||
{
|
||||
int k = Math.Min(m + 1, q + 2);
|
||||
do
|
||||
{
|
||||
k--;
|
||||
}
|
||||
while (!pattern.Substring(0, q).Equals(pattern.Substring(0, k) + (char)c));
|
||||
automaton[q, c] = k;
|
||||
}
|
||||
}
|
||||
return automaton;
|
||||
}
|
||||
```
|
||||
|
||||
Vyhledávání v textu pak bude vypadat takto:
|
||||
|
||||
```csharp
|
||||
int FiniteAutomaton(string text, string pattern)
|
||||
{
|
||||
int n = text.Length;
|
||||
int m = pattern.Length;
|
||||
int[,] automaton = CreateAutomaton(pattern);
|
||||
int q = 0;
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
q = automaton[q, text[i]];
|
||||
if (q == m)
|
||||
{
|
||||
return i - m + 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
```
|
||||
|
||||
Tato metoda šetří čas, pokud se pattern v některých místech opakuje. Mějmě například pattern `abcDabcE` a text `abcDabcDabcE`. Tato metoda nemusí začínat porovnávat pattern od začátku po přečtení druhého `D`, ale začne od $P \lbrack 5 \rbrack$ (včetně), protože _ví_, že předchozí část patternu se již vyskytla v textu.
|
||||
|
||||
Jinými slovy na indexu druhého `D` je `abcD` nejdelší prefix $P$, který je zároveň suffixem už načteného řetězce.
|
||||
|
||||
- **Složitost**\
|
||||
Vytvoření automatu vyžaduje $\Theta(m^3 \cdot |\Sigma|)$ času, dá se však provést efektivněji než v `CreateAutomaton` a to v čase $\Theta(m \cdot |\Sigma|)$.
|
||||
|
||||
Složitost hledání je pak v $\Theta(n)$. [iv003-strings](#iv003-strings)
|
||||
|
||||
### Knuth-Morris-Pratt (KMP)
|
||||
|
||||
KMP představuje efektivnější využití idei z metody konečného automatu:
|
||||
|
||||
- Každý stav $q$ je označen písmenem z patternu. Výjimkou je počáteční stav $S$ a koncový stav $F$.
|
||||
- Každý stav má hranu `success`, která popisuje sekvenci znaků z patternu, a `failure` hranu, která míří do některého z předchozích stavů -- takového, že už načtené znaky jsou největší možný prefix patternu.
|
||||
|
||||
V reálné implementaci nejsou `success` hrany potřeba; potřebujeme jen vědět, kam skočit v případě neúspěchu.
|
||||
|
||||
```csharp
|
||||
/// <summary>
|
||||
/// Computes the longest proper prefix of P[0..i]
|
||||
/// that is also a suffix of P[0..i].
|
||||
/// </summary>
|
||||
int[] ComputeFailure(string pattern)
|
||||
{
|
||||
int m = pattern.Length;
|
||||
int[] fail = new int[m];
|
||||
int j = 0;
|
||||
for (int i = 1; i < m; i++)
|
||||
{
|
||||
while (j >= 0 && pattern[j] != pattern[i])
|
||||
{
|
||||
j = fail[j];
|
||||
}
|
||||
|
||||
// If comparison at i fails,
|
||||
// return to j as the new starting point.
|
||||
fail[i] = j;
|
||||
|
||||
j++;
|
||||
}
|
||||
return fail;
|
||||
}
|
||||
|
||||
int KnuthMorrisPratt(string text, string pattern)
|
||||
{
|
||||
int[] fail = ComputeFailure(pattern);
|
||||
int n = text.Length;
|
||||
int m = pattern.Length;
|
||||
// NB: I index from 0 here. Although I use 1..n in the text.
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
while (j >= 0 && text[i] != pattern[j])
|
||||
{
|
||||
/*
|
||||
There can be at most n-1 failed comparisons
|
||||
since the number of times we decrease j cannot
|
||||
exceed the number of times we increment i.
|
||||
*/
|
||||
j = fail[j];
|
||||
}
|
||||
|
||||
j++;
|
||||
if (j == m)
|
||||
{
|
||||
return i - m;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
```
|
||||
|
||||
**⚠️ WARNING**\
|
||||
Nejsem si jistý, že ty indexy v kódu výše mám dobře.
|
||||
|
||||
**📌 NOTE**\
|
||||
"In other words we can amortize character mismatches against earlier character matches." [iv003-strings](#iv003-strings)
|
||||
|
||||
- **Složitost**\
|
||||
Amortizací neúspěšných porovnání vůči úspěšným získáme $\mathcal{O}(m)$ pro `ComputeFailure` a $\mathcal{O}(n)$ pro `KnuthMorrisPratt`.
|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[iv003, 1]]] [IV003 Algoritmy a datové struktury II (jaro 2021)](https://is.muni.cz/auth/el/fi/jaro2021/IV003/)
|
||||
- [[[iv003-strings,2]]] https://is.muni.cz/auth/el/fi/jaro2021/IV003/um/slides/stringmatching.pdf
|
||||
- [[[rabin-karp-wiki,3]]] https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm
|
||||
- [[[horner,4]]] https://en.wikipedia.org/wiki/Horner%27s_method
|
||||
- [[[backtracking,5]]] https://betterprogramming.pub/the-technical-interview-guide-to-backtracking-e1a03ca4abad
|
344
src/content/docs/szmgr/SZP02_numericke_metody.md
Normal file
344
src/content/docs/szmgr/SZP02_numericke_metody.md
Normal file
@ -0,0 +1,344 @@
|
||||
---
|
||||
title: "Numerické metody"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Iterativní metody pro řešení nelineárních rovnic (Newtonova metoda a její modifikace). Přímé metody pro řešení systému lineárních rovnic (Gaussova eliminace, Jacobi, Gauss-Seidel, relaxační metody). Numerická diferenciace, diferenciační schémata.
|
||||
|
||||
_MA018_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
- **Numerická analýza / numerical analysis**\
|
||||
Oblast matematiky / informatiky zabývající se tvorbou numerických metod a algoritmů, které řeší problémy matematické analýzy (např. derivace, integrály a podobný symbolický balast) pomocí numerické aproximace. [numerical-analysis](#numerical-analysis)
|
||||
|
||||
Je výhodná v situacích, kdy problém nelze řešit analyticky nebo je to příliš složité a není to (výpočetní) čas.
|
||||
|
||||
- **Notace chyb**
|
||||
|
||||
- $x$ je přesná hodnota,
|
||||
- $\tilde{x}$ je aproximace $x$,
|
||||
- $x - \tilde{x}$ je absolutní chyba $\tilde{x}$,
|
||||
- $\lvert x - \tilde{x} \rvert \leq \alpha$ je odhad absolutní chyby,
|
||||
- $\frac{x - \tilde{x}}{x}$ je relativní chyba,
|
||||
- $\left\lvert \frac{x - \tilde{x}}{x} \right\rvert \leq \alpha$ je odhad relativní chyby.
|
||||
|
||||
- **Numerická stabilita**\
|
||||
Schopnost numerické metody zpracovat chyby vstupních dat a výpočetních operací.
|
||||
|
||||
Desetinná čísla jsou v počítačích nevyhnutelně reprezentována nepřesně. Numericky stabilní metody jsou takové, které tyto nepřesnosti **nezhoršují**. [numerical-stability](#numerical-stability)
|
||||
|
||||
- **Řád metody / order of accuracy / order of approximation**\
|
||||
Hodnota reprezentující, jak rychle metoda konverguje k výsledku, resp. jak přesný je její odhad.
|
||||
|
||||
Numerická metoda obvykle konverguje snižováním nějakého _kroku_ $h$. Pokud ho lze zvolit libovolně malý, a lze-li prohlásit, že pro chybu aproximace $E$ platí: [rate](#rate) [numericka-metoda](#numericka-metoda) [order-question](#order-question)
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
|
||||
E(h) &\leq C \cdot h^p \\
|
||||
E(h) &\in \mathcal{O}(h^p)
|
||||
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
kde $C$ je konstanta. Pak $p$ je řád metody.
|
||||
|
||||
## Iterativní metody pro řešení nelineárních rovnic
|
||||
|
||||
- **Root-finding problem**\
|
||||
Problém nalezení _kořenů_ (root) funkce $f$. T.j. takových parametrů $x, ...$, kde funkce vrací 0: [root-finding](#root-finding)
|
||||
|
||||
```math
|
||||
f(x, ...) = 0
|
||||
```
|
||||
|
||||
- **Iterative methods for root-finding problem**\
|
||||
Metody pro řešení root-finding problemu, které využívají iterativního přístupu. Tedy opakují nějaký výpočet a zpřesňují svůj odhad, dokud nedosáhnou požadované přesnosti. [ma018](#ma018) [root-finding](#root-finding)
|
||||
- **Řád metody / rate of convergence**\
|
||||
Hodnota reprezentující, jak rychle metoda konverguje k výsledku. [rate](#rate)
|
||||
- **Prostá iterační metoda / metoda pevného bodu / fixed-point iteration**\
|
||||
Používá se pro rovnice typu $x = g(x)$.
|
||||
|
||||
1. Zvolíme počáteční odhad $x_0$.
|
||||
2. Opakujeme $x_{n+1} = g(x_n)$ dokud $\lvert x_{n+1} - x_n \rvert \leq \alpha$ (kde $\alpha$ je požadovaná přesnost).
|
||||
|
||||

|
||||
|
||||
- **Newtonova metoda / metoda tečen**\
|
||||
Používá k odhadu kořene funkce $f$ její tečnu v bodě $x_n$. Iterační funkce je:
|
||||
|
||||
```math
|
||||
g(x_{k+1}) = x_k - \frac{f(x_k)}{f'(x_k)}
|
||||
```
|
||||
|
||||
1. Zvolíme počáteční odhad $x_0$.
|
||||
2. Další odhad je $x_{n+1} = g(x_n)$, tedy průsečík tečny fukce $f$ v bodě $x_n$ s osou $x$.
|
||||
3. Opakujeme 2. dokud nedosáhneme požadované přesnosti odhadu.
|
||||
|
||||

|
||||
|
||||
- **Metoda sečen / secant method**\
|
||||
Používá k odhadu kořene funkce $f$ sečny, resp. _finite difference_, které aproximují derivaci funkce $f$. Díky tomu není potřeba znát derivaci funkce $f$. Iterační funkce je:
|
||||
|
||||
```math
|
||||
g(x_{k+1}) = x_k - \frac{f(x_k)(x_k - x_{k-1})}{f(x_k) - f(x_{k-1})}
|
||||
```
|
||||
|
||||

|
||||
|
||||
- **Metoda regula falsi**\
|
||||
Je _bracketing_ metoda, tedy metoda, která využívá intervalu, ve kterém se nachází kořen. Nemusí se použít iterativně, ale v iterativní podobě tento interval postupně zmenšuje. [regula-falsi](#regula-falsi)
|
||||
|
||||
```math
|
||||
x_{k+1} = x_k - \frac{x_k - x_s}{f(x_k) - f(x_s)} f(x_k)
|
||||
```
|
||||
|
||||
kde $s$ je největší index takový, že $f(x_k)f(x_s) < 0$.
|
||||
|
||||
## Přímé metody pro řešení systému lineárních rovnic
|
||||
|
||||
### Gaussova eliminace
|
||||
|
||||
Systém rovnice je přepsán do matice. Gaussova eliminace je posloupnost operací, jejichž cílem je převést matici do horní trojúhelníkové matice (_row echelon form_). [gauss-elimination](#gauss-elimination) Povoleny jsou následující operace:
|
||||
|
||||
- výměna dvou řádků,
|
||||
- vynásobení řádku nenulovou konstantou,
|
||||
- přičtení násobku jednoho řádku k jinému.
|
||||
|
||||
### Jacobiho iterační metoda
|
||||
|
||||
Iterativní algoritmus pro řešení soustavy lineárních rovnic. Rozděluje vstupní matici lineárních rovnic na matici diagonál $D$, dolní trojúhelníkovou matici $L$ a horní trojúhelníkovou matici $U$. [jacobi-method](#jacobi-method)
|
||||
|
||||
Nechť $A\mathbf{x} = \mathbf{b}$ je systém $n$ lineárních rovnic. Tedy:
|
||||
|
||||
```math
|
||||
A = \begin{bmatrix}
|
||||
a_{11} & a_{12} & \cdots & a_{1n} \\
|
||||
a_{21} & a_{22} & \cdots & a_{2n} \\
|
||||
\vdots & \vdots & \ddots & \vdots \\
|
||||
a_{n1} & a_{n2} & \cdots & a_{nn}
|
||||
\end{bmatrix}, \qquad
|
||||
|
||||
\mathbf{x} = \begin{bmatrix}
|
||||
x_{1} \\ x_2 \\ \vdots \\ x_n
|
||||
\end{bmatrix} , \qquad
|
||||
|
||||
\mathbf{b} = \begin{bmatrix}
|
||||
b_{1} \\ b_2 \\ \vdots \\ b_n
|
||||
\end{bmatrix}.
|
||||
```
|
||||
|
||||
Algoritmus vypadá takto:
|
||||
|
||||
1. Zvolíme počáteční odhad $\mathbf{x}^{(0)}$, nejčastěji $\vec{0}$.
|
||||
2. Nový odhad získáme ze vztahu:
|
||||
|
||||
```math
|
||||
\mathbf{x}^{(k+1)} = D^{-1}(\mathbf{b} - (L + U)\mathbf{x}^{(k)})
|
||||
```
|
||||
|
||||
Jelikož $L + U = A - D$, dá to zapsat i jako:
|
||||
|
||||
```math
|
||||
\mathbf{x}^{(k+1)} = D^{-1}\mathbf{b} + (I - D^{-1} A) \mathbf{x}^{(k)}
|
||||
```
|
||||
|
||||
- **Spektrální poloměr**\
|
||||
Spektrální poloměr $\rho$ matice $A$ je největší absolutní hodnota vlastního čísla matice $A$.
|
||||
|
||||
```math
|
||||
\rho(A) = \max_{i=1,\ldots,n} |\lambda_i|
|
||||
```
|
||||
|
||||
- **(Řádková) diagonální dominance**\
|
||||
Matice $A$ je diagonálně dominantní, pokud platí:
|
||||
|
||||
```math
|
||||
|a_{ii}| > \sum_{j=1, j \neq i}^n |a_{ij}|
|
||||
```
|
||||
|
||||
Tedy absolutní hodnota prvku na diagonále je větší než součet absolutních hodnot všech ostatních prvků v řádku.
|
||||
|
||||
- _Striktní_: nerovnost je ostrá ($>$).
|
||||
- _Slabá_: nerovnost je neostá ($\ge$).
|
||||
|
||||
Analogicky se definuje sloupcová diagonální dominance.
|
||||
|
||||
- **Konvergence Jacobiho metody**\
|
||||
Jacobiho metoda konveguje pokud všechny následující podmínky:
|
||||
|
||||
1. Nechť $T_j = I - D^{-1} A$ je matice iterace Jacobiho metody. Pak Jacobiho metoda konverguje, pokud:
|
||||
|
||||
```math
|
||||
\rho(T_j) < 1
|
||||
```
|
||||
|
||||
2. Jacobiho metoda konverguje pro libovolný počáteční odhad $\mathbf{x}^{(0)}$, pokud $A$ je diagonálně dominantní (sloupcově nebo řádkově).
|
||||
|
||||
### Gaussova-Seidelova iterační metoda
|
||||
|
||||
Iterativní metoda pro řešení soustavy lineárních rovnic. Dělí vstupní matici na spodní trojúhelníkovou matici $L_*$ (včetně diagonály, tedy $L_* = D + L$) a striktně horní trojúhelníkovou matici $U$ (diagonála je nulová). Algoritmus vypadá takto: [gauss-seidel](#gauss-seidel)
|
||||
|
||||
1. Zvolíme počáteční odhad $\mathbf{x}^{(0)}$.
|
||||
2. Nový odhad získáme ze vztahu:
|
||||
|
||||
```math
|
||||
\mathbf{x}^{(k+1)} = L_*^{-1}(\mathbf{b} - U\mathbf{x}^{(k)}).
|
||||
```
|
||||
|
||||
Alternativně:
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
|
||||
T_{gs} &= (D + L)^{-1} U = L_*^{-1} U \\
|
||||
\mathbf{x}^{(k+1)} &= T_{gs} \mathbf{x}^{(k)} + g,\quad g = L_*^{-1} \mathbf{b}
|
||||
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
- **Konvergence Gaussovy-Seidelovy metody**\
|
||||
Analogicky jako u Jacobiho metody, ale místo matice $T_j$ se použije matice $T_{gs} = (D + L)^{-1} U$.
|
||||
|
||||
### Relaxační iterativní metody
|
||||
|
||||
Modifikace Gauss-Seidelovy metody. Využívá parametr $\omega$, který určuje, jak moc se má nový odhad lišit od předchozího. Vztah pro další iteraci se mění na: [relaxation-method](#relaxation-method)
|
||||
|
||||
```math
|
||||
\begin{align*}
|
||||
\mathbf{x}^{(k+1)} &= (D - \omega L)^{-1} [(1-\omega)D + \omega U]\mathbf{x}^{(k)} + \omega(D - \omega L)^{-1}\mathbf{b} \\
|
||||
T_\omega &= (D - \omega L)^{-1} [(1-\omega)D + \omega U]
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
- Pro $0 < \omega < 1$ se názývá metodou dolní relaxace. Je vhodná v případě, kdy Gauss-Seidel nekonverguje.
|
||||
- Pro $\omega = 1$ je totožná s Gauss-Seidelem.
|
||||
- Pro $\omega > 1$ se názývá metodou horní relaxace / SOR metodou. Zrychluje konvergenci Gauss-Seidela.
|
||||
|
||||
### Dekompozice matic
|
||||
|
||||
Metody podobné Gaussově eliminaci, ale s vlastnostmi, které mohou být vyhodné.
|
||||
|
||||
- **LU dekompozice**\
|
||||
Rozdělení matice $A$ na horní dolní trojúhelníkovou matici $L$ a horní trojúhelníkovou matici $U$, tak že $A = LU$.
|
||||
|
||||
Je to v podstatě Gaussova eliminace. Matice $P$ je permutační matice, která prohazuje řádky:
|
||||
|
||||
```math
|
||||
P \cdot A = L \cdot U
|
||||
```
|
||||
|
||||
Platí, že:
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
A \cdot x &= b \\
|
||||
A &= LU \\
|
||||
LU \cdot x &= b
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
Původní problém řešení soustavy linárních rovnic se tedy převede na dva problémy:
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
y &= U \cdot x \\
|
||||
L \cdot y &= b \\
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
Řešíme tedy dva systémy rovnic s trojúhelníkovými maticemi.
|
||||
|
||||
Oproti Gaussovi je výhodnější pro:
|
||||
|
||||
- Opakované řešení soustav s maticí $A$ a různými pravými stranami $b$.
|
||||
- Inverzi matice $A$.
|
||||
- Výpočet determinantu matice $A$.
|
||||
|
||||
- **QR dekompozice**\
|
||||
Rozdělení matice $A$ na ortogonální matici $Q$ a horní trojúhelníkovou matici $R$ (už ne $U$), tak že $A = QR$.
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
|
||||
A \cdot x &= b \\
|
||||
A = QR \Rightarrow U \cdot x &= Q^T \cdot b \\
|
||||
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
Protože je ortogonální a tedy $Q^{-1} = Q^T$.
|
||||
|
||||
Má lepší numerickou stabilitu než LU dekompozice.
|
||||
|
||||
## Numerická diferenciace
|
||||
|
||||
Algoritmy numerické diferenciace (derivace) počítají odhady derivace reálných funkcí -- aproximují $f'(x)$. Využívají při tom známé hodnoty této funkce a jiné znalosti a předpoklady. [differentiation](#differentiation)
|
||||
|
||||
Numerická diferenciace se využívá pro aproximaci differenciálních rovnic (převodem na _diferenční rovnice_).
|
||||
|
||||
- **Langrangeova interpolace**\
|
||||
Pokud známe hodnoty $f$ můžeme mezi nimi interpolovat pomocí Lagrangeova polynomu a derivovat ten, protože derivovat polynomy je jednoduché.
|
||||
|
||||
**❗ IMPORTANT**\
|
||||
Lagrangeovu interpolaci řeší část otázky [Křivky a povrchy](../krivky-a-povrchy/).
|
||||
|
||||
- **Finite difference method**\
|
||||
Rodina metod numerické diferenciace, které využívají _konečné diference_. Tedy approximují limitu v definici derivace malými posuny ve vstupních hodnotách diferenciovaných funkcí. [finite-difference-method](#finite-difference-method)
|
||||
|
||||
Jednotlivým "odstínům" -- konkrétním výpočetním vzorcům -- téhle metody se říká _diferenciační schémata_.
|
||||
|
||||
**💡 TIP**\
|
||||
Abych pravdu řekl, nepodařilo se mi najít zdroj pro konkrétní definici pojmu "diferenciační schéma".
|
||||
|
||||
- **(Konečné) diference prvního řádu / first-order (finite) differences**\
|
||||
Nejjednodušší schéma numerické diferenciace. Vychází z definice derivace. [finite-difference](#finite-difference)
|
||||
|
||||
- _Dopředná diference / forward (finite) difference_
|
||||
|
||||
```math
|
||||
\frac{\partial f}{\partial x} \approx \frac{f(x+h) - f(x)}{h}
|
||||
```
|
||||
|
||||
- _Zpětná diference / backward (finite) difference_
|
||||
|
||||
```math
|
||||
\frac{\partial f}{\partial x} \approx \frac{f(x) - f(x-h)}{h}
|
||||
```
|
||||
|
||||
- _Centrální diference / central (finite) difference_
|
||||
|
||||
```math
|
||||
\frac{\partial f}{\partial x} \approx \frac{f(x+h) - f(x-h)}{2h}
|
||||
```
|
||||
|
||||
kde $h$ je kladné číslo napodobující nekonečně malou změnu (limitu) v definici derivace. Může to být konstanta, může ale být i zvoleno adaptivně.
|
||||
|
||||
**💡 TIP**\
|
||||
Tečna je tak napodobena sečnou.
|
||||
|
||||
- **Richardson extrapolation**\
|
||||
Způsob zlepšení rate of convergence iterativních metod. [richardson](#richardson)
|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[ma018,1]]] [MA018 Numerical Methods (podzim 2019)](https://is.muni.cz/auth/el/fi/podzim2019/MA018/)
|
||||
- [[[numerical-analysis,2]]] [Wikipedia: Numerical analysis](https://en.wikipedia.org/wiki/Numerical_analysis)
|
||||
- [[[root-finding,3]]] [Wikipedia: Root-finding algorithms](https://en.wikipedia.org/wiki/Root-finding_algorithms)
|
||||
- [[[rate, 4]]] [Wikipedia: Rate of convergence](https://en.wikipedia.org/wiki/Rate_of_convergence)
|
||||
- [[[regula-falsi,5]]] [Wikipedia: Regula falsi](https://en.wikipedia.org/wiki/Regula_falsi)
|
||||
- [[[gauss-elimination,6]]] [Wikipedia: Gaussian elimination](https://en.wikipedia.org/wiki/Gaussian_elimination)
|
||||
- [[[jacobi-method,7]]] [Wikipedia: Jacobi method](https://en.wikipedia.org/wiki/Jacobi_method)
|
||||
- [[[gauss-seidel,8]]] [Wikipedia: Gauss-Seidel method](https://en.wikipedia.org/wiki/Gauss%E2%80%93Seidel_method)
|
||||
- [[[relaxation-method, 9]]] [Wikipedia: Relaxation (iterative method)](<https://en.wikipedia.org/wiki/Relaxation_(iterative_method)>)
|
||||
- [[[differentiation, 10]]] [Wikipedia: Numerical differentiation](https://en.wikipedia.org/wiki/Numerical_differentiation)
|
||||
- [[[finite-difference, 11]]] [Wikipedia: Finite difference](https://en.wikipedia.org/wiki/Finite_difference)
|
||||
- [[[finite-difference-method, 12]]] [Wikipedia: Finite difference method](https://en.wikipedia.org/wiki/Finite_difference_method)
|
||||
- [[[richardson,13]]] [Wikipedia: Richardson extrapolation](https://en.wikipedia.org/wiki/Richardson_extrapolation)
|
||||
- [[[linear-eq, 14]]] [Wikipedia: System of linear equations](https://en.wikipedia.org/wiki/System_of_linear_equations)
|
||||
- [[[numerical-stability, 15]]] [Wikipedia: Numerical stability](https://en.wikipedia.org/wiki/Numerical_stability)
|
||||
- [[[numericka-metoda,16]]] [Wikipedia: Numerická metoda](https://cs.wikipedia.org/wiki/Numerick%C3%A1_metoda)
|
||||
- [[[order-question,17]]] [What is the intuitive meaning of order of accuracy and order of approximation?](https://math.stackexchange.com/questions/2873291/what-is-the-intuitive-meaning-of-order-of-accuracy-and-order-of-approximation)
|
544
src/content/docs/szmgr/SZP03_statistika.md
Normal file
544
src/content/docs/szmgr/SZP03_statistika.md
Normal file
@ -0,0 +1,544 @@
|
||||
---
|
||||
title: "Statistika"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Diskrétní a spojité náhodné veličiny (NV), základní rozložení. Číselné charakteristiky NV. Centrální limitní věta. Bodové odhady, intervaly spolehlivosti, testování statistických hypotéz, hladina významnosti. Základní parametrické a neparametrické testy, ANOVA, testy nezávislosti NV. Lineární regrese, celkový F-test, dílčí t-testy.
|
||||
|
||||
_MV013_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
**Opakování**
|
||||
|
||||
**💡 TIP**\
|
||||
Viz bakalářské otázky [Kombinatorika a pravděpodobnost](../../szb/kombinatorika-a-pravdepodobnost/) a [Statistika](../../szb/statistika/).
|
||||
|
||||
- **Statistika**\
|
||||
Zabývá se sbíráním, organizací, analýzou, interpretací a prezentací dat. [statistics](#statistics)
|
||||
|
||||
- _Popisná / decriptive_: shrnuje data, která máme,
|
||||
- _Inferenční / inferential_: předpokládá, že data která máme jsou jen součástí celku; pracuje s modely celé populace a hypotézami o ní.
|
||||
|
||||
- **Základní prostor $\Omega$**\
|
||||
Konečná množina možných jevů. Např $\{1, 2, 3, 4, 5, 6\}$ pro možné hody šestistěnkou.
|
||||
- **Možný výsledek (elementární náhodný jev) $\omega_k$**\
|
||||
Prvek základního prostoru $\Omega$.
|
||||
- **Náhodný jev (event) $A$**\
|
||||
Podmnožina $A \sube \Omega$, která nás zajímá. Např. _"Na šestistěnce padne sudé číslo."_
|
||||
|
||||
## Náhodné veličiny
|
||||
|
||||
- **Náhodná veličina (NV) / random variable**\
|
||||
Něco, co se dá u každého možného výsledku změřit. Zobrazení z prostoru elementárních jevů do měřitelného prostoru $E$ (třeba $\mathbb{R}$).
|
||||
|
||||
$X : \Omega \to \mathbb{E}$
|
||||
|
||||
### Diskrétní
|
||||
|
||||
Diskrétní NV je náhodná veličina, která nabývá konečně nebo spočetně mnoha hodnot. $\mathbb{E}$ je konečná nebo spočetná, např. $\N$.
|
||||
|
||||
Příklad: hodnota na šestistěnce.
|
||||
|
||||
Jinými slovy, NV $X : \Omega \to \R$ je _diskrétní_, pokud se prvky $\Omega$ zobrazí do $\R$ jako izolované body $\{x_1, x_2, \ldots\}$.
|
||||
|
||||
- **Rozdělení pravděpodobnosti**\
|
||||
Funkce $P(X) : \mathbb{E} \to \R$, která každé hodnotě popsané veličinou $X$ přiřazuje pravděpodobnost jejího výskytu.
|
||||
|
||||
- Každá $x_i$ má nenulovou pravděpodobnost:
|
||||
|
||||
```math
|
||||
P(x_i) > 0
|
||||
```
|
||||
|
||||
- Součet pravděpodobností všech možných hodnot $x_i$ je $1$:
|
||||
|
||||
```math
|
||||
\sum_{x} P(x_i) = 1
|
||||
```
|
||||
|
||||
### Spojité
|
||||
|
||||
Spojitá NV je náhodná veličina, která nabývá až nespočetně nekonečně mnoha hodnot. Tedy $\mathbb{E}$ je nespočetná, např. $\R$.
|
||||
|
||||
Příklad: doba čekání na šalinu, analogový signál, výška člověka (pokud máme fakt dobrej metr).
|
||||
|
||||
Jinými slovy, NV $X : \Omega \to \R$ je _spojitá_, pokud se prvky $\Omega$ zobrazí do $\R$ jako interval $\lbrack a, b \rbrack$.
|
||||
|
||||
- **Hustota pravděpodobnosti / probability density function (PDF)**\
|
||||
Funkce $f(x) : \mathbb{E} \to \R$, která každé hodnotě popsané veličinou $X$ přiřazuje pravděpodobnost jejího výskytu.
|
||||
|
||||
- Každý bod tohoto intervalu má **nulovou** pravděpodobnost:
|
||||
|
||||
```math
|
||||
f(x) = 0
|
||||
```
|
||||
|
||||
- Nicméně integrál pravděpodobnostní funkce $f(x)$ je $1$:
|
||||
|
||||
```math
|
||||
\int_{-\infty}^{\infty} f(x) dx = 1
|
||||
```
|
||||
|
||||
- Pravděpodobnost, že NV nabývá hodnoty z intervalu $\lbrack a, b \rbrack$ je pak:
|
||||
|
||||
```math
|
||||
P(a \leq X \leq b) = \int_{a}^{b} f(x) dx
|
||||
```
|
||||
|
||||
### Základní rozložení
|
||||
|
||||
- **Distribuční funkce / cumulative distribution function (CDF)**
|
||||
|
||||
Funkce $F(X) : \mathbb{E} \to \R$ udává pravděpodobnost, že NV $X$ nabývá hodnoty menší než $x$.
|
||||
|
||||
```math
|
||||
\begin{align*}
|
||||
|
||||
F(x) &= P(X \leq x) & \text{pro diskrétní NV} \\
|
||||
F(x) &= \int_{-\infty}^{x} f(x) dx & \text{pro spojité NV}
|
||||
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
Charakterizuje rozdělení, kterému náhodná veličina $X$ podléhá.
|
||||
|
||||
Pro spojité NV je to plocha pod křivkou pravděpodobnostní funkce. A taky se dá použít k vyjádření pravdepodobnosti:
|
||||
|
||||
```math
|
||||
P(a \leq X \leq b) = F(b) - F(a)
|
||||
```
|
||||
|
||||
**Diskrétní rozložení**
|
||||
|
||||
| Název |
|
||||
| ---------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ---------------------------------- |
|
||||
| Definice | Popis | Příklad | Bernoulliho / alternativní |
|
||||
| $ P(x) = \begin{cases} 1 - p & x \ne 1 \\ p & x = 1 \\ \end{cases} $ | Náhodný pokus, kde jsou jen dva možné výsledky. | Hod mincí. | Binomické |
|
||||
| $ P(x, n, p) = \binom{n}{x} p^x (1-p)^{n-k} $ | Sekvence $n$ pokusů. Popisuje pravděpodobnost, že $x$ bude úspěšných. | Hod mincí $n$ krát. | Poissonovo |
|
||||
| $ P(k, \lambda) = \frac{\lambda^k e^{-\lambda}}{k!} $ | Pokud se něco děje průměrně $\lambda$-krát za jednotku času, jaká je pravděpodobnost, že se to stane $k$-krát za stejnou jednotku času? Výskyt jednoho jevu nesmí ovlivnit pravděpodobnost následujícího výskytu a také se nemohou stát dva jevy najednou. | Kolik lidí přijde do obchodu za hodinu. _(Za předpokladu, že je pandemie a dovnitř může jen jeden člověk.)_ | Geometrické |
|
||||
| $ P(k, p) = \begin{cases} p (1-p)^k & k = 0, 1, ... \\ 0 & \text{jinak} \\ \end{cases} $ | Když tě zajímá, jaká je šance, že se něco pokazí $k$ krát, než to konečně uspěje. | Kolikrát musíš hodit mincí, než padne poprvé hlava. | (Diskrétní) rovnoměrné / uniformní |
|
||||
|
||||
**Spojité rozložení**
|
||||
|
||||
| Název |
|
||||
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | -------------------------------- |
|
||||
| Definice | Popis | Příklad | (Spojité) rovnoměrné / uniformní |
|
||||
| $ f(x) = \begin{cases} \frac{1}{b-a} & a \le x \le b \\ 0 & x < a \lor x > b \\ \end{cases} $ | Všechny jevy v daném intervalu $(a, b)$ (může být otevřený nebo uzavřený) jsou stejně pravděpodobné. | Bod na kružnici. | Exponenciální |
|
||||
| $ f(x, \lambda) = \begin{cases} \lambda e^{-\lambda x} & x \ge 0 \\ 0 & x < 0 \\ \end{cases} $ | Čas mezi jevy v Poissonově procesu. | Jak dlouho budeš čekat na šalinu. | Normální / Gaussovo |
|
||||
| $ f\_\mathcal{N}(x, \mu, \sigma^2) = \frac{1}{\sigma \sqrt{2 \pi}} e^{ -\frac {\left(x - \mu \right)^2} {2\sigma^2} } $ | Používá se jako default, když nevíš, jakou má proměnná distribuci, kvůli centrální limitní větě. ($\mu$ je mean, $\sigma^2$ je rozptyl). | Výška lidí. | Standardní normální |
|
||||
| $ f(x) = f\_\mathcal{N}(x, 0, 1) = \frac{1}{\sqrt{2 \pi}} e^{-\frac{x^2}{2}} $ | Je fajn, protože má standardní odchylku rovnu jedné, takže člověku stačí si pamatovat, že: _ 68 % je v intervalu $(-1, 1)$, _ 95 % je v intervalu $(-2, 2)$, \* 99,7 % je v intervalu $(-3, 3)$. | Výška lidí (ale přeškálovaná). | Cauchy |
|
||||
| $ f(x) = \frac{1}{ \pi \sigma \left\lbrack 1 + \left( \frac{x - \mu}{\sigma} \right)^2 \right\rbrack } $ | Poměr dvou spojitých náhodných proměnných s normálním rozdělením. Expected value ani rozptyl na ní nejsou definované. | Poměr výšky k šířce obličeje. | Gamma |
|
||||
| $ f(x, \alpha, \beta) = \begin{cases} \frac{\beta^\alpha}{\Gamma(\alpha)} x^{\alpha - 1} e^{-\beta x} & x > 0 \\ 0 & \text{jinak} \\ \end{cases} $ | Když máš sekvenci jevů, kde čekací doba na každý má exponenciální rozdělení s rate $\beta$, pak čekací doba na $n$-tý jev má Gamma rozdělení s $\alpha = n$. | Jak dlouho budeš čekat na $n$-tou šalinu. | $\chi^2$ (Chi-square) |
|
||||
| $ f(x, n) = \begin{cases} { \Large \frac{ x^{\frac{n}{2} - 1} e^{-\frac{x}{2}} }{ 2^\frac{n}{2} \Gamma\left( \frac{k}{2} \right) } } & x > 0 \\ 0 & \text{jinak} \\ \end{cases} $ | Používá se při testování hypotéz. Nechť $Z_1, Z_2, ..., Z_n$ jsou nezávislé náhodné proměnné se standardním normálním rozdělením a $X = \sum_{i=1}^n Z_i^2$, pak $X$ má $\chi^2$ rozdělení s $n$ stupni volnosti. | Testování, jestli je mince férová. | Studentovo $t$ |
|
||||
|
||||
### Číselné charakteristiky
|
||||
|
||||
Stejně jako náhodné veličiny popisují jevy, číselné charakteristiky popisují chování náhodných veličin... pomocí čísel.
|
||||
|
||||
#### Míry polohy
|
||||
|
||||
- **Střední hodnota / mean / expected value**\
|
||||
Průměr hodnot veličiny vážený jejich pravděpodobností. Značí se $\overline{X}$ nebo $E(X)$.
|
||||
|
||||
**📌 NOTE**\
|
||||
Taky někdy označovaný jako _obecný moment prvního řádu / první obecný moment_. [moment](#moment)
|
||||
|
||||
- **$\alpha$-kvantil $Q_\alpha$**\
|
||||
Dělí statický soubor na stejně velké části.
|
||||
- **Medián**\
|
||||
Prostřední prvek uspořádaného statistického souboru. Kvantil $Q_{0.5}$.
|
||||
|
||||
```math
|
||||
\tilde{x} = \begin{cases}
|
||||
x_{\frac{n+1}{2}} & \text{pro liché }n\\
|
||||
\frac{1}{2} (x_\frac{n}{2} + x_{\frac{n}{2} + 1}) & \text{pro sudé }n
|
||||
\end{cases}
|
||||
```
|
||||
|
||||
- **Percentil**\
|
||||
Výběrový kvantil ($p$-tý kvantil, kde $0 < p < 1$) $Q_p$.
|
||||
- **Modus**\
|
||||
Hodnota s největší četností.
|
||||
|
||||
#### Míry variability
|
||||
|
||||
Jak moc se od sebe prvky liší (nezávisle na konstantním posunutí)?
|
||||
|
||||
- **Rozpyl / variance**\
|
||||
Vyjadřuje, jak moc se NV odchyluje od své střední hodnoty. Značí se $\sigma^2$, $\text{var}(X)$ nebo $D(X)$.
|
||||
|
||||
```math
|
||||
\text{var}(X) = E\left((x_i - E(X))^2\right)
|
||||
```
|
||||
|
||||
**📌 NOTE**\
|
||||
Taky někdy označovaný jako _centrální moment druhého řádu / druhý centrální moment_. [moment](#moment)
|
||||
|
||||
- **Směrodatná odchylka / standard deviation**\
|
||||
Míra variability NV. Značí se $\sigma$ nebo $\text{SD}(X)$. Je definovaná jako $\sqrt{\sigma^2}$.
|
||||
- **ovariance veličin $X$ a $Y$**\
|
||||
Měří určitou podobnost mezi $X$ a $Y$.
|
||||
|
||||
```math
|
||||
\text{cov}(X, Y) = E((X - E(X)) \cdot (Y - E(Y)))
|
||||
```
|
||||
|
||||
Ze vzorce výše plyne
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
\text{cov}(X, X) &= \text{var}(X) \\
|
||||
\text{cov}(X, Y) &= \text{cov}(Y, X) \\
|
||||
\text{cov}(X, Y) &= E(X \cdot Y) - E(X) \cdot E(Y)
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
- **Korelace**\
|
||||
Míra podobnosti $\rho_{X, Y}$ náhodných veličin $X$ a $Y$. Pokud $X = X$, pak $\rho_{X, X} = 1$. Pokud jsou $X$ a $Y$ nezávislé, pak $\rho_{X, Y} = 0$.
|
||||
|
||||
```math
|
||||
\rho_{X, Y} = \frac{\text{cov}(X, Y)}{\sqrt{\text{var}(X)} \cdot \sqrt{\text{var}(Y)}}
|
||||
= \frac{E((X - E(X)) \cdot (Y - E(Y)))}{\sqrt{\text{var}(X)} \cdot \sqrt{\text{var}(Y)}}
|
||||
```
|
||||
|
||||
#### Míry tvaru
|
||||
|
||||
- **Koeficient šikmosti / skewness**\
|
||||
Vztah polohy meanu vůči mediánu. Vyjadřuje symetrii dat.
|
||||
- **Koeficient špičatosti / kurtosis**\
|
||||
Jak vysoký je peak? Jak moc je to rozpláclé.
|
||||
|
||||
## Centrální limitní věta (CLV) / Central limit theorem (CLT)
|
||||
|
||||
S rostoucím počtem sample výsledků $X_i$ se jejich distribuce blíží normálnímu rozdělení bez ohledu na jejich původní rozdělení.
|
||||
|
||||
Popisuje chování _výběrového průměru_ pro velké soubory vzorků a umožňuje tak sestrojení intervalových odhadů.
|
||||
|
||||
- **Moivreova-Laplacova věta**
|
||||
|
||||
Mějme NV $X$. Pokud je $X$ součtem $n$ vzájemně nezávislých NV $X_1, X_2, ..., X_n$ s Bernoulliho rozdělením s parametrem $\pi$, má $X$ binomické rozdělení s parametry $n$ a $\pi$, pak s $n \to \infty$:
|
||||
|
||||
```math
|
||||
\frac{X - n \pi}{\sqrt{n \pi (1 - \pi)}} \approx N(0, 1)
|
||||
```
|
||||
|
||||
- **Lévyho-Lindenbergova věta**
|
||||
|
||||
**💡 TIP**\
|
||||
Zobecnění Moivreovy-Laplacovy věty.
|
||||
|
||||
Mějme NV $X$. Pokud je $X$ součtem $n$ vzájemně nezávislých NV $X_1, X_2, ..., X_n$ se shodným rozdělením libovolného typu, s konečnou střední hodnotou $E(X_i) = \mu$ a konečným rozptylem $D(X_i) = \sigma^2$, pak pro normovanou NV $U$ asymptoticky s $n \to \infty$ platí:
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
|
||||
\overline{X} = \frac{1}{n} \sum_{i=1}^n X_i &\approx N \left( \mu, \frac{\sigma^2}{n} \right) \\
|
||||
|
||||
\sqrt{n} \frac{\overline{X} - \mu}{\sqrt{\sigma^2}} &\approx N(0, 1) \\
|
||||
|
||||
\frac{\sum_{i=1}^n X_i - n \mu}{\sqrt{n \sigma^2}} &\approx N(0, 1)
|
||||
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
**Výpočet s CLV**
|
||||
|
||||
Nechť $X$ je náhodná proměnná popisují jak padá 6, když hodíme kostkou 100krát. Tedy:
|
||||
|
||||
```math
|
||||
X \approx \text{Binomial} \left( 100, \frac{1}{6} \right)
|
||||
```
|
||||
|
||||
Podle CLV má $X$ asymptoticky $X \approx N(\frac{100}{6},\frac{500}{36})$.
|
||||
|
||||
Pak například pravděpodobnost, že šestka padne méně než 16krát je:
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
|
||||
P(X < 16) &\doteq P(X \leq 16) = 0.429 \\
|
||||
P(X < 16) = P(X \leq 15) &\doteq F(X \leq 15) = 0.327 \\
|
||||
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
S _continuity correction_ (opravou v důsledku změny z diskrétní na spojitou NV) je to:
|
||||
|
||||
```math
|
||||
P(X < 16) = P(X \leq 15.5) \doteq F(15.5) = 0.377
|
||||
```
|
||||
|
||||
## Odhady
|
||||
|
||||
- **Odhad parametru / parameter estimation**\
|
||||
Když se snažíš vymyslet, jaké asi hodnoty mají parametery té které distribuce mít, aby co nejlíp pasovala na tvoje samply.
|
||||
|
||||
Cílem odhadu je určit parametry rozdělení NV $X$ na základě informace z výběrového souboru (realizaci NV, datasetu). Chceme hodnotu a přesnost odhadu.
|
||||
|
||||
- **Metoda odhadu / estimator**\
|
||||
Popisuje, jak odhad získat.
|
||||
- **Nestranný odhad / unbiased estimator**\
|
||||
Metoda odhadu parametru $\theta$ taková, že střední hodnota odhadu je rovna $\theta$. Nestrannost je celkem rozumné omezení, protože nechceme, aby byl odhad odchýlený.
|
||||
- **Nejlepší nestranný odhad / best unbiased estimator**\
|
||||
Nestranný odhad, který má nejmenší rozptyl ze všech nestranných odhadů.
|
||||
- **Konzistentní odhad / consistent estimator**\
|
||||
Metoda odhadu parametru $\theta$ taková, že s počtem vzorků $n$ konverguje k $\theta$ pro $n \to \infty$. [consistent-estimator](#consistent-estimator)
|
||||
- **(Výběrová) statistika / (sample) statistic**\
|
||||
Náhodná veličina dána funkcí, která bere výběrový soubor a vrací číslo. Máme například:
|
||||
|
||||
- _Výběrový průměr / sample mean_,
|
||||
- _Výběrový rozptyl / sample variance_,
|
||||
- _Výběrovou směrodatnou odchylku / sample standard deviation_,
|
||||
- _Výběrovou (empirickou) distribuční funkci / sample distribution function_.
|
||||
|
||||
> Náhodná veličina $T_n$, která vznikne aplikací funkce $T$ na náhodný výběr o velikosti $n$ $\mathbf{X} = (X_1, X_2, \ldots, X_n)$ se nazývá statistika.
|
||||
>
|
||||
> ```math
|
||||
> T_n = T(X_1, X_2, \ldots, X_n)
|
||||
> ```
|
||||
|
||||
**💡 TIP**\
|
||||
_Estimator_ je funkce počítající statistiku použitá k odhadu parametru. [statistic](#statistic)
|
||||
|
||||
- **Bodový odhad / point estimate / pointwise estimate**\
|
||||
Odhad parametru daný **jednou hodnotou**, která hodnotu parametru aproximuje.
|
||||
- **Intervalový odhad / interval estimate**\
|
||||
Odhad parametru daný pomocí **intervalu hodnot**, který hodnotu parametru s velkou pravděpodobností obsahuje. Délka intervalu vypovídá o přesnosti odhadu.
|
||||
- **Interval spolehlivosti / confidence interval**\
|
||||
Interval spolehlivosti parametru $\theta$ s hladinou spolehlivosti $1 - \alpha$, kde $\alpha \in \lbrack 0, 1 \rbrack$ je dvojice statistik $\lbrack \theta_L, \theta_U \rbrack$ taková, že:
|
||||
|
||||
```math
|
||||
P(\theta_L < \theta < \theta_U) = 1 - \alpha
|
||||
```
|
||||
|
||||
kde $\theta_L$ je **dolní mez intervalu** a $\theta_U$ je **horní mez intervalu**.
|
||||
|
||||
- **Hladina významnosti a spolehlivosti / significance and confidence level**
|
||||
- Hladina významnosti $\alpha$ je pravděpodobnost, že parametr **nespadá** do intervalového odhadu.
|
||||
- Hladina spolehlivosti $1 - \alpha$ je pravděpodobnost, že parametr **spadá** do intervalového odhadu.
|
||||
- **Levostranný, pravostranný a oboustranný interval / left-tailed, right-tailed and two-tailed interval**
|
||||
- _Levostranný (dolní)_: $P(\theta \le \theta_L) = 1 - \alpha$.
|
||||
- _Pravostranný (horní)_: $P(\theta \ge \theta_U) = 1 - \alpha$.
|
||||
- _Oboustranný_: $P(\theta \le \theta_L) = P(\theta \ge \theta_U) = \frac{\alpha}{2}$.
|
||||
|
||||
**Tvorba intervalového odhadu**
|
||||
|
||||
Máme vzorek velikosti $n$ s výběrovým průměrem $\overline{X}$ a výběrovým rozptylem $S^2$. Odhadněte střední hodnotu $\mu$ s hladinou spolehlivosti 0.95, pokud víte, že $X \approx N(\mu, \sigma^2)$, kde rozptyl $\sigma^2$ je neznámý.
|
||||
|
||||
1. Zvolíme vhodnou výběrovou statistiku $T(X)$ jejíž rozdělení závislé na $\mu$ známe. V tomhle případě Studentův t-test:
|
||||
|
||||
```math
|
||||
T(X) = \frac{\overline{X} - \mu}{S / \sqrt{n}} \sim t_{n - 1}
|
||||
```
|
||||
|
||||
Tedy víme, že $T(X) \sim t(n-1)$
|
||||
|
||||
2. Určíme kvantily $t_\frac{\alpha}{2} = t_{0.025}$ a $t_{1 - \frac{\alpha}{2}} = t_{0.975}$ z $T(X)$:
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
|
||||
P(t_{0.025}(n - 1) < T(X) < t_{0.975}(n-1)) &= 1 - \alpha = 0.95 \\
|
||||
|
||||
t_{0.025}(n - 1) &= -t_{0.975}(n - 1) \\
|
||||
|
||||
P(t_{0.025}(n - 1) < T(X) < -t_{0.025}(n-1)) &= 0.95 \\
|
||||
|
||||
P(\overline{X} - t_{0.025}(n - 1) \frac{S}{\sqrt{n}} < \textcolor{red}{\mu} < \overline{X} + t_{0.025}(n - 1) \frac{S}{\sqrt{n}}) &= 0.95
|
||||
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
3. Vyčíslíme interval z poslední rovnice.
|
||||
|
||||
- **Věrohodnost / likelihood**
|
||||
|
||||
Říká, jak dobře náš model (rozdělení pravděpodobnosti náhodné veličiny dané parametry) sedí na naměřená data.
|
||||
|
||||
**📌 NOTE**\
|
||||
Pravděpodobnost je funkce jevů. Likelihood je funkce parametrů modelu.
|
||||
|
||||
**📌 NOTE**\
|
||||
Likelihood nemusí nutně vracet čísla z intervalu $\lbrack 0, 1 \rbrack$.
|
||||
|
||||
- **Maximum likelihood estimation (MLE)**\
|
||||
Metoda odhadu parametru založená na maximalizaci likelihoodu, že model sedí na naměřená data. [mle](#mle)
|
||||
- **Method of moments (MOM)**\
|
||||
Metoda odhadu parametru založená na rovnosti teoretického a výběrového momentu. [mom](#mom)
|
||||
|
||||
## Testování statistických hypotéz
|
||||
|
||||
- **Hypotéza**\
|
||||
Nějaký předpoklad o datech, který chceme ověřit. Často je formulovaná pomocí parametrů modelu. Např. _"střední hodnota je 5."_
|
||||
- **Testování hypotézy**\
|
||||
Cílem testování hypotéz je ověřit, že data **nepopírají** nějakou hypotézu.
|
||||
|
||||
- _Null hypothesis $H_0$_: "výchozí nastavení"; často tvrdí, že nějaká vlastnost neexistuje.
|
||||
- _Alternative hypothesis $H_1$_: "to co, chceme dokázat"; opak $H_0$.
|
||||
|
||||
Alternativní hypotézu _potvrzujeme_ tak, že _vyvracíme_ nulovou hypotézu. Pokud se nám nepodaří vyvrátit $H_0$, pak o $H_1$ nevíme nic. [null](#null)
|
||||
|
||||
> Na testování použijeme statistiku $T_n = T(\mathbf{X})$, kterou nazýváme **testovací statistikou**. Množinu hodnot, které může testovací statistika nabýt, rozdělíme na dvě disjunktní oblasti. Jednu označíme $W_\alpha$, a nazveme ji **kritickou oblastí** (nebo také _oblastí zamítnutí hypotézy_ (**region of rejection**, **critical region**)) a druhá je doplňkovou oblastí (oblast _nezamítnutí testované hypotézy_).
|
||||
>
|
||||
> Na základě realizace náhodného výběru $\mathbf{x} = (x_1, ..., x_n)'$ vypočítáme hodnotu testovací statistiky $t_n = T(\mathbf{x})$.
|
||||
>
|
||||
> - Pokud hodnota testovací statistiky $t_n$ nabude hodnoty z kritické oblasti, t.j. $t_n = T(\mathbf{x}) \in W_\alpha$, pak **nulovou hypotézu zamítáme**.
|
||||
> - Pokud hodnota testovací statistiky $t_n$ nabude hodnoty z oblasti nezamítnutí, t.j. $t_n = T(\mathbf{x}) \not\in W_\alpha$, pak **nulovou hypotézu nezamítáme**.
|
||||
>
|
||||
> — MV013
|
||||
|
||||
**Metafora se soudem**
|
||||
|
||||
Platí presumpce nevinny. Předpokládáme, že člověk zločin nespáchal, dokud tuhle hypotézu nevyvrátíme.
|
||||
|
||||
- _$H_0$_: "Obžalovaný **neukradl** papamobil."
|
||||
- _$H_1$_: "Obžalovaný **ukradl** papamobil."
|
||||
|
||||
- **Chyby v testování hypotéz**
|
||||
|
||||
- _Typ I_: zamítnutí $H_0$, i když je pravdivá -- _false positive_.
|
||||
- _Typ II_: nezamítnutí $H_0$, i když je nepravdivá -- _false negative_.
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
_Positive_ = zamítnutí $H_0$, tedy potvrzení $H_1$.
|
||||
|
||||
_Negative_ = nezamítnutí $H_0$, tedy o $H_1$ nevíme nic.
|
||||
</dd></dl>
|
||||
|
||||
- **$p$-hodnota (hladina významnosti)**\
|
||||
Nejmenší hladina významnosti $\alpha$, při které ještě zamítáme $H_0$. [p-value](#p-value)
|
||||
|
||||
Pravděpodobnost, že došlo k chybě typu I -- zavrhnuli jsme $H_0$, ačkoli platí.
|
||||
|
||||
stem:[
|
||||
p = P(\text{type I error}) = P(\text{we reject } H_0 \;|\; H_0)
|
||||
]
|
||||
|
||||
**💡 TIP**\
|
||||
Pokud $p$-value vyjde menší než požadovaná hladina významnosti $\alpha$, pak pravděpodobnost, že došlo k chybě typu I je dostatečně malá na to, abychom mohli tvrdit, že zavrhujeme $H_0$, protože $H_0$ neplatí, a tedy akceptujeme $H_1$.
|
||||
|
||||
### Parametrické testy
|
||||
|
||||
Parametrické testy jsou založené na parametrech pravděpodobnostních rozdělení.
|
||||
|
||||
- **Studentův T-test**\
|
||||
Umožňuje ověřit zda normální rozdělení má danou střední hodnotu. Taky umožňuje ověřit zda dvě normální rozdělení mají stejnou střední hodnotu, za předpokladu, že mají stejný (byť neznámý) rozptyl. [t-test](#t-test)
|
||||
- **Analysis of variance (ANOVA)**\
|
||||
Testuje rozdíly mezi středními hodnotami dvou a více skupin. Používá se k ověření, zda rozptyly dvou nebo více množin dat jsou stejné až na konstantní posun a škálování. [anova](#anova)
|
||||
|
||||
### Neparametrické testy
|
||||
|
||||
Neparametrické testy nejsou založené (jen) na parametrech pravděpodobnostních rozdělení. Používají se, když neznáme rozdělení dat, nebo je těžké splnit předpoklady parametrických testů.
|
||||
|
||||
- **Sign test**\
|
||||
Testuje, zda se dvě náhodné veličiny při pozorování liší konzistentně. Jinými slovy, zda stření hodnota jejich rozdílu má nulový medián.
|
||||
- **One-sample Wilcoxon signed-rank test**\
|
||||
Testuje, zda vzorky patří do symetrického rozdělení s daným mediánem.
|
||||
- **Pearsonův chi-squared ($\chi^2$) test**\
|
||||
Umožňuje ověřit, že dvě kategorické NV jsou nezávislé. [chi-squared](#chi-squared)
|
||||
|
||||
### Testy (ne)závislosti náhodných veličin
|
||||
|
||||
**Opakování**
|
||||
|
||||
- **Statistická / stochastická nezávislost**\
|
||||
Náhodné jevy $A$ a $B$ jsou stochasticky nezávislé, pokud $P(A \cap B) = P(A) \cdot P(B)$.
|
||||
|
||||
**Výskyt $A$ nemá vliv na výskyt $B$.**
|
||||
|
||||
- "Při při prvním hodu padne 6" a "při druhém hodu padne 6" jsou **nezávislé** jevy.
|
||||
- Naproti tomu jev, že padne 6 při prvním hodu kostkou a jev, že součet čísel zaznamenaných v prvním a druhém pokusu je 8, jsou **závislé** jevy. [nezavislost](#nezavislost)
|
||||
|
||||
- **Nezávislost diskrétních NV**
|
||||
|
||||
Pokud $X$, $Y$ a $Z$ jsou diskrétní náhodné veličiny, pak definujeme $X$ a $Y$ jako _podmíněně nezávislé_ vzhledem k $Z$, pokud:
|
||||
|
||||
```math
|
||||
P(X \le x, Y \le y | Z = z) = P(X \le x | Z = z) \cdot P(Y \le y | Z = z)
|
||||
```
|
||||
|
||||
pro všechny $x$, $y$ a $z$ takové, že $P(Z = z) > 0$.
|
||||
|
||||
- **Nezávislost spojitých NV**
|
||||
|
||||
Pokud $X$, $Y$ a $Z$ jsou spojité náhodné veličiny a mají společnou hustotu pravděpodobnosti $f_{XYZ}(x,y,z)$, pak definujeme $X$ a $Y$ jako _podmíněně nezávislé_ vzhledem k $Z$, pokud:
|
||||
|
||||
```math
|
||||
f_{X,Y|Z}(x,y|z) = f_{X|Z}(x|z) \cdot f_{Y|Z}(y|z)
|
||||
```
|
||||
|
||||
pro všechna $x$, $y$ a $z$ takové, že $f_Z(z) > 0$.
|
||||
|
||||
> To neformálně řečeno znamená, že jakmile máme k dispozici informaci obsaženou v Z, není už další informace A užitečná pro přesnější poznání B ani znalost B nepřidá nic pro pochopení A, i kdyby A a B byly vzájemně závislé.
|
||||
>
|
||||
> — Wikipedia: Statistická nezávislost
|
||||
|
||||
- **Regrese**\
|
||||
Analýza vztahu mezi dvěma závislými NV.
|
||||
- **Lineární regrese**\
|
||||
Regrese s předpokladem, že vztah dvě NV jsou závislé lineárně. Rovnici regresní přímky zapisujeme jako:
|
||||
|
||||
```math
|
||||
Y_i = \beta_0 + \beta_1 \cdot X_i + \varepsilon_i
|
||||
```
|
||||
|
||||
Kde:
|
||||
|
||||
- $Y$ je NV závislá na $X$,
|
||||
- $\beta_0$ je konstanta,
|
||||
- $\beta_1$ je směrnice (slope),
|
||||
- $\varepsilon_i$ je $i$-tá pozorovaná hodnota chyby -- náhodná složka / šum.
|
||||
|
||||
Platí:
|
||||
|
||||
- $E(\varepsilon_i) = 0$,
|
||||
- $D(\varepsilon_i) = \sigma^2$,
|
||||
- $\text{cov}(\varepsilon_i, \varepsilon_j) = 0$ pro $i \neq j$,
|
||||
- $\varepsilon_i \sim N(0, \sigma^2)$ -- náhodná složka má normální rozdělení,
|
||||
- regresní parametry $\beta_0$ a $\beta_1$ mohou mít libovolnou hodnotu.
|
||||
|
||||
- **Celkový F-test**\
|
||||
Pracuje s nulovou hypotézou ve tvaru:
|
||||
|
||||
```math
|
||||
H_0: \beta_1 = \beta_2 = \ldots = \beta_k = 0
|
||||
```
|
||||
|
||||
Tedy testujeme, zda hodnota analyzované NV závisí na lineární kombinaci vysvětlujících NV. Pokud je $H_0$ zamítnuta, pak alespoň jedna závislost existuje. Pokud je $H_0$ nezamítnuta, pak je množina vysvětlujících NV úplně blbě.
|
||||
|
||||
Testová statistika má F-rozdělení.
|
||||
|
||||
- **Dílčí t-testy**\
|
||||
Umožňují otestovat, že dává smysl použít $i$-tou vysvětlující NV. Testujeme nulovou hypotézu:
|
||||
|
||||
```math
|
||||
H_0: \beta_i = 0
|
||||
```
|
||||
|
||||
Pokud nelze zamítnout, pak $i$-tá vysvětlující NV nemá vliv na analyzovanou NV a můžeme ji vynechat.
|
||||
|
||||
Testová statistika má Studentovo t-rozdělení.
|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[statistics,1]]] [Wikipedia: Statistics](https://en.wikipedia.org/wiki/Statistics)
|
||||
- [[[nv,2]]] [Wikipedia: Náhodná veličina](https://cs.wikipedia.org/wiki/N%C3%A1hodn%C3%A1_veli%C4%8Dina)
|
||||
- [[[cdf,3]]] [Wikipedia: Cumulative distribution function](https://en.wikipedia.org/wiki/Cumulative_distribution_function)
|
||||
- [[[mean,4]]] [Wikipedia: Mean](https://en.wikipedia.org/wiki/Mean)
|
||||
- [[[clv,5]]] [Wikipedia: Centrální limitní věta](https://cs.wikipedia.org/wiki/Centr%C3%A1ln%C3%AD_limitn%C3%AD_v%C4%9Bta)
|
||||
- [[[consistent-estimator,6]]] [Wikipedia: Consistent estimator](https://en.wikipedia.org/wiki/Consistent_estimator)
|
||||
- [[[statistic, 7]]] [Wikipedia: Statistic](https://en.wikipedia.org/wiki/Statistic)
|
||||
- [[[mle, 8]]] [Wikipedia: Maximum likelihood estimation](https://en.wikipedia.org/wiki/Maximum_likelihood_estimation)
|
||||
- [[[mom, 9]]] [Wikipedia: Method of moments](<https://en.wikipedia.org/wiki/Method_of_moments_(statistics)>)
|
||||
- [[[null, 10]]] [Wikipedia: Null hypothesis](https://en.wikipedia.org/wiki/Null_hypothesis)
|
||||
- [[[p-value, 11]]] [Wikipedia: P-hodnota](https://cs.wikipedia.org/wiki/P-hodnota)
|
||||
- [[[mv013,12]]] [MV013 Statistics for Computer Science (jaro 2021)](https://is.muni.cz/auth/el/fi/jaro2021/MV013/)
|
||||
- [[[anova, 13]]] [Wikipedia: Analysis of variance](https://en.wikipedia.org/wiki/Analysis_of_variance)
|
||||
- [[[nezavislost,14]]] [Wikipedia: Statistická nezávislost](https://cs.wikipedia.org/wiki/Statistick%C3%A1_nez%C3%A1vislost)
|
||||
- [[[t-test, 15]]] [Wikipedia: T-test](https://cs.wikipedia.org/wiki/T-test)
|
||||
- [[[chi-squared,16]]] [Chi-square tests](https://www.scribbr.com/statistics/chi-square-tests/)
|
||||
- [[[moment, 17]]] [Momenty rozdělení](http://kfe.fjfi.cvut.cz/~limpouch/sigdat/pravdh/node10.html)
|
497
src/content/docs/szmgr/SZP04_3d_modelovani.md
Normal file
497
src/content/docs/szmgr/SZP04_3d_modelovani.md
Normal file
@ -0,0 +1,497 @@
|
||||
---
|
||||
title: "3D modelování a datové struktury"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Mnohoúhelníkové a trojúhelníkové sítě: datové struktury, modelování, pass:[<s>filtrování</s>], změna struktury sítě, **\*zjednodušování sítě\*\***. Implicitní **a parametrické\*** reprezentace a modelování **_(SDF, CSG, B-Rep)_**.
|
||||
|
||||
_PA010_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
## Mnohoúhelníkové a trojúhelníkové sítě
|
||||
|
||||
### Základní pojmy
|
||||
|
||||
- **Geometrie**
|
||||
- Mění jí deformace.
|
||||
- Např. to, kde jsou body.
|
||||
- Zahrnuje zakřivení (curvature), plochu (area), vzdálenosti mezi body, atd. [pa010-2021](#pa010-2021)
|
||||
- **Topologie**
|
||||
|
||||
- Nemění ji deformace.
|
||||
- Např. to jak jsou body propojené.
|
||||
- Sousednost (neighborhood), souvislost (connectedness), adjacency. atd. [pa010-2021](#pa010-2021)
|
||||
|
||||
**Topology [topology](#topology)**
|
||||
|
||||

|
||||
|
||||
- **Topological manifold**\
|
||||
Prostor/útvar, který lokálně _připomíná_ (je homeomorfní) $n$-dimenzionální Euklidovský prostor. [pa010-2021](#pa010-2021) [manifold-wiki](#manifold-wiki)
|
||||
|
||||
$n$-manifold je takový topologický manifold, kde okolí každého bodu je homeomorfní s $n$-dimenzionálním Euklidovským prostorem. [manifold-wiki](#manifold-wiki)
|
||||
|
||||
Manifoldy jsou typicky fyzikálně validní a efektivní (např. pomocí half-edge).
|
||||
|
||||
- Souřadnicový prostor $\mathbb{R}^n$ je $n$-manifold.
|
||||
- Libovolný diskrétní prostor je 0-manifold.
|
||||
- Kruh je 1-manifold.
|
||||
- Torus (donut) a Kleinova láhev je 2-manifold (povrch).
|
||||
- Každý povrch je 2-manifold až na neuzavřené hrany. [pa010-2021](#pa010-2021)
|
||||
- $n$-dimenzionální koule je $n$-manifold.
|
||||
|
||||

|
||||
|
||||
- **Orientability / orientace**
|
||||
|
||||
> - Orientable surfaces allow consistent definition of clockwise and counter-clockwise orientation.
|
||||
> - We can define front/back or inner/outer side.
|
||||
> - In non-orientable surfaces, the orientation can change after running through a surface loop.
|
||||
>
|
||||
> — PA010
|
||||
|
||||
**Möbiova páska a Kleinova láhev**
|
||||
|
||||
Möbiova páska je neorientovatelná, protože po oběhnutí pásu se změní orientace.
|
||||
|
||||
Kleinova láhev je orientovatelná, protože po oběhnutí láhve se orientace nezmění.
|
||||
|
||||

|
||||

|
||||
|
||||
- **Elementy topologie**
|
||||
- Vertices (vertexy / vrcholy) (V)
|
||||
- Edges (hrany) (E)
|
||||
- Faces (stěny) (F)
|
||||
- Genus (G)
|
||||
- Edge loops (L)
|
||||
- Boundary edge loops (rings, R)
|
||||
- Shells (S)
|
||||
- **Genus**
|
||||
|
||||
- Počet "děr" v povrchu.
|
||||
- Počet "držadel" v povrchu.
|
||||
- Počet skupin křivek, které nelze stáhnout do bodu.
|
||||
|
||||
> Genus of an orientable surface is the maximum number of cuttings along nonintersecting simple closed curves without separating it.
|
||||
>
|
||||
> — PA010
|
||||
|
||||
<dl><dt><strong>💡 TIP</strong></dt><dd>
|
||||
|
||||
Podle Wikipedie je _genus_ česky _rod plochy_.
|
||||
</dd></dl>
|
||||
|
||||
<dl><dt><strong>💡 TIP</strong></dt><dd>
|
||||
|
||||
Je to **maximální** počet těch řezů.
|
||||
|
||||
Následující povrch[genus](#genus) jde rozdělit podél červené křivky na dva, ale neuvažujeme ji, protože chceme **nejvyší možný** počet řezů, které povrch **nerozdělí**.
|
||||
|
||||

|
||||
</dd></dl>
|
||||
|
||||
- **Boundary edge loops / rings**\
|
||||
Edge loops uvnitř stěn, které nejsou vnějšími hranicemi objektu.
|
||||
|
||||
"Díry" ve stěnách, ale není to genus.
|
||||
|
||||
$R = L - F$
|
||||
|
||||

|
||||
|
||||
- **Shells (S)**\
|
||||
Spojené komponenty povrchu (množiny stěn).
|
||||
|
||||

|
||||
|
||||
- **Eulerova charakteristika / Euler-Poincaré formula**\
|
||||
Eulerova charakteristika $\chi$ popisuje topologický prostor či geometrický útvar $M$. Je to topologický invariant -- nezmění se jakkoli je tento útvar pozohýbán.
|
||||
|
||||
```math
|
||||
\chi(M) = V - E + F \text{ (bez děr)} \\
|
||||
\chi(M) = V - E + F - R = 2 \cdot (S - G) \text{ (s děrami)}
|
||||
```
|
||||
|
||||
<dl><dt><strong>❗ IMPORTANT</strong></dt><dd>
|
||||
|
||||
Pro libovolný mnohostěn (polyhedron) bez děr je $\chi = 2$.
|
||||
</dd></dl>
|
||||
|
||||
<dl><dt><strong>❗ IMPORTANT</strong></dt><dd>
|
||||
|
||||
Pro uzavřený 2-manifoldní trojúhelníkový mesh:
|
||||
|
||||
Každý trojúhelník má 3 hrany a každá hrana je sdílena dvěma trojúhelníky, takže $E = \frac{3}{2} F$.
|
||||
|
||||
**💡 TIP**\
|
||||
Intuitivně: pokud jsme neúsporní, pak máme tři hrany pro každý trojúhelník ($3F$), každou hranu ale "přilepíme" k nějakému dalšímu trojúhelníku, takže každou hranu máme zbytečně dvakrát ($2E$), proto $3F = 2E$, tedy $E = \frac{3}{2} F$.
|
||||
|
||||
Z Euler-Poincaré plyne, že
|
||||
|
||||
```math
|
||||
V = 2 + E - F = 2 + \frac{3}{2} F - F = 2 + \frac{1}{2} F \sim \frac{1}{2}
|
||||
```
|
||||
|
||||
- Tedy platí poměr $E:F:V = 3:2:1$.
|
||||
- Tedy průmeřný vertex degree (počet hran, které vycházejí z vertexu) je $2 \cdot \frac{E}{V} \sim 6$.
|
||||
|
||||
Každá hrana (ve 2-manifoldu) přispívá k degree právě dvou vertexů, protože někde začíná a končí.
|
||||
|
||||
Kdybychom sečetli degree všech vertexů, dostali bychom $2E$, proto $2E \sim 6V$.
|
||||
|
||||
</dd></dl>
|
||||
|
||||
- **Simplex**\
|
||||
Nejjednodušší polytop (generalizace mnohoúhelníku, mnohostěnu, atd.). Generalizace trojúhelníku v libovolné dimenzi:
|
||||
|
||||
- 0D -- bod
|
||||
- 1D -- úsečka
|
||||
- 2D -- trojúhelník
|
||||
- 3D -- tetraedr
|
||||
- 4D -- 5-cell (5nadstěn)
|
||||
|
||||
### Datové struktury
|
||||
|
||||
- **Seznam trojúhelníků / list of triangles (polygon soup)**\
|
||||
Jednoduchý, ale obsahuje redundantní informace. Neříká nic o sousednosti.
|
||||
- **Indexed face set**\
|
||||
Vrcholy trojúhelníků jsou dány pomocí indexů do pole vertexů. Méně redundantní, ale neříká nic o sousednosti.
|
||||
- **Adjacency matrix**\
|
||||
Matice vertexů říkající, zda-li je mezi vertexy hrana. Nijak nereprezentuje faces.
|
||||
|
||||

|
||||
|
||||
- **Corner table / tabulka rohů**\
|
||||
Pro každý vertex udává sousední rohy. Fajn, pokud nás zajímá sousednost vertexů. Trochu redundantní. Použitelná jen pro trojúhelníkové sítě.
|
||||
|
||||
- $c.v$ -- vertex rohu,
|
||||
- $c.t$ -- trojúhelník rohu,
|
||||
- $c.n$ -- následující roh trojúhelníku,
|
||||
- $c.p$ -- předchozí roh trojúhelníku,
|
||||
- $c.o$ -- opačný roh v sousedním trojúhelníku (opačný roh kdyby to byl quad).
|
||||
- $c.r$ -- "pravý" roh v sousedním trojúhelníku,
|
||||
- $c.l$ -- "levý" roh v sousedním trojúhelníku.
|
||||
|
||||

|
||||
|
||||
- **Half-edge data structure**\
|
||||
Použitelná pro 2-manifoldy. Poskytuje rychlé hledání sousednosti. Umožňuje efektivní modifikace meshů.
|
||||
|
||||
```csharp
|
||||
record HalfEdge // e.g. e
|
||||
{
|
||||
Vertex Start { get; set; } // e.g. A
|
||||
// NB: End is optional since you can easily access Twin.Start.
|
||||
Vertex End { get; set; } // e.g. B
|
||||
HalfEdge Twin { get; set; }
|
||||
|
||||
HalfEdge Next { get; set; }
|
||||
// NB: Prev is optional since you can easily access Next.Next.
|
||||
HalfEdge Prev { get; set; }
|
||||
Face Face { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Modelování
|
||||
|
||||
**❗ IMPORTANT**\
|
||||
Tahle sekce má docela průnik s otázkou [Modelování 3D postav](../modelovani-3d-postav/).
|
||||
|
||||
- **Boundary representation model (B-rep)**\
|
||||
Modelování objektů pomocí jejich hranic -- boundaries (hrany, stěny, atd.).
|
||||
- **Polygonální síť / mesh**\
|
||||
Síť trojúhelníků. Hrany jsou vždy rovné. Potřebuje velké množství polygonů na hladké povrchy.
|
||||
- **B-spline plochy**\
|
||||
Vertexy řídící sítě slouží k aproximaci křivek. Nedokáže popsat libovolnou topologii.
|
||||
- **Topologická validita**
|
||||
- B-rep model splňuje Euler-Poincaré formuli. (Což neimplikuje, že je 2-manifold.)
|
||||
- Sousedící faces mají stejnou orientaci.
|
||||
- Žádné faces "nevisí" ven z modelu.
|
||||
- **Geometrická validita**\
|
||||
Numerické chyby v geometrii (např. v pozicích vertexů) mohou způsobit konflikty mezi topologickou a geometrickou informací. [pa010-2021](#pa010-2021)
|
||||
|
||||
_Např.: Rovnice rovin tvrdí, že hrana je uvnitř objektu, ale topologie říká, že je mimo něj._
|
||||
|
||||
- **Eulerovy operátory**\
|
||||
Operátory zachovávající Euler-Poincaré formuli. Jsou dostatečné pro konstrukci užitečných meshů. Pracují s 6 parametry: $V$ -- vertices, $E$ -- edges, $F$ -- faces, $H$ -- components, $S$ -- shells, $G$ -- genus. [pa010-2021](#pa010-2021) [boundaries](#boundaries)
|
||||
|
||||
**📌 NOTE**\
|
||||
Zdá se, že $H$ -- components je ekvivalentní $R$ -- rings.
|
||||
|
||||
Ač Eulerových operátorů se dá zadefinovat mnoho, v praxi stačí:
|
||||
|
||||
|====
|
||||
| Operátor
|
||||
| Popis
|
||||
|
||||
| `MSFV`
|
||||
| make shell, face, vertex
|
||||
|
||||
| `MEV`
|
||||
| make edge, vertex
|
||||
|
||||
| `MFE`
|
||||
| make face, edge
|
||||
|
||||
| `MSH`
|
||||
| make shell, hole
|
||||
|
||||
| `MEKL`
|
||||
| make edge, kill loop
|
||||
|
||||
2+|
|
||||
|
||||
| `KEV`
|
||||
| kill edge, vertex
|
||||
|
||||
| `KFE`
|
||||
| kill face, edge
|
||||
|
||||
| `KSFV`
|
||||
| kill shell, face, vertex
|
||||
|
||||
| `KSH`
|
||||
| kill shell, hole
|
||||
|
||||
| `KEML`
|
||||
| kill edge, make loop
|
||||
|====
|
||||
|
||||
- **Regularizované booleovské operátory / regularized boolean operators**\
|
||||
Reprezentace těles pomocí booleovských operací. _Regularizované_ značí, že výsledek je vždy platné 2-manifold těleso.
|
||||
|
||||
- `AND` - průnik $\cap^*$
|
||||
- `OR` - sjednocení $\cup^*$
|
||||
- `SUB` - rozdíl $\setminus^*$
|
||||
|
||||
Regularizace vypadá tak, že nejprve je provedena booleovská operace, poté je vypočítán _interior_ a následně _closure_. [rbo](#rbo)
|
||||
|
||||
- _Interior point_ $p$ tělesa $S$ je takový bod, že existuje $r$ takové, že otevřená koule s poloměrem $r$ a středem v $p$ obsahuje jen body z $S$.
|
||||
- _Exterior point_ $p$ tělesa $S$ je takový bod, že existuje $r$ takové, že otevřená koule s poloměrem $r$ a střem v $p$ **nemá žádný průnik** s $S$.
|
||||
- _Interior_ tělesa $S$ je množina všech jeho interior pointů.
|
||||
- _Exterior_ tělesa $S$ je množina všech jeho exterior pointů.
|
||||
- _Boundary_ tělesa $S$ je množina bodů, které nejsou ani interior ani exterior tělesa $S$.
|
||||
- _Clusure_ tělesa $S$ je sjednocení jeho interior a boundary.
|
||||
|
||||
_Otevřená koule_ je koule bez povrchu. Tedy právě ty body, které jsou jejím "vnitřkem".
|
||||
|
||||
**Schéma interior and a boundary tělesa $A \cap B$ [pa010-2021](#pa010-2021)**
|
||||
|
||||

|
||||
|
||||
**Příklad regularizovaného průniku [pa010-2021](#pa010-2021)**
|
||||
|
||||

|
||||
|
||||
- **Global deformations (Alan Barr)**\
|
||||
Mění tvar celého meshe. Obvykle jednoduché a snadno implementovatelné. Jsou fajn při modelování.
|
||||
|
||||
- _Translace_,
|
||||
- _Rotace_,
|
||||
- _Škálování / scale_,
|
||||
- _Zkosení / shear_,
|
||||
- _Tapering / zúžení_ -- nekonstantní škálování,
|
||||
|
||||
**Tapering in [3ds Max](https://help.autodesk.com/view/3DSMAX/2016/ENU/?guid=GUID-51233298-312D-4773-AD22-ADB08E70CCE1)**
|
||||
|
||||

|
||||
|
||||
- _Twisting / screw / šroubování_ -- nekonstantní rotace okolo osy,
|
||||
|
||||
**Twisting in [3ds Max](https://help.autodesk.com/view/3DSMAX/2022/ENU/?guid=GUID-0AD7CE08-9992-4E49-BA11-672DEA3B13CF)**
|
||||
|
||||

|
||||
|
||||
- _Bending / ohýbání_ -- ohnutí rozsahu vertexů okolo daného bodu o daný úhel.
|
||||
|
||||
**Bending in [Blender](https://docs.blender.org/manual/en/latest/modeling/meshes/editing/mesh/transform/bend.html)**
|
||||
|
||||

|
||||
|
||||
- **Free-form deformations (FFD)**\
|
||||
Lokální deformace vertexů v dané "kleci" / mřížce / lattice -- Bezierově objemu.
|
||||
|
||||
1. Vyrob FFD mřížku (Bezierův objem).
|
||||
2. "Umísti" do objemu objekt, který chceš deformovat.
|
||||
3. Deformuj mřížku (hýbej s jejími body).
|
||||
4. Transformuj vertexy v mřížce podle změn v FFD prostoru.
|
||||
|
||||

|
||||
|
||||
Má řadu rozšíření s různými tvary mřížky.
|
||||
|
||||
### Změna struktury sítě
|
||||
|
||||
**❗ IMPORTANT**\
|
||||
Modifikace meshů mají značný přesah do otázky [Křivky a povrchy](../krivky-a-povrchy/) a taky [Pokročilá počítačová grafika](../pokrocila-pocitacova-grafika/)
|
||||
|
||||
- **Překlápění hrany / edge flip**\
|
||||
Lokální změna, která nahradí hranu $(b,c)$ hranou $(a,d)$. Trojúhelníky $(a,b,c)$ a $(b,d,c)$ se stanou $(a,d,c)$ a $(a,b,d)$. [pa010-2021](#pa010-2021)
|
||||
|
||||

|
||||
|
||||
- **Rozdělení hrany / edge split**\
|
||||
Lokální změna přidávající další vertex a hrany mezi dva trojúhelníky, které tak rozdělí na čtyři. [pa010-2021](#pa010-2021)
|
||||
|
||||

|
||||
|
||||
- **Zhroucení grany / edge collapse**\
|
||||
Lokální změna, která nahrazuje hranu vrcholem. [pa010-2021](#pa010-2021)
|
||||
|
||||

|
||||
|
||||
- **Upsampling / subdivision**\
|
||||
Globální změna, která rozdělí jedno primitivum (trojúhelník / quad) na více. Vyhlazuje mesh dělením na menší kousky. [pa010-2021](#pa010-2021)
|
||||
|
||||

|
||||
|
||||
- **Downsampling / decimation / simplification**\
|
||||
Globální redukce množství primitiv. Často využívá edge collapse.
|
||||
- **Regularization / mesh resampling**\
|
||||
Globální upráva s cílem zlepšit kvalitu meshe, např.: tvar trojúhelníků a četnost vertexů. [pa010-2021](#pa010-2021)
|
||||
|
||||

|
||||
|
||||
- **Isotropic remeshing**\
|
||||
Algoritmus pro regularizaci meshů. Opakuje čtyři kroky:
|
||||
|
||||
1. Rozděl hrany delší než $4 / 3$ průměrné délky.
|
||||
2. Zhruť hrany kratší než $4 / 5$ průměrné délky.
|
||||
3. Překlop hrany, pokud to zlepší stupeň vrcholu (ideální je 6).
|
||||
4. Vycentruj vrcholy.
|
||||
|
||||
Zlepšuje rychlost některých algoritmů, eliminuje podlouhlé trojúhelníky, které se blbě renderují, zlepšuje subdivision, ale nejde použít vždy a může vést ke ztrátě detailů (řeší _Adaptive remeshing_). [pa010-2021](#pa010-2021)
|
||||
|
||||

|
||||
|
||||
## Implicitní reprezentace a modelování
|
||||
|
||||
_Když máme objekt definovaný polévkou matematických symbolů místo hromádky trojúhelníků._ Jinými slovy máme jednu nebo více reálných funkcí, které klasifikují body v prostoru.
|
||||
|
||||
- **Rovina**\
|
||||
Dána bodem $p$ a normálou $N$, ohraničuje poloprostor. Vzdálenost bodu od roviny je dána (za předpokladu, že $N$ je normalizovaná):
|
||||
|
||||
```math
|
||||
f(x) = (x - p) \cdot N
|
||||
```
|
||||
|
||||
- **Kvadriky / kvadratické plochy**
|
||||
|
||||
- _Elipsoid_ (třeba koule): $\frac{x^2}{a^2} + \frac{y^2}{b^2} + \frac{z^2}{c^2} = 1$,
|
||||
|
||||
**An ellipsoid by [Sam Derbyshire](https://commons.wikimedia.org/w/index.php?curid=18447750)**
|
||||
|
||||

|
||||
|
||||
- _Hyperboloid_ (třeba kužel): $\frac{x^2}{a^2} + \frac{y^2}{b^2} - \frac{z^2}{c^2} = 1$,
|
||||
|
||||
**A one-sheeted hyperboloid by [Sam Derbyshire](https://commons.wikimedia.org/w/index.php?curid=18447776)**
|
||||
|
||||

|
||||
|
||||
- _Válec (cylinder)_: $\frac{x^2}{a^2} + \frac{y^2}{b^2} = 1$,
|
||||
|
||||
**A cylinder by [Sam Derbyshire](https://commons.wikimedia.org/w/index.php?curid=18447784)**
|
||||
|
||||

|
||||
|
||||
- _Paraboloid_ (třeba miska): $\frac{x^2}{a^2} + \frac{y^2}{b^2} - z = 0$,
|
||||
|
||||
**A paraboloid by [Sam Derbyshire](https://commons.wikimedia.org/w/index.php?curid=18447777)**
|
||||
|
||||

|
||||
|
||||
- **Kvartiky / kvartické plochy**
|
||||
|
||||
- _Torus_ (donut): $\left( \sqrt{x^2 + y^2} - R \right)^2 + z^2 - r^2 = 0$.
|
||||
|
||||
**[A torus](https://commons.wikimedia.org/w/index.php?curid=979546)**
|
||||
|
||||

|
||||
|
||||
- **Distance surfaces**\
|
||||
Tělesa lze definovat pomocí vzdálenosti od jiných entit:
|
||||
|
||||
- _Sphere_: $d(x, \text{point}) = r$,
|
||||
- _Cylinder / capsule_: $d(x, \text{line}) = r$,
|
||||
- _Torus_: $d(x, \text{circle}) = r$,
|
||||
- _Generalized cylinder_: $d(x, \text{curve}) = r$,
|
||||
- _Offset surface_: $d(x, \text{surface}) = r$.
|
||||
|
||||
kde $d(x, A)$ je nejmenší vzdálenost bodu $x$ od entity $A$. [pa010-2020](#pa010-2020)
|
||||
|
||||
- **Constructive solid geometry (CSG)**\
|
||||
Umožňuje kombinovat implicitní objekty pomocí logických operací. Předpokládáme, že pokud $f(x, y, z) < 0$ pak je bod uvnitř objektu daném $f$. Tato metoda nezachovává $C^1$ spojitost. Pro dva objekty $f$ a $g$: [pa010-2020](#pa010-2020)
|
||||
|
||||
- _Sjednocení_: $\min(f, g)$,
|
||||
- _Průnik_: $\max(f, g)$,
|
||||
- _Rozdíl_: $\max(f, -g)$.
|
||||
- _Komplement_: $-f$.
|
||||
|
||||
- **Bloby (kapky)**\
|
||||
Součet několika Gaussových křivek. [pa010-2020](#pa010-2020)
|
||||
|
||||
```math
|
||||
\begin{align*}
|
||||
|
||||
r_i^2 (x,y,z) &= (x-x_i)^2 + (y-y_i)^2 + (z-z_i)^2 \\
|
||||
f(x,y,z) &= -1 + \sum_i \exp \left( -B_i \cdot \frac{r_i^2 (x,y,z)}{R_i^2} + B_i \right) \\
|
||||
f(x,y,z) &= -1 + \sum_i D(r_i)
|
||||
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
kde:
|
||||
|
||||
- $B_i$ je "blobbiness",
|
||||
- $R_i$ je poloměr blobu v klidu,
|
||||
- $D(r_i)$ je Gaussova křivka,
|
||||
- $r_i$ je funkce poloměru kapky.
|
||||
|
||||

|
||||
|
||||
- **Metaballs**\
|
||||
Podobné blobům, ale nepoužívá exponenciální funkci. Organicky se "slévající" koule. [pa010-2020](#pa010-2020)
|
||||
|
||||
```math
|
||||
\begin{align*}
|
||||
|
||||
D(r_i)= \begin{cases}
|
||||
|
||||
\alpha \left( 1 - \frac{3r_i^2}{R_i^2} \right)
|
||||
& 0 \leq r_i \leq R_i/3 \\
|
||||
|
||||
\frac{3\alpha}{2} \left( 1 - \frac{r_i}{R_i} \right) ^2
|
||||
& R_i/3 \leq r_i \leq R_i \\
|
||||
|
||||
0
|
||||
& R_i \leq r_i
|
||||
|
||||
\end{cases}
|
||||
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
**Metaballs by [SharkD](https://commons.wikimedia.org/w/index.php?curid=5237220)**
|
||||
|
||||

|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[pa010-2021,1]]] Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021)
|
||||
- [[[pa010-2020,2]]] Sochor: PA010 Intermediate Computer Graphics (podzim 2020)
|
||||
- [[[notes-pa010,3]]] [Moje poznámky z PA010 (podzim 2020)](/fi/pa010/)
|
||||
- [[[manifold-wiki,4]]] [Wikipedia: Topological manifold](https://en.wikipedia.org/wiki/Topological_manifold)
|
||||
- [[[klein-bottle,5]]] [Konrad Polthier: Imaging maths - Inside the Klein bottle ](https://plus.maths.org/content/imaging-maths-inside-klein-bottle)
|
||||
- [[[genus,6]]] [Saul Schleimer: Notes on the complex of curves](https://www.researchgate.net/publication/228393582_Notes_on_the_complex_of_curves)
|
||||
- [[[topology, 7]]] [Topology vs. Geometry](https://www.austincc.edu/herbling/shape-of-space.pdf)
|
||||
- [[[boundaries, 8]]] [Ian Stroud: Boundary Representation Modelling Techniques](https://link.springer.com/book/10.1007/978-1-84628-616-2)
|
||||
- [[[rbo, 9]]] [Interior, Exterior and Closure](https://pages.mtu.edu/~shene/COURSES/cs3621/NOTES/model/closure.html)
|
||||
- [[[validity,10]]] [Representational validity of boundary representation models](https://www.sciencedirect.com/science/article/pii/S0010448500000476)
|
||||
- [[[denoising,11]]] [Bilateral Normal Filtering for Mesh Denoising](https://ieeexplore.ieee.org/document/5674028)
|
688
src/content/docs/szmgr/SZP05_krivky_a_povrchy.md
Normal file
688
src/content/docs/szmgr/SZP05_krivky_a_povrchy.md
Normal file
@ -0,0 +1,688 @@
|
||||
---
|
||||
title: "Křivky a povrchy"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Implicitní a parametrické reprezentace. Interpolace a aproximace. Cn, Gn spojitost, podmínky spojitosti pro po částech definované funkce. Bézierovy křivky, B-spline křivky, pass:[<s>NURBS, </s>]Coonsovy pass:[<s>křivky a </s>]pláty. Povrchy tvořené rekurzivním dělením polygonů.
|
||||
|
||||
_PB009, PA010_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
## Druhy reprezentace
|
||||
|
||||
Jak povrchy tak křivky mohou být reprezentovány třemi způsoby:
|
||||
|
||||
### Explicitní reprezentace
|
||||
|
||||
Křivka nebo povrch je vyjádřen pomocí **funkce**.
|
||||
|
||||
```math
|
||||
\begin{align*}
|
||||
|
||||
y &= f(x) & \text{ pro křivku} \\
|
||||
z &= f(x, y) & \text{ pro povrch}
|
||||
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
Omezení na funkce je však příliš silné. Spoustu pěkných křivek a povrchů nelze vyjádřit pomocí jediné funkce.
|
||||
|
||||
### Implicitní reprezentace
|
||||
|
||||
Máme k dispozici rovnici ve tvaru:
|
||||
|
||||
```math
|
||||
\begin{align*}
|
||||
|
||||
F(x, y) &= c & \text{ pro křivku} \\
|
||||
F(x, y, z) &= c & \text{ pro povrch}
|
||||
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
kde $c$ je konstanta a je obvykle rovná 0.
|
||||
|
||||
Tato rovnice udává množinu bodů, ze které se křivka nebo povrch sestává. Takové množině se někdy říká _level set_ a metodám, které s nimi pracují _level-set methods_.
|
||||
|
||||
**❗ IMPORTANT**\
|
||||
Výhodou implicitně zadaných ploch je kompaktnější reprezentace a jednodušší ray casting. Nicméně výpočty s nimi jsou časově náročné, takže se stejně nejdřív převádí na polygonové meshe -- _polygonizace_.
|
||||
|
||||
**❗ IMPORTANT**\
|
||||
Tahle sekce přesahuje do [3D modelování a datové struktury](../3d-modelovani-a-datove-struktury/) -> _Implicitní reprezentace a modelování_.
|
||||
|
||||
### Parametrická reprezentace
|
||||
|
||||
Udává **dráhu** pohybujícího se bodu, či něco jako **hladinu** povrchu. Snadno se z ní vyjadřuje tečna, čehož se využívá při jejich skládání.
|
||||
|
||||
Pro křivky:
|
||||
|
||||
```math
|
||||
\begin{align*}
|
||||
|
||||
Q(t) &= \lbrack x(t), y(t), z(t) \rbrack & \text{ (bodová rovnice křivky)} \\
|
||||
\vec{q}(t) &= (x(t), y(t), z(t)) & \text{ (vektorová rovnice křivky)}
|
||||
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
kde $t$ je "čas" z intervalu $\lbrack t_\text{min}, t_\text{max} \rbrack$, nejčastěji $\lbrack 0, 1 \rbrack$. Výhodné je, že takto zadaná křivka se může sama křížit, uzavírat, a podobně.
|
||||
|
||||
Analogicky pro povrchy:
|
||||
|
||||
```math
|
||||
Q(u, v) = \lbrack x(u, v), y(u, v), z(u, v) \rbrack
|
||||
```
|
||||
|
||||
kde pro $u$ a $v$ už metafora s časem nefunguje. Obvykle obě náleží do intervalu $\lbrack 0, 1 \rbrack$.
|
||||
|
||||
## Terminologie
|
||||
|
||||
Pro zbytek otázky je podstatné znát několik termínů:
|
||||
|
||||
- **Dotykový / tečný / tangent vektor křivky**\
|
||||
Aktuální směr křivky v daném bodě. Z parametricky vyjádřené křivky $\vec{q}$ ho lze v čase $t_0$ získat jako derivaci:
|
||||
|
||||
```math
|
||||
\vec{q}'(t_0) = \left(
|
||||
\frac{\partial x(t_0)}{\partial t},
|
||||
\frac{\partial y(t_0)}{\partial t},
|
||||
\frac{\partial z(t_0)}{\partial t}
|
||||
\right)
|
||||
```
|
||||
|
||||
Rovnice tečny $\vec{p}$ je pak $\vec{p}(u) = \vec{q}(t_0) + \vec{q}'(t_0) \cdot u$.
|
||||
|
||||
- **Polynomiální křivka**\
|
||||
Velmi častý druh křivek v počítačové grafice. Vypadají jako:
|
||||
|
||||
```math
|
||||
Q_n(t) = a_0 + a_1 \cdot t + a_2 \cdot t^2 + \ldots + a_n \cdot t^n
|
||||
```
|
||||
|
||||
Je velmi snadné je evaluovat a derivovat. Z nich často skládáme křivky po částech.
|
||||
|
||||
- **Kubika**\
|
||||
Polynomiální křivka třetího stupně.
|
||||
|
||||
Parametricky:
|
||||
|
||||
```math
|
||||
\begin{align*}
|
||||
|
||||
x(t) = a_{x}t^{3} + b_{x}t^{2} + c_{x}t + d_{x} \\
|
||||
y(t) = a_{y}t^{3} + b_{y}t^{2} + c_{y}t + d_{y} \\
|
||||
z(t) = a_{z}t^{3} + b_{z}t^{2} + c_{z}t + d_{z}
|
||||
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
Zapsáno pomocí matice:
|
||||
|
||||
```math
|
||||
Q(t) = T \cdot C = \lbrack t^3, t^2, t, 1 \rbrack \cdot \begin{bmatrix}
|
||||
a_x & a_y & a_z \\
|
||||
b_x & b_y & b_z \\
|
||||
c_x & c_y & c_z \\
|
||||
d_x & d_y & d_z
|
||||
\end{bmatrix}
|
||||
```
|
||||
|
||||
Tečný vektor $\vec{q'}$ je pak:
|
||||
|
||||
```math
|
||||
\vec{q'}(t) = \frac{\partial}{\partial t} \cdot C = \lbrack 3t^2, 2t, 1, 0 \rbrack \cdot C
|
||||
```
|
||||
|
||||
U kubik platí, že $C = M \cdot G$, kde $M$ je bázová matice a $G$ je vektor geometrických podmínek.
|
||||
|
||||
- $T \cdot M$ definuje polynomiální bázi -- skupinu polynomů -- která je společná pro všechny křivky určitého typu.
|
||||
- $G$ pak obsahuje parametry konkrétní křivky -- řídící a dotykové body.
|
||||
- $t$ udává, jestli jsme na začátku či konci křivky.
|
||||
|
||||
- **Tečná rovina**\
|
||||
Rovina, která se povrchu dotýká v konkrétním bodě a její normála je na povrch kolmá. Pro parametrickou plochu $Q$ je tečná plocha $T$ dána jako:
|
||||
|
||||
```math
|
||||
\begin{align*}
|
||||
|
||||
\vec{q_{u}}(u,v) &= \frac{\partial Q(u,v)}{\partial u}
|
||||
= \left(
|
||||
\frac{\partial x(u,v)}{\partial u},
|
||||
\frac{\partial y(u,v)}{\partial u},
|
||||
{\partial z(u,v) \over \partial u}
|
||||
\right) \\
|
||||
|
||||
\vec{q_{v}}(u,v) &= \frac{\partial Q(u,v)}{\partial v}
|
||||
= \left(
|
||||
\frac{\partial x(u,v)}{\partial v},
|
||||
\frac{\partial y(u,v)}{\partial v},
|
||||
{\partial z(u,v) \over \partial v}
|
||||
\right) \\
|
||||
|
||||
T(r,s) &= Q(u,v) + r.\vec{q_{u}} + s.\vec{q_{v}}, \quad r,s \in \mathbb{R}
|
||||
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
kde $\vec{q_u}$ je tečný vektor ve směru parametru $u$, a analogicky $\vec{q_v}$
|
||||
|
||||
- **Normála / kolmice**\
|
||||
Normálu $\vec{n}$ parametricky dané plochy $Q$ určíme jako vektorový součin tečných vektorů:
|
||||
|
||||
```math
|
||||
\vec{n} = \frac{\vec{q_u} \times \vec{q_v}}{\left\lVert \vec{q_u} \times \vec{q_v} \right\rVert}
|
||||
```
|
||||
|
||||
- **Gradient**\
|
||||
Funkce, která vrací "směr a velikost největšího růstu". Nejčastěji se používá u povrchů k určení normály, ale lze ji použít v libovolné dimenzi k různým účelům. Pokud je povrch $f$ zadán implicitně, pak je gradient:
|
||||
|
||||
```math
|
||||
\nabla f = \left(
|
||||
\frac{\partial f}{\partial x},
|
||||
\frac{\partial f}{\partial y},
|
||||
\frac{\partial f}{\partial z}
|
||||
\right)
|
||||
```
|
||||
|
||||
## Interpolace a aproximace
|
||||
|
||||
- **Interpolace**\
|
||||
Prokládání daných bodů křivkou. Konstrukce křivky, která interpolovanými body prochází.
|
||||
|
||||
V případě kubiky výše to znamená, že $G$ obsahuje body, kterými křivka prochází.
|
||||
|
||||
Mějmě funkci $f(x)$, jejíž hodnotu známe v bodech $f(x_0), f(x_1), \ldots, f(x_n)$. Interpolace znamená nalezení hodnot $f(x)$ pro všechna $x_0 < x < x_n$.
|
||||
|
||||
- **Aproximace**\
|
||||
Přiblížení, odhad. Je nepřesným popisem nějaké jiné entity (např. čísla či funkce). Saháme k ní, pokud pro analytické řešení nemáme dost informací nebo výpočetní kapacity. Aproximace je méně přesná než interpolace, ale výpočetně jednodušší.
|
||||
|
||||
V případě kubiky výše to znamená, že $G$ obsahuje _řídící_ body, které sice udávají směr křivky, ale ta jimi neprochází.
|
||||
|
||||
## Spojitost
|
||||
|
||||
Představme si, že máme dva segmenty křivky: $Q_1$ a $Q_2$, spojené v bodě $t$, tedy $Q_1(t) = Q_2(t)$. Tento bod nazýváme _uzlem_ (knot). _Spojitost_ je zjednodušeně způsob, jakým jsou tyhle segmenty spojeny v uzlu.
|
||||
|
||||
### Parametrická spojitost stupně stem:[n] (stem:[C^n])
|
||||
|
||||
Křivka $Q$ patří do třídy $C^n$, pokud má ve všech bodech $t$ spojitou derivaci až do řádu $n$.
|
||||
|
||||
- $C^0$ -- dva segmenty jsou spojené; konečný bod jednoho segmentu je počátečním bodem druhého.
|
||||
- $C^1$ -- platí $C^0$ a navíc je tečný vektor na konci prvního segmentu shodný s tečným vektorem na začátku druhého segmentu -- první derivace v uzlu jsou si rovny.
|
||||
- $C^2$ -- platí $C^1$ a druhé derivace v uzlu jsou si rovny.
|
||||
- $C^n$ -- platí $C^{n-1}$ a navíc jsou si $n$-té derivace v uzlu rovny.
|
||||
|
||||
- Bod pohybující se po $C^0$-spojité dráze sebou "trhne" **v prostoru**, když projde uzlem.
|
||||
- V případě $C^1$ křivky se při průchodu uzlem směr ani rychlost prudce **nezmění**, může se však změnit zrychlení.
|
||||
- V případě $C^2$ křivky se při průchodu uzlem **nezmění** už ani zrychlení.
|
||||
|
||||
### Geometrická spojitost stupně stem:[n] (stem:[G^n])
|
||||
|
||||
Je podobná parametrické spojitosti, ale vyžaduje jen "geometrickou" spojitost. Vyžaduje, aby si derivace byly **sobě úměrné**. [mallinus](#mallinus) [geometric-continuity](#geometric-continuity)
|
||||
|
||||
- $G^0$ -- koncový bod prvního segmentu je totožný s počátečním bodem druhého segmentu ($C^0 = G^0$).
|
||||
- $G^1$ -- platí $G^0$ a navíc je **směr** tečny na konci prvního segmentu shodný s **směrem** tečny na začátku druhého segmentu. **Velikost tečného vektoru (rychlost) se však může prudce změnit.**
|
||||
- $G^2$ -- platí $G^1$ a navíc mají stejný **střed křivosti** (center of curvature). [smoothness](#smoothness)
|
||||
|
||||
Platí, že $C^n \Rightarrow G^n$, ale obráceně $G^n \not\Rightarrow C^n$.
|
||||
|
||||
**📌 NOTE**\
|
||||
Podle slidů z PB009 musí faktor úměrnosti být různý od 0. [pb009-2019](#pb009-2019) Podle Barskyho a DeRoseho musí v první derivaci být $> 0$ a v dalších už je to šumák. [geometric-continuity](#geometric-continuity) Co je správně? Kdo ví. Nemám dost častu to zjistit, takže to ponechávám jako cvičení čtenáři.
|
||||
|
||||
## Křivky
|
||||
|
||||
### Lagrangeův interpolační polynom
|
||||
|
||||
Základní metoda interpolace funkce, jejíž hodnotu známe jen v $n + 1$ diskrétních bodech $P_0, P_1, ... P_n$. Sestává se z pomocných polynomů $\ell_i$: [lagrange](#lagrange)
|
||||
|
||||
```math
|
||||
\ell_i(x) = \prod_{0 \le k \le n, k \neq i}^n \frac{x - x_k}{x_i - x_k}
|
||||
```
|
||||
|
||||
Který splňuje podmínku:
|
||||
|
||||
```math
|
||||
\ell_i(x_k) = \begin{cases}
|
||||
|
||||
1 & \text{ pro } i = k \\
|
||||
0 & \text{ pro } i \neq k
|
||||
|
||||
\end{cases}
|
||||
```
|
||||
|
||||
Pak polynom $P$ interpoluje danou množinu bodů:
|
||||
|
||||
```math
|
||||
P(x) = \sum_{i=0}^n P_i \ell_i(x)
|
||||
```
|
||||
|
||||
Blbé je, že musíme všechny pomocné polynomy přepočítat, když přidáme nový bod.
|
||||
|
||||
- **Hornerovo schéma / Horner’s method**\
|
||||
Metoda evaluace polynomů. Vychází z myšlenky, že násobení se dá nestovat: [horner](#horner)
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
|
||||
& a_0 + a_1 \cdot x + a_2 \cdot x^2 + ... + a_n \cdot x_n \\
|
||||
|
||||
& = a_0 + x(a_1 + x(a_2 + ... + x(a_{n-1} + x \cdot a_n)...))
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
Vyžaduje jen $n$ násobení a $n$ sčítání, což je optimální.
|
||||
|
||||
### Hermitovské křivky
|
||||
|
||||
Asi nejznámnější interpolační křivky v počítačové grafice. Jsou určeny dvěma řídícími body -- $P_0$ a $P_1$ -- a dvěma dotykovými vektory -- $\vec{p_0'}$ a $\vec{p_1'}$. Řídící body určují začátek a konec křivky, dotykové vektory její směr a vyklenutí. Pokud jsou oba vektory nulové, je to úsečka.
|
||||
|
||||
Je jednoduché je na sebe navázat v $C^1$, neboť tečné vektory jsou přímo součástí definice.
|
||||
|
||||
- **Cubic Hermite spline / Ferguson curve**\
|
||||
Pro Hermitovskou kubiku platí: [hermite-spline](#hermite-spline) [ferguson](#ferguson)
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
|
||||
Q(t) &=
|
||||
|
||||
\begin{bmatrix}
|
||||
t^{3} & t^{2} & t & 1
|
||||
\end{bmatrix}
|
||||
|
||||
\cdot
|
||||
|
||||
\begin{bmatrix}
|
||||
2 & -2 & 1 & 1 \\
|
||||
-3 & 3 & -2 & -1 \\
|
||||
0 & 0 & 1 & 0 \\
|
||||
1 & 0 & 0 & 0
|
||||
\end{bmatrix}
|
||||
|
||||
\cdot
|
||||
|
||||
\begin{bmatrix}
|
||||
P_{0} \\
|
||||
P_{1} \\
|
||||
\vec{p'}_{0} \\
|
||||
\vec{p'}_{1}
|
||||
\end{bmatrix} = \\
|
||||
|
||||
&= P_0 \cdot F_1(t) + P_1 \cdot F_2(t) + \vec{p'}_0 \cdot F_3(t) + \vec{p'}_1 \cdot F_4(t)
|
||||
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
kde $F_1, F_2, F_3, F_4$ jsou Hermitovské polynomy 3. stupně:
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
|
||||
\textcolor{red}{F_1(t)} &= 2t^3 - 3t^2 + 1 \\
|
||||
\textcolor{blue}{F_2(t)} &= -2t^3 + 3t^2 \\
|
||||
\textcolor{green}{F_3(t)} &= t^3 - 2t^2 + t \\
|
||||
\textcolor{cyan}{F_4(t)} &= t^3 - t^2
|
||||
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||

|
||||
|
||||
### Bézierova křivka
|
||||
|
||||
Asi nejčastěji používaná **aproximační** křivka. Využívá se zejména ve 2D grafice, třeba při definici fontů.
|
||||
|
||||
- Bézierova křivka $n$-tého stupně je definována $n + 1$ řídícími body $P_0, P_1, ... P_n$.
|
||||
- Změnou polohy jednoho bodu dojde ke změně celé křivky. Proto se často dělí na segmenty menšího stupně, které se pak navazují na sebe.
|
||||
|
||||
Základem jsou **Bernsteinovy polynomy** $n$-tého stupně:
|
||||
|
||||
[stem]
|
||||
b\_{\nu,n}(x) = \binom{n}{\nu} x^{\nu} \left( 1 - x \right)^{n - \nu}, \quad \nu = 0, \ldots, n,
|
||||
|
||||
Mezi jejich vlastnosti patří:
|
||||
|
||||
- Nezápornost: $b_{\nu,n}(x) \ge 0$ pro $x \in \lbrack 0, 1 \rbrack$.
|
||||
- Jejich součet je roven jedné: $\sum_{\nu = 0}^n b_{\nu,n}(x) = 1$.
|
||||
- Dají se vyjádřit rekurzí: $b_{\nu,n}(x) = (1 - x) \cdot b_{\nu,n-1}(x) + x \cdot b_{\nu-1,n-1}(x)$.
|
||||
|
||||
**Bernstein basis polynomials for 4th degree curve blending by [VisorZ](https://commons.wikimedia.org/w/index.php?curid=40129768)**
|
||||
|
||||

|
||||
|
||||
- **DeCasteljau algorithm**\
|
||||
Rekurzivní algoritmus pro konstrukci Bézierových křivek. Využívá vlastností Bernsteinových polynomů.
|
||||
|
||||

|
||||
|
||||
- **Bézierova kubika**\
|
||||
Bézierova křivka třetího stupně. Je dána čtyřmi řídícími body $P_0, P_1, P_2, P_3$:
|
||||
|
||||
```math
|
||||
P(t) = (1 - t)^3 \cdot P_0 + 3 \cdot (1 - t)^2 \cdot t \cdot P_1 + 3 \cdot (1 - t) \cdot t^2 \cdot P_2 + t^3 \cdot P_3
|
||||
```
|
||||
|
||||
### B-spline
|
||||
|
||||
- **Splajn / spline**\
|
||||
Splajn stupně $n$ po částech definovaná polynomiální funkce stupně $n-1$ proměnné $x$. [bspline](#bspline)
|
||||
|
||||
_Po částech definovaná / piecewise_ znamená, že má několik intervalů a pro každý z nich jiný polynom.
|
||||
|
||||
- Místa, kde se části polynomu dotýkají jsou _uzly_ a jsou značeny pomocí $t_0, t_1, ..., t_n$ a řazeny v neklesajícím pořadí.
|
||||
- Pokud jsou uzly unikátní, pak je splajn v uzlech $C^{n-2}$ spojitý. [bspline](#bspline)
|
||||
- Pokud je $r$ uzlů shodných, je v tomto místě pouze $C^{n-r-1}$ spojitý.
|
||||
|
||||
---
|
||||
|
||||
**Basis spline / B-spline** stupně $n$ je aproximační křivka / splajn daná sekvencí $n$ uzlů. Jako funkce vrací užitečné hodnoty jen mezi prvním a posledním uzlem, všude jinde je nulová. Svůj název dostala podle toho, že B-splajny slouží jako bázové funkce pro splajnové křivky.
|
||||
|
||||
Lze ji definovat pomocí **Cox-de Boorovy** rekurzivní formule:
|
||||
|
||||
**💡 TIP**\
|
||||
de Boorův algoritmus je generalizací DeCasteljauova algoritmu ale pro B-splajny.
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
|
||||
B_{i,0}(x) &= \begin{cases}
|
||||
1 & \text{pro } t_i \le x < t_{i+1} \\
|
||||
0 & \text{jinak}
|
||||
\end{cases}
|
||||
|
||||
\\
|
||||
|
||||
B_{i,n}(x) &= \textcolor{red}{\frac{x - t_i}{t_{i+n} - t_i}} B_{i,n-1}(x)
|
||||
+ \textcolor{blue}{\frac{t_{i+n+1} - x}{t_{i+n+1} - t_{i+1}}} B_{i+1,n-1}(x)
|
||||
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
Zatímco $x$ jde od $t_i$ k $t_{i+n}$, červený výraz začíná na 1 a klesá k 0.
|
||||
|
||||
Podobně, zatímco $x$ jde od $t_{i+1}$ k $t_{i+n+1}$, modrý výraz začíná na 0 a roste k 1.
|
||||
|
||||
Navíc platí $\sum_{i=0}^{n} B_{i,n}(x) = 1$.
|
||||
|
||||
Jejich užitečnost spočívá v tom, že libovolný splajn stupně $n$ daný sekvencí uzlů lze vyjádřit jako lineární kombinaci B-splajnů:
|
||||
|
||||
```math
|
||||
S(x) = \sum_{i=0} c_i B_{i,n}(x)
|
||||
```
|
||||
|
||||
**📌 NOTE**\
|
||||
Uzlů je zpravidla víc než $n+1$, protože pak teprve máme víc než jeden B-spline, který kombinujeme.
|
||||
|
||||
- **Uniformní B-splajny**\
|
||||
Uzly jsou rozloženy rovnoměrně. Tedy mezi každými dvěma uzly $t_i$ a $t_{i+1}$ je stejná vzdálenost $h$.
|
||||
|
||||
Příklad:
|
||||
|
||||
```math
|
||||
T = \begin{bmatrix}
|
||||
t_0 & t_1 & t_2 & t_3
|
||||
\end{bmatrix}
|
||||
= \begin{bmatrix}
|
||||
0 & 0.\overline{3} & 0.\overline{6} & 1
|
||||
\end{bmatrix}
|
||||
```
|
||||
|
||||
- **Coonsova kubika**\
|
||||
Kubika $P$ daná 4 řídícími body $P_0, P_1, P_2, P_3$. Neprochází ani jedním z kontrolních bodů. [coons](#coons)
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
|
||||
P(t) &= B_0(t) \cdot P_0 + B_1(t) \cdot P_1 + B_2(t) \cdot P_2 + B_3(t) \cdot P_3, t \in \lbrack 0, 1 \rbrack \\
|
||||
|
||||
B_0(t) &= \frac{1}{6} (1 - t)^3 \\
|
||||
B_1(t) &= \frac{1}{6} (3t^3 - 6t^2 + 4) \\
|
||||
B_2(t) &= \frac{1}{6} (-3t^3 + 3t^2 + 3t + 1) \\
|
||||
B_3(t) &= \frac{1}{6} t^3
|
||||
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||

|
||||
|
||||
**📌 NOTE**\
|
||||
Něco ohledně tohohle termínu mi hrozně smrdí. Zdá se, že jediní, kdo používají "coons cubic curve" jsme my a ČVUT.
|
||||
|
||||
## Povrchy
|
||||
|
||||
Interpolace je náročná, proto se častěji používají aproximační povrchy.
|
||||
|
||||
### Interpolační plocha
|
||||
|
||||
Plocha $\vec{P}$.
|
||||
Dáno:
|
||||
|
||||
- $(m + 1) \times (n + 1)$ řídících bodů $\vec{P}_{i,j}$.
|
||||
- $m + 1$ hodnot $u_k$ a $n + 1$ hodnot $v_l$.
|
||||
|
||||
Platí, že $\vec{P}(u_k, u_l) = \vec{P}_{k,l}$ pro $k = 0, 1, ..., m$ a $l = 0, 1, ..., n$.
|
||||
|
||||
Interpolujeme vektorovým polynomem $\vec{a}_{i,j}$:
|
||||
|
||||
```math
|
||||
\vec{P}(u, v) = \sum_{i = 0}^m \sum{j = 0}^n \vec{a}_{i,j} \cdot u^i \cdot v^j
|
||||
```
|
||||
|
||||
V případě Lagrangeova polynomu je $\vec{a}_{i,j} = \ell_i^m(u) \cdot \ell_j^n(v)$.
|
||||
|
||||
### Hermitovský plát
|
||||
|
||||
Interpolační povrch.
|
||||
|
||||
- **12-ti vektorová varianta**\
|
||||
4 rohové body a 8 tečných vektorů.
|
||||
|
||||

|
||||
|
||||
- **16-ti vektorová varianta**\
|
||||
4 rohové body, 8 tečných vektorů a 4 zkrutové vektory.
|
||||
|
||||

|
||||
|
||||
### Coonsovy pláty / Coonsovy plochy / Coons patch
|
||||
|
||||
Plochy vzniknuvší interpolací mezi křivkami udávající jejich okraje. Dají se na sebe pěkně napojovat, právě protože jsou definovány svými okraji.
|
||||
|
||||
**⚠️ WARNING**\
|
||||
Coonsovy pláty jsou **interpolační**, zatímco Coonsovy křivky jsou **aproximační**.
|
||||
|
||||
- **Bilineární Coonsovy pláty**
|
||||
|
||||
Určeny 4 křivkami $P(u, 0), P(u, 1), P(0, v), P(1, v)$, které tvoří okraj plátu.
|
||||
|
||||
Implicitně se dá zapsat jako:
|
||||
|
||||
```math
|
||||
\begin{bmatrix}
|
||||
1-u & -1 & u
|
||||
\end{bmatrix}
|
||||
|
||||
\cdot
|
||||
|
||||
C
|
||||
|
||||
\cdot
|
||||
|
||||
\begin{bmatrix}
|
||||
1-v \\ -1 \\ v
|
||||
\end{bmatrix}
|
||||
|
||||
= 0
|
||||
```
|
||||
|
||||
Povrch je pak tvořen body $C$, které tuto rovnici splňují.
|
||||
|
||||
Explicitně se dá zapsat jako:
|
||||
|
||||
```math
|
||||
P(u, v) = \begin{bmatrix} 1 - u & u \end{bmatrix} \cdot \begin{bmatrix} P_{0, v} \\ P_{1, v} \end{bmatrix}
|
||||
+ \begin{bmatrix} P_{u, 0} & P_{u, 1} \end{bmatrix} \cdot \begin{bmatrix} 1 - v \\ v \end{bmatrix}
|
||||
- \begin{bmatrix} 1 - u & u \end{bmatrix} \cdot
|
||||
\begin{bmatrix}
|
||||
P_{0, 0} & P_{0, 1} \\
|
||||
P_{1, 0} & P_{1, 1}
|
||||
\end{bmatrix}
|
||||
\cdot \begin{bmatrix} 1 - v \\ v \end{bmatrix}
|
||||
```
|
||||
|
||||

|
||||
|
||||
Zásadním nedostatek těchto ploch je, že není snadné vyjádřit tečné vektory na okrajích, a proto není snadné je napojovat na sebe.
|
||||
|
||||
- **Bikubické Coonsovy pláty**
|
||||
|
||||
Podobné bilineárním, ale používájí Hermitovské polynomy:
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
|
||||
F_1(t) &= 2t^3 - 3t^2 + 1 \\
|
||||
F_2(t) &= -2t^3 + 3t^2 \\
|
||||
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
Implicitně je pak tento plát dán:
|
||||
|
||||
```math
|
||||
\begin{bmatrix}
|
||||
F_1(u) & -1 & F_2(u)
|
||||
\end{bmatrix}
|
||||
|
||||
\cdot
|
||||
|
||||
C
|
||||
|
||||
\cdot
|
||||
|
||||
\begin{bmatrix}
|
||||
F_1(v) \\ -1 \\ F_2(v)
|
||||
\end{bmatrix}
|
||||
|
||||
= 0
|
||||
```
|
||||
|
||||
Stejně jako u bilineárních ploch, i tady je těžké získat tečné vektory na okrajích.
|
||||
|
||||
- **Obecná bikubická plocha**
|
||||
|
||||
Kromě rohů je parametrizována i tečnými vektory na okrajích. Konečně tedy umožňuje snadné navazování.
|
||||
|
||||
### Bézierovy plochy
|
||||
|
||||
Aproximační plochy dány $(m + 1) \times (n + 1)$ řídícími body. Jsou:
|
||||
|
||||
- snadno diferencovatelné,
|
||||
- jednoduše se modelují,
|
||||
- lze z nich relativně snadno spočítat průnik s paprskem,
|
||||
- speciální případ NURBS ploch.
|
||||
|
||||
```math
|
||||
P(u, v) = \sum_{i=0}^m \sum_{j=0}^n B_i^m(u) \cdot B_j^n(v) \cdot \vec{a}_{i,j}
|
||||
```
|
||||
|
||||
Kde $B_i^m(u)$ a $B_j^n(v)$ jsou Bernsteinovy polynomy.
|
||||
|
||||

|
||||
|
||||
Při změně jendoho z bodů se změní celá plocha, proto se často více plátů spojuje dohromady. Pro spojitost $G^0$ se musí rovnat řídící body na okrajích. Pro $G^0$ musí tečné vektory na okrajích být lineárně závislé.
|
||||
|
||||
Zobrazují se rekurzivním dělením (patch splitting). Využívá se algoritmu de Casteljau.
|
||||
|
||||
### B-spline plochy
|
||||
|
||||
Aproximační plochy analogické B-spline křivkám, ale se dvěma parametry.
|
||||
|
||||
- Jsou lepší pro modelování než Hermitovské nebo Bézierovy plochy, protože se lépe navazují, jelikož B-splajny stupně $k$ garantují spojitost $C^{k-1}$.
|
||||
- Změnou jednoho řídícího bodu nezměníme celou plochu, ale jen část.
|
||||
- Celá plocha leží v konvexním obalu řídících bodů.
|
||||
- Průchodu řídícím bodem lze dosáhnout zvýšením jeho násobnosti (a tak snížením spojitosti).
|
||||
- Invariantní k lineárním transformacím.
|
||||
|
||||
- **NURBS plochy**
|
||||
|
||||
Standard v průmyslovém modelování. Umožňují definovat velké množstí ploch: free-form surfaces, plochy založené na přímkách a kuželosečkách, atd. [nurbs](#nurbs) Jsou invariantní k lineárním transformacím i k perspektivní projekci.
|
||||
|
||||
```math
|
||||
S(u,v) = \sum_{i=1}^k \sum_{j=1}^l R_{i,j}(u,v) \mathbf{P}_{i,j}
|
||||
```
|
||||
|
||||
kde $\mathbf{P}_{i,j}$ jsou řídící body a $R_{i,j}(u,v)$ jsou NURBS bázové funkce:
|
||||
|
||||
```math
|
||||
R_{i,j}(u,v) = \frac {N_{i,n}(u) N_{j,m}(v) w_{i,j}} {\sum_{p=1}^k \sum_{q=1}^l N_{p,n}(u) N_{q,m}(v) w_{p,q}}
|
||||
```
|
||||
|
||||
$N_{i,n}(u)$ a $N_{j,m}(v)$ jsou B-spline bázové funkce stupně $n$ a $m$. $w_{i,j}$ jsou váhy.
|
||||
|
||||
**💡 TIP**\
|
||||
NURBS plochy se využívají v modelovací technice _sweeping_ (šablonování), kdy se množina bodů pohybuje (posunuje, rotuje, ...) prostorem za vniku tělesa. [sweeping](#sweeping)
|
||||
|
||||
## Surface subdivision / rekurzivní dělení polygonů
|
||||
|
||||
Polygonové povrchy dělíme v případě, kdy chceme je zjemnit, vyhladit.
|
||||
|
||||
- **Pravidla dělení**\
|
||||
Dělení dodržují nějaké pravidlo.
|
||||
|
||||
- _Topologická pravidla_: udávají vztahy pro generování nových vrcholů, hran, atd. z topologie objektu.
|
||||
- _Geometrická pravidla_: generují nové vrcholy, hrany, atd. na základě intepolací sousedních vrcholů.
|
||||
|
||||
- **Extraordinary vertices / mimořádné vrcholy**
|
||||
|
||||
Vrcholy, které mají jiný počet sousedů (valenci) než ostatní vrcholy.
|
||||
|
||||
- **4-point scheme**
|
||||
|
||||
Interpolace $C^1$ křivkou.
|
||||
|
||||
- **Catmull-Clark**
|
||||
|
||||
Aproximuje původní mesh. Zachovává $C^2$, na mimořádných bodech ale jen $C^1$. Po první iteraci vždy vznikou quady. Založený na bikubických uniformních B-splinech.
|
||||
|
||||
- **Doo-Sabin**
|
||||
|
||||
Aproximuje původní mesh. Narozdíl od Catmull-Clark je založený na **bikvadratických** uniformních B-splinech.
|
||||
|
||||

|
||||
|
||||
- **Loop**
|
||||
|
||||
Aproximuje původní mesh. Funguje jen na trojúhelníkové síti.
|
||||
|
||||
- **Butterfly**
|
||||
|
||||
**Interpoluje** původní mesh. Funguje jen na trojúhelníkové síti.
|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[pa010-2021,1]]] Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021)
|
||||
- [[[pa010-2020,2]]] Sochor: PA010 Intermediate Computer Graphics (podzim 2020)
|
||||
- [[[pb009-2019,3]]] Sochor: PB009 Principles of Computer Graphics (jaro 2019)
|
||||
- [[[smoothness,4]]] [Wikipedia: Smoothness](https://en.wikipedia.org/wiki/Smoothness)
|
||||
- [[[mallinus,5]]] [Jaakko Kurhila and Matti Mäkelä: Parametric Curves](https://www.cs.helsinki.fi/group/goa/mallinnus/curves/curves.html)
|
||||
- [[[geometric-continuity,6]]] [Geometric Continuity of Parametric Curves: Three Equivalent Characterizations](https://ieeexplore.ieee.org/document/41470)
|
||||
- [[[lagrange, 7]]] [Wikipedia: Lagrange polynomial](https://en.wikipedia.org/wiki/Lagrange_polynomial)
|
||||
- [[[bspline, 8]]] [Wikipedia: B-spline](https://en.wikipedia.org/wiki/B-spline)
|
||||
- [[[hermite-spline, 9]]] [Wikipedia: Cubic Hermite spline](https://en.wikipedia.org/wiki/Cubic_Hermite_spline)
|
||||
- [[[ferguson, 10]]] [ČVUT: Ferguson curve](https://marian.fsik.cvut.cz/~kongo/download/pcgr/lectures/01%20crv_ferg.pdf)
|
||||
- [[[coons, 11]]] [ČVUT: Coons curve](https://marian.fsik.cvut.cz/~kongo/download/pcgr/lectures/03%20crv_coons.pdf)
|
||||
- [[[coons-path, 12]]] [Wikipedia: Coons patch](https://en.wikipedia.org/wiki/Coons_patch)
|
||||
- [[[nurbs, 13]]] [Wikipedia: Non-uniform rational B-spline](https://en.wikipedia.org/wiki/Non-uniform_rational_B-spline)
|
||||
- [[[sweeping,14]]] [Wikipedia: Solid modeling](https://en.wikipedia.org/wiki/Solid_modeling#Sweeping)
|
||||
- [[[horner,15]]] [Wikipedia: Horner’s method](https://en.wikipedia.org/wiki/Horner%27s_method)
|
||||
|
||||
## Další zdroje
|
||||
|
||||
- [NURBS Calculator](http://nurbscalculator.in/)
|
||||
- [ČVUT: Computer Graphics](https://mat.fs.cvut.cz/computer-graphics/)
|
||||
|
||||
<div class="fortunate-brain">
|
||||
</div>
|
449
src/content/docs/szmgr/SZP06_strojove_uceni.md
Normal file
449
src/content/docs/szmgr/SZP06_strojove_uceni.md
Normal file
@ -0,0 +1,449 @@
|
||||
---
|
||||
title: "Strojové učení"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Strojové učení a rozpoznávání vzorů: problém klasifikace a regrese, shluková analýza, učení s učitelem a bez učitele. Vícevrstvé neuronové sítě, vícevrstvé perceptrony, ztrátové funkce, zpětná propagace. pass:[<s>Hopfieldova síť, </s>]konvoluční sítě, rekurentní sítěpass:[<s>, samo-organizující mapy</s>].
|
||||
|
||||
_PV021_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
**💡 TIP**\
|
||||
Velkou část zpracování téhle otázky jsem ukradl [sám sobě](/fi/pv021/).
|
||||
|
||||
## Strojové učení a rozpoznávání vzorů
|
||||
|
||||
- **Machine learning / strojové učení**
|
||||
|
||||
Oblast informatiky zabývající se konstrukcí systémů, které nemají svoji funkcionalitu explicitně naprogramovanou, ale naučí se ji až na základě vstupních dat. [ml](#ml) [pv021](#pv021)
|
||||
|
||||
Používá se např. pro:
|
||||
|
||||
- filtrování spamu v emailech,
|
||||
- rozpoznávání řeči, rukopisu, tváří, zvuků, atd.,
|
||||
- klasifikaci textů,
|
||||
- herní strategie,
|
||||
- analýzu trhu,
|
||||
- autonomní řízení vozidel.
|
||||
|
||||
- **Rozpoznávání vzorů / pattern recognition**\
|
||||
Problém automatizovaného rozpoznávání vzorů v datech (např. číslic v obrázku). Příklady jsou _klasifikace_, _regrese_ a _shluková analýza_. [pattern-recognition](#pattern-recognition)
|
||||
- **Klasifikace**\
|
||||
Problém identifikace kategorie, do které patří vstupní data. Výstupem klasifikace je buď jedna konkrétní kategorie nebo vektor popisující s jakou pravděpodobností vstup do každé kategorie patří. [classification](#classification)
|
||||
- **Regrese**\
|
||||
Problém odhadu hodnoty nějaké proměnné na základě znalosti jiných proměnných. Výstupem regrese je obvykle reálné číslo. [regression](#regression)
|
||||
|
||||
Například při _lineární regresi_ se snažíme data napasovat na přímku -- najít její offset a směrnici. Při _logistické regresi_ chceme to samé ale místo přímky máme logistic sigmoid. A tak dále. [pv021](#pv021)
|
||||
|
||||
- **Shluková analýza / cluster analysis**\
|
||||
Vicedimenzionální problém rozdělení vstupních dat do skupin (shluků) tak, aby data v jednom shluku byla _podobnější_ sobě než datům v jiných shlucích. [clustering](#clustering)
|
||||
|
||||
Souvisejícím problémem je vyjádření toho, že jsou si data v nějakém smyslu _podobná_.
|
||||
|
||||
- **Supervised learning / učení s učitelem**\
|
||||
Síť se učí na základě množiny trénovacích vstupů ve formátu (vstup, výstup). Supervised learning algoritmy se snaží síť modifikovat tak, aby vracela výstupy co možná nejpodobnější těm trénovacím. [pv021](#pv021)
|
||||
- **Unsupervised learning / učení bez učitele**\
|
||||
Síť dostává jen vstupy. Cílem je získat o vstupní množině dat nějakou užitečnou informaci, třeba kde jsou shluky. [pv021](#pv021)
|
||||
|
||||
## Neuronové sítě
|
||||
|
||||
- **Neural network / neuronová síť**
|
||||
|
||||
Neuronová síť je množina propojených neuronů, jejíž chování je zakódováno do spojení mezi neurony. Je primitivním modelem biologických neuronových sítí.
|
||||
|
||||
Typ neuronové sítě je dán její architekturou (způsobem zapojení), aktivitou (transformací vstupů na výstupy) a učením (metodou změny vah při trénování).
|
||||
|
||||
- **Architektura**\
|
||||
Neuron může být _input_, _output_ nebo _hidden_. Může být dokonce input i output najednou. Hidden je, právě když není input ani output.
|
||||
|
||||
Síť být cyklická -- _recurrent_ -- nebo acyklická -- _feed-forward_.
|
||||
|
||||
- **Stav sítě**\
|
||||
Vektor výstupů všech neuronů sítě (nejen output).
|
||||
- **Stavový prostor sítě**\
|
||||
Množina všech možných stavů sítě.
|
||||
- **Vstup sítě**\
|
||||
Vektor reálných čísel (prvek $\Reals^n$), kde $n$ je počet vstupů.
|
||||
- **Vstupní prostor sítě**\
|
||||
Množina všech vstupů sítě.
|
||||
- **Iniciální stav**\
|
||||
Input neuronům je za výstup ($y$) dán vektor vstupů ($\vec{x}$). Všem ostatním neuronům je výstup ($y$) nastaven na 0.
|
||||
- **Výstup sítě**\
|
||||
Vektor výstupů ($y$) output neuronů. Výstup se v průběhu výpočtu může měnit.
|
||||
- **Výpočet**\
|
||||
Typicky po diskrétních krocích:
|
||||
|
||||
1. Zvolí se množina neuronů (vybrané podle pravidla daného architekturou).
|
||||
2. Zvoleným neuronům je nastaven výstup -- prostě se vyhodnotí aktivační funkce.
|
||||
3. Vrať se ke kroku 1.
|
||||
|
||||
Výpočet je _konečný_, pokud se stav sítě dále nemění po konečném množství opakování postupu výše.
|
||||
|
||||
- **Konfigurace**\
|
||||
Vektor hodnot všech vah.
|
||||
- **Vahový prostor**\
|
||||
Množina všech konfigurací.
|
||||
- **Iniciální konfigurace**\
|
||||
Počáteční hodnoty vah (než začne trénování).
|
||||
|
||||
## Multilayer perceptron (MLP) / vícevrstvé neuronové sítě
|
||||
|
||||
- **Perceptron -- jeden neuron**
|
||||
|
||||
- Hrubá matematická aproximace biologického neuronu.
|
||||
- Binární klasifikátor -- rozlišuje jestli vstup patří nebo nepatří do nějaké jedné kategorie.[pv021](#pv021)
|
||||
- Linerání klasifikátor -- jeho funkce kombinuje vstupy lineárně.
|
||||
|
||||

|
||||
|
||||
- $x_i$ -- inputy
|
||||
- $w_i$ -- váhy
|
||||
- $\xi = w_0 + \sum_{i=1}^n w_i x_i$ -- vnitřní potenciál
|
||||
- $y$ -- výstup
|
||||
- $y = \sigma(\xi)$ -- aktivační funkce udávající výstup
|
||||
- bias -- udává "jak těžké" je pro neuron se aktivovat (čím vyšší číslo, tím těžší je pro neuron vydat nenulový výstup)
|
||||
- $x_0$ -- pro snažší implementaci se závádí dodatečný vstup, který má vždy hodnotu 1 a váhu rovnu -bias
|
||||
|
||||
**📌 NOTE**\
|
||||
Vnitřní potenciál funguje jako nadrovina (čára při 2D, rovina při 3D, nepředstavitelný mostrum ve vyšších dimenzí), která rozděluje prostor vstupů na část, kde je $\xi < 0$ a kde $\xi > 0$.
|
||||
|
||||
- **Multilayer perceptron (MLP)**
|
||||
|
||||
MLP je feed-forward (neobsahuje cykly) architektura NN, kde platí:
|
||||
|
||||
- Neurony rozděleny do vrstev -- jedné vstupní, jedné výstupní a libovolného počtu skrytých vrstev uprostřed.
|
||||
- Vrstvy jsou _dense_ -- každý neuron v $i$-té vrstvě je napojen na každý neuron v $(i + 1)$-ní vrstvě.
|
||||
|
||||

|
||||
|
||||
Kde:
|
||||
|
||||
- $\textcolor{green}{X}$ -- množina input neuronů
|
||||
- $\textcolor{red}{Y}$ -- množina output neuronů
|
||||
- $Z$ -- množina všech neuronů
|
||||
- Neurony mají indexy $i$, $j$, ...
|
||||
- $\xi_j$ -- vnitřní potenciál neuronu $j$ po skončení výpočtu
|
||||
- $y_j$ -- výstup neuronu $j$ po skončení výpočtu
|
||||
- $x_0 = 1$ -- hodnota formálního jednotkového vstupu (kvůli biasům)
|
||||
- $w_{j,i}$ -- váha spojení **z** neuronu $i$ **do** neuronu $j$ (dst <- src)
|
||||
- $w_{j,0} = -b_j$ -- bias -- váha z formální jednotky do neuronu $j$
|
||||
- $j_{\leftarrow}$ -- množina neuronů $i$, jenž mají spojení **do** $j$ (j <- i)
|
||||
- $j^{\rightarrow}$ -- množina neuronů $i$, do nichž vede spojení **z** $j$ (j -> i)
|
||||
|
||||
### Aktivita
|
||||
|
||||
- **Pravidlo pro výběr neuronů při výpočtu**\
|
||||
V i-tému kroku vezmi i-tou vrstvu.
|
||||
- **Vnitřní potenciál neuronu $j$**\
|
||||
$\xi_j = \sum_{i \in j_{\leftarrow}} w_{ji}y_i$
|
||||
- **Aktivační funkce neuronu $j$**\
|
||||
$\sigma_j : \Reals \to \Reals$ (třeba logistic sigmoid)
|
||||
- **Stav nevstupního neuronu $j$**\
|
||||
$y_j = \sigma_j(\xi_j)$ resp. $y_j(\vec{w}, \vec{x})$
|
||||
- **Logistic sigmoid**\
|
||||
Většina aktivačních funkcí vychází s funkce _sigmoid_. (Jsou _sigmoidní_, vypadají trochu jako písmeno `S`). Přidávají do výpočtu nelinearitu, která je potřeba, aby NN mohla modelovat libovolné funkce. Zároveň je podobná klasickému thresholdu, ale je "vyhlazená".
|
||||
|
||||
```math
|
||||
\sigma(\xi) = \frac{1}{1 + e^{-\lambda \cdot \xi}}
|
||||
```
|
||||
|
||||
kde $\lambda$ je _steepness_ parametr, který určuje, jak rychle sigmoid roste.
|
||||
|
||||

|
||||
|
||||
### Trénink
|
||||
|
||||
**❗ IMPORTANT**\
|
||||
Pro likelihood viz otázka [Statistika](../statistika/).
|
||||
|
||||
Neuronka je model, kde váhy neuronů jsou parametry. Při učení neuronek je naším cílem maximalizovat likelihood, jakožto míru toho, že naše síť sedí na "naměřená data", training set $\cal T$. Tomuhle přístupu se říká _maximum likelihood principle_.
|
||||
|
||||
- **Training set $\cal T$**\
|
||||
je množina $p$ samplů, kde $\vec{x} \in \Reals^{|X|}$ jsou vstupní vektory a $\vec{d} \in \Reals^{|Y|}$ jejich očekáváné výstupy.
|
||||
|
||||
```math
|
||||
\mathcal{T} = \{(\vec{x}_1, \vec{d}_1), (\vec{x}_2, \vec{d}_2), ..., (\vec{x}_p, \vec{d}_p)\}
|
||||
```
|
||||
|
||||
- **Ztrátové funkce / loss function / error function**\
|
||||
Popisuje způsob, jakým je při tréninku výstup z NN porovnán s očekáváným výstupem.
|
||||
|
||||
Její volba závisí na tom, co NN modeluje. Např. volíme:
|
||||
|
||||
- _mean squared error_ (MSE) -- pro regresi,
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
|
||||
E_k(\vec{w}) &= \frac{1}{2} \sum_{j \in Y}
|
||||
\left(
|
||||
y_j(\vec{w}, \vec{x_k}) - d_{kj}
|
||||
\right)^2 \\
|
||||
|
||||
E(\vec{w}) &= \textcolor{red}{\frac{1}{p}} \sum_{k=1}^p E_k(\vec{w})
|
||||
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
- _(categorical) cross-entropy_ -- pro (multi-class) klasifikaci.
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
|
||||
E(\vec{w}) = -\frac{1}{p} \sum_{k=1}^p \sum_{j \in Y} d_{kj} \ln(y_j)
|
||||
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
- **Gradient descent**\
|
||||
Algoritmus počítající, jak se mají vahy neuronů upravit, aby se zmenšila ztráta. Vychází z gradientu ztrátové funkce.
|
||||
|
||||
```math
|
||||
\Delta \vec{w}^{(t)} = - \varepsilon(t) \cdot \nabla E (\vec{w}^{(t)})
|
||||
```
|
||||
|
||||
- **Stochastic Gradient Descent (SGD)**\
|
||||
Sample nebereš po jednom ale po malých randomizovaných várkách -- minibatchích $T$, a váhy upravuješ až po zpracování minibatche.
|
||||
|
||||
```math
|
||||
\Delta \vec{w}^{(t)} = - \varepsilon(t) \cdot \sum_{k \in T} \nabla E_k(\vec{w}^{(t)})
|
||||
```
|
||||
|
||||
- **Backpropagation / zpětná propagace**\
|
||||
Technika, kdy se v průběhu _gradient descent_ ztráta způsobená konkrétním neuronem dedukuje na zákládě jeho příspěvku k výsledku. Algoritmus tak postupuje od output vrstvy směrem k input vrstvě.
|
||||
- **Learning rate $\varepsilon$**\
|
||||
Hyperparametr $0 < \varepsilon \le 1$ ovlivňující rychlost učení. Může záviset na iteraci $t$, pak je to funkce $\varepsilon(t)$.
|
||||
|
||||
**Gradient descent v MLP**
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
|
||||
w_{ji}^{(t+1)}
|
||||
&= w_{ji}^{(t)} + \Delta w_{ji}^{(t)} \\
|
||||
|
||||
\Delta w_{ji}^{(t)}
|
||||
&= -\varepsilon(t) \cdot \textcolor{green}{\frac{\partial E}{\partial w_{ji}}(\vec{w}^{(t)})} \\
|
||||
|
||||
\textcolor{green}{\frac{\partial E}{\partial w_{ji}}}
|
||||
&= \sum_{k=1}^{p} \textcolor{blue}{\frac{\partial E_k}{\partial w_{ji}}} \\
|
||||
|
||||
\textcolor{blue}{\frac{\partial E_k}{\partial w_{ji}}}
|
||||
&= \textcolor{red}{\frac{\partial E_k}{\partial y_j}}
|
||||
\cdot \textcolor{purple}{\frac{\partial y_j}{\partial \xi_j}}
|
||||
\cdot \textcolor{teal}{\frac{\partial \xi_j}{\partial w_{ji}}} \\
|
||||
&= \textcolor{red}{\frac{\partial E_k}{\partial y_j}}
|
||||
\cdot \textcolor{purple}{\sigma'_j(\xi_j)}
|
||||
\cdot \textcolor{teal}{y_i}
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
Za předpokladu, že $E$ je squared error, pak:
|
||||
|
||||
**⚠️ WARNING**\
|
||||
V případě, že $E$ není squared error, následující výpočet neplatí.
|
||||
|
||||
```math
|
||||
\large
|
||||
\textcolor{red}{\frac{\partial E_k}{\partial y_j}} =
|
||||
\begin{cases}
|
||||
y_j - d_{kj} & \text{ pokud } j \in Y ; \\
|
||||
\sum_{r \in j^{\rightarrow}} \textcolor{brown}{\frac{\partial E_k}{\partial y_r}}
|
||||
\cdot \textcolor{dodgerblue}{\frac{\partial y_r}{\partial \xi_r}}
|
||||
\cdot \textcolor{forestgreen}{\frac{\partial \xi_r}{\partial y_j}}
|
||||
= \sum_{r \in j^{\rightarrow}} \textcolor{brown}{\frac{\partial E_k}{\partial y_r}}
|
||||
\cdot \textcolor{dodgerblue}{\sigma'_r(\xi_r)}
|
||||
\cdot \textcolor{forestgreen}{w_{rj}}
|
||||
& \text{ jinak}.
|
||||
\end{cases}
|
||||
```
|
||||
|
||||
**Algoritmus pro výpočet $\frac{\partial E}{\partial w_{ji}}$**
|
||||
|
||||
1. Inicializuj $\varepsilon_{ji} := 0$.
|
||||
2. forward pass -- vyhodnoť NN pro sample $k$ (t.j. $y_j(\vec{w}, \vec{x_k})$ pro všechny $j \in Z$)
|
||||
3. backward pass -- od konce pro každou vrstvu spočítej $\frac{\partial E_k}{\partial y_j}$
|
||||
a. pokud $j \in Y$, pak $\frac{\partial E_k}{\partial y_j} = y_j - d_{kj}$
|
||||
b. pokud $j \in Z \setminus Y \cup X $, a $j$ je v $l$-té vrstvě, pak
|
||||
$\frac{\partial E_k}{\partial y_j} = \sum_{r \in j^{\rightarrow}} \frac{\partial E_k}{\partial y_r} \cdot \sigma'_r(\xi_r) \cdot w_{rj}$
|
||||
4. weight update -- pro všechna $w_{ji}$ spočítej
|
||||
$\frac{\partial E_k}{\partial w_{ji}} := \frac{\partial E_k}{\partial y_j} \cdot \sigma'_j(\xi_j) \cdot y_i$
|
||||
5. $\varepsilon_{ji} := \varepsilon_{ji} + \frac{\partial E_k}{\partial w_{ji}}$
|
||||
6. $\varepsilon_{ji}$ obsahuje výslednou hodnotu $\frac{\partial E}{\partial w_{ji}}$
|
||||
|
||||
## Konvoluční sítě
|
||||
|
||||
Neuronové sítě uzpůsobené ke zpracování obrazu. Místo násobení matic používají alespoň v jedné vrstvě konvoluci. Konvoluční sítě mají dva nové typy vrstev: _konvoluční_ a _pooling_, ale jinak se od klasických MLP moc neliší. Aktivace a trénink zůstavají v podstatě stejné. [cnn](#cnn)
|
||||
|
||||
**❗ IMPORTANT**\
|
||||
Pro konvoluci viz otázka [Zpracování rastrového obrazu](../zpracovani-rastroveho-obrazu/).
|
||||
|
||||
**Typical CNN by [Aphex34](https://commons.wikimedia.org/w/index.php?curid=45679374)**
|
||||
|
||||

|
||||
|
||||
- **Konvoluční vrstva**
|
||||
- Každý neuron je napojen jen na malý _receptive field_ neuronů o vrstvu níže, který se posouvá o daný stride.
|
||||
- Výstup z neuronu v konvoluční vrstvě je dán konvolucí jeho receptive field s váhami a přičtením biasu.
|
||||
- Všechny neurony v konvoluční vrstvě sdílí stejné váhy a biasy dané velikostí receptive field, což jim umožňuje naučit se nějaký vzor o velikosti receptive field -- říkáme, že taková vrstva je feature mapa.
|
||||
- Vzorů se chceme zpravidla naučit více, máme vícero vzájemně nezávislých feature map napojených na stejnou vstupní vrstvu.
|
||||
- **Pooling vrstva**\
|
||||
Nemají váhy. Slouží ke snížení počtu parametrů. Každý neuron počítá nějakou jednoduchou funkci na svém _receptive field_:
|
||||
- _max-pooling_: maximum,
|
||||
- _L2-pooling_: square root of sum of squares,
|
||||
- _average-pooling_: mean.
|
||||
- **Backpropagation**
|
||||
|
||||
Algoritmus je potřeba trochu poupravit, aby podporovat konvoluční a pooling vrstvy.
|
||||
|
||||
U konvolučních vrstev nestačí pro každou váhu $w_{ji}$ spočítat $\frac{\partial E_k}{\partial w_{ji}}$, protože pro každou váhu existuje víc než jeden výstup $y_j$. Tedy:
|
||||
|
||||
```math
|
||||
\frac{\partial E_k}{\partial w_{ji}} = \sum_{rl \in \textcolor{red}{\bf \lbrack ji \rbrack}} \frac{\partial E_k}{\partial y_r}
|
||||
\cdot \sigma'_r(\xi_r)
|
||||
\cdot y_l
|
||||
```
|
||||
|
||||
kde $\color{red}\bf \lbrack ji \rbrack$ je množina spojení (dvojic neuronů) sdílících váhu $w_{ji}$.
|
||||
|
||||
Pokud $j \in Z \setminus Y$ a $j^{\rightarrow}$ je max-pooling, pak $j^{\rightarrow} = \{ i \}$ a platí:
|
||||
|
||||
```math
|
||||
\frac{\partial E_k}{\partial y_j}
|
||||
= \begin{cases}
|
||||
\frac{\partial E_k}{\partial y_i} & \text{pokud } j = \argmax_{r \in i_{\leftarrow}} y_r \\
|
||||
0 & \text{jinak}
|
||||
\end{cases}
|
||||
```
|
||||
|
||||
## Rekurentní sítě
|
||||
|
||||
Neuronové sítě, jejichž architektura obsahuje cykly. Tedy výstup v jednom bodě v čase sítě přispívá k výstup v budoucnosti. Jinými slovy, je to neuronka s pamětí. _Recurrent neural networks_ (RNN) konkrétně jsou MLP _minimálně_ rozšířené tak, aby měly paměť. [rnn](#rnn)
|
||||
|
||||
- **Výhody**
|
||||
|
||||
- Umí zpracovat vstupy s variabilní, předem neznámou délkou.
|
||||
- Velikost modelu (množiny vah) je fixní nezávisle na velikosti vstupu.
|
||||
- Váhy se sdílí mezi vstupy (např. slova ve větě), což umožňuje naučit se nějaký kontext.
|
||||
|
||||
- **Nevýhody**
|
||||
- Trénování je složitější, protože se vyskytuje zpětná vazba.
|
||||
- Výpočetně náročnější.
|
||||
- Gradient může explodovat (exploding) nebo zaniknout (diminishing).
|
||||
|
||||

|
||||
|
||||
- **Notace**\
|
||||
V čase $t$:
|
||||
|
||||
- $\vec{x_t} = (x_{t, 1}, x_{t, 2}, ..., x_{t, M})$ je vstupní vektor předávaný $M$ vstupním neuronům,
|
||||
- $\vec{h_t} = (h_{t, 1}, h_{t, 2}, ..., h_{t, H})$ je vektor hodnot $H$ skrytých neuronů,
|
||||
- $\vec{y_t} = (y_{t, 1}, y_{t, 2}, ..., y_{y, N})$ je výstupní vektor $N$ neuronů,
|
||||
- $U_{j, i}$ je váha mezi inputem $i$ a hiddenem $j$,
|
||||
- $W_{j', i'}$ je váha mezi hiddenem $i'$ a hiddenem $j'$,
|
||||
- $V_{j'', i''}$ je váha mezi hiddenem $i''$ a outputem $j''$.
|
||||
|
||||
- **Aktivita**
|
||||
|
||||
- Na počátku je výstup neuronky vynulován. Paměť je tedy prázdná.
|
||||
- RNN zpracovává sekvenci vstupů $\mathbb{x} = \vec{x_1}, \vec{x_2}, ..., \vec{x_T}$ délky $T$.
|
||||
- Pro každý prvek $\vec{x_t} \in \mathbb{x}$, síť vyprodukuje výstup z hidden neuronů:
|
||||
|
||||
```math
|
||||
\vec{h_t} = \sigma(U \cdot \vec{x}_t + W \cdot \vec{h}_{t-1})
|
||||
```
|
||||
|
||||
- Pro výstup pak:
|
||||
|
||||
```math
|
||||
\vec{y_t} = \sigma(V \cdot \vec{h}_t)
|
||||
```
|
||||
|
||||
- **Trénink**
|
||||
|
||||
Trénovací set je množina dvojic -- (vstupní **sekvence**, výstupní **sekvence**).
|
||||
|
||||
```math
|
||||
\mathcal{T} = \{ (\bold{x}_1, \bold{d}_1), ..., (\bold{x}_p, \bold{d}_p) \}
|
||||
```
|
||||
|
||||
**📌 NOTE**\
|
||||
Ano, to znamená, že $x_{lt1}$ je první prvek $t$-ho prvku v $l$-té vstupní sekvenci.
|
||||
|
||||
Squared error samplu $(\bold{x}, \bold{d})$:
|
||||
|
||||
```math
|
||||
E_{(\bold{x}, \bold{d})} = \sum_{t=1}^T \sum_{k=1}^N \frac{1}{2} (y_{tk} - d_{tk})^2
|
||||
```
|
||||
|
||||
Gradient descent je podobný. Na začátku jsou všechny váhy inicalizovány poblíž 0 a pak iterativně přepočítávány:
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
|
||||
U_{kk'}^{(l+1)} &= U_{kk'}^{(l)} - \varepsilon(l) \cdot \frac{\partial E_{(x, d)}}{\partial U_{kk'}} \\
|
||||
V_{kk'}^{(l+1)} &= V_{kk'}^{(l)} - \varepsilon(l) \cdot \frac{\partial E_{(x, d)}}{\partial V_{kk'}} \\
|
||||
W_{kk'}^{(l+1)} &= W_{kk'}^{(l)} - \varepsilon(l) \cdot \frac{\partial E_{(x, d)}}{\partial W_{kk'}} \\
|
||||
|
||||
\frac{\partial E_{(x, d)}}{\partial U_{kk'}} &= \sum_{t=1}^T
|
||||
\textcolor{brown}{\frac{\partial E_{(x, d)}}{\partial h_{tk}}}
|
||||
\cdot \sigma'
|
||||
\cdot x_{tk'} \\
|
||||
\frac{\partial E_{(x, d)}}{\partial V_{kk'}} &= \sum_{t=1}^T
|
||||
\textcolor{darkgreen}{\frac{\partial E_{(x, d)}}{\partial y_{tk}}}
|
||||
\cdot \sigma'
|
||||
\cdot h_{tk'} \\
|
||||
\frac{\partial E_{(x, d)}}{\partial W_{kk'}} &= \sum_{t=1}^T
|
||||
\textcolor{brown}{\frac{\partial E_{(x, d)}}{\partial h_{tk}}}
|
||||
\cdot \sigma'
|
||||
\cdot h_{(t-1)k'} \\
|
||||
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
Za předpokladu squared error je backpropagation:
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
\textcolor{darkgreen}{\frac{\partial E_{(x, d)}}{\partial y_{tk}}}
|
||||
&= y_{tk} - d_{tk} \\
|
||||
|
||||
\textcolor{brown}{\frac{\partial E_{(x, d)}}{\partial h_{tk}}}
|
||||
&= \sum_{k'=1}^N
|
||||
\textcolor{darkgreen}{\frac{\partial E_{(x, d)}}{\partial y_{tk'}}}
|
||||
\cdot \sigma'
|
||||
\cdot V_{k'k}
|
||||
+
|
||||
\sum_{k'=1}^H
|
||||
\textcolor{brown}{\frac{\partial E_{(x, d)}}{\partial h_{(t+1)k'}}}
|
||||
\cdot \textcolor{red}{\sigma'
|
||||
\cdot W_{k'k}}
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
**💡 TIP**\
|
||||
Pokud $\textcolor{red}{\sigma' \cdot W_{k’k}} \not\approx 1$, pak gradient buď vybouchne nebo se ztratí.
|
||||
|
||||
- **Long Short-Term Memory (LSTM)**\
|
||||
LSTM řeší problém s vanishing a exploding gradientem, kterým RNN. V RNN je $\sigma$ typicky $\tanh$. V LSTM obsahuje jeden hidden neuron vlastně čtyři "podvrstvy", které mimo jiné umožňují část paměti zapomenout:
|
||||
|
||||

|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[pv021, 1]]] T. Brázdil: PV021 Neural Networks
|
||||
- [[[ml, 2]]] [Wikipedia: Machine learning](https://en.wikipedia.org/wiki/Machine_learning)
|
||||
- [[[classification, 3]]] [Wikipedia: Statistical classification](https://en.wikipedia.org/wiki/Statistical_classification)
|
||||
- [[[regression, 4]]] [Wikipedia: Regression analysis](https://en.wikipedia.org/wiki/Regression_analysis)
|
||||
- [[[clustering, 5]]] [Wikipedia: Cluster analysis](https://en.wikipedia.org/wiki/Cluster_analysis)
|
||||
- [[[pattern-recognition, 6]]] [Wikipedia: Pattern recognition](https://en.wikipedia.org/wiki/Pattern_recognition)
|
||||
- [[[hopfield, 7]]] [Wikipedia: Hopfield network](https://en.wikipedia.org/wiki/Hopfield_network)
|
||||
- [[[hebb, 8]]] [Wikipedia: Hebbian theory](https://en.wikipedia.org/wiki/Hebbian_theory)
|
||||
- [[[cnn, 9]]] [Wikipedia: Convolutional neural network](https://en.wikipedia.org/wiki/Convolutional_neural_network)
|
||||
- [[[rnn, 10]]] [Wikipedia: Recurrent neural network](https://en.wikipedia.org/wiki/Recurrent_neural_network)
|
||||
- [[[som, 11]]] [Wikipedia: Self-organizing map](https://en.wikipedia.org/wiki/Self-organizing_map)
|
||||
- [[[som-tutorial, 12]]] [Self-Organizing Maps: Tutorial](https://sites.pitt.edu/~is2470pb/Spring05/FinalProjects/Group1a/tutorial/som.html)
|
||||
- [[[som-sdl, 13]]] [SDL Component Suite: Kohonen Network](http://www.lohninger.com/helpcsuite/kohonen_network_-_background_information.htm)
|
573
src/content/docs/szmgr/SZP07_grafy.md
Normal file
573
src/content/docs/szmgr/SZP07_grafy.md
Normal file
@ -0,0 +1,573 @@
|
||||
---
|
||||
title: "Grafy a grafové algoritmy"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Reprezentace grafů. Souvislost grafu, rovinné grafy. Prohledávání grafu do šířky a do hloubky, nejkratší vzdálenosti, kostry, toky v sítích. Algoritmy: Bellman-Ford, Dijkstra, Ford-Fulkerson, Push-Relabel, maximální párování v bipartitních grafech.
|
||||
|
||||
_IB000, IB002, IV003_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
**💡 TIP**\
|
||||
Tahle otázka má solidní překryv s bakalářskými otázkami [Grafy](../../szb/grafy/) a [Grafové problémy](../../szb/grafove-problemy/).
|
||||
|
||||
## Terminologie
|
||||
|
||||
- **Graf**\
|
||||
Dvojice $G = (V, E)$ kde:
|
||||
|
||||
- $V$ je množina vrcholů; $\lvert V \rvert = n$,
|
||||
- $E$ je množina hran; $\lvert E \rvert = m$,
|
||||
- hrana $e \in E$ je dvojice vrcholů $e = (u, v)$.
|
||||
|
||||
- **Váha grafu**\
|
||||
Váha grafu je součet vah hran grafu $G$.
|
||||
|
||||
```math
|
||||
w(G) = \sum_{e \in E(G)} w(e)
|
||||
```
|
||||
|
||||
- **Bipartitní graf**\
|
||||
Graf jehož vrcholy lze rozdělit do dvou disjunktních množin tak, že všechny hrany vedou z jedné množiny do druhé.
|
||||
|
||||
**Example of bipartite graph without cycles by [Watchduck](https://commons.wikimedia.org/w/index.php?curid=121779105)**
|
||||
|
||||

|
||||
|
||||
- **(Silná) souvislost grafu / (strongly) connected graph**\
|
||||
Graf $G$ je souvislý, pokud pro každé dva vrcholy $u, v \in V(G)$ existuje cesta z $u$ do $v$.
|
||||
- **Slabá souvislost grafu / weakly connected graph**\
|
||||
Graf $G$ je slabě souvislý, pokud je souvislý jeho podgraf $G'$ vzniklý odebráním orientace hran.
|
||||
|
||||
> Je souvislý alespoň, pokud zapomeneme, že hrany mají směr?
|
||||
|
||||
- **Silně souvislá komponenta / strongly connected component**\
|
||||
Silně souvislá komponenta grafu $G$ je jeho maximální podgraf $G'$ takový, že je silně souvislý. Jinými slovy pro každé dva vrcholy $u, v \in V(G')$ existuje cesta z $u$ do $v$.
|
||||
- **Planární / rovinný graf**\
|
||||
Graf $G$ je planární, pokud se dá nakreslit do roviny tak, že se žádné dvě hrany nekříží.
|
||||
|
||||
Platí v nich Eulerova formule:
|
||||
|
||||
```math
|
||||
\lvert V \rvert - \lvert E \rvert + \lvert F \rvert = 2
|
||||
```
|
||||
|
||||
Kde $\lvert F \rvert$ je počet stěn -- oblastí ohraničených hranami.
|
||||
|
||||
Vrcholy planárního grafu lze vždy obarvit 4 barvami tak, že žádné dva sousední vrcholy nebudou mít stejnou barvu.
|
||||
|
||||
- **(Hranový) řez / (edge) cut**\
|
||||
Množina hran $C \subseteq E(G)$ taková, že po odebrání hran $C$ se graf $G$ rozpadne na více komponent -- $G' = (V, E \setminus C)$ není souvislý.
|
||||
|
||||
Analogicky se definuje i _vrcholový řez / vertex cut_.
|
||||
|
||||
## Reprezentace grafů
|
||||
|
||||
- **Seznam následníků / adjacency list**\
|
||||
Pro každý vrchol $v \in V$ máme seznam (např. dynamic array nebo linked list) $N(v)$ jeho následníků.
|
||||
|
||||
Zabírá $\Theta(\lvert V \rvert + \lvert E \rvert)$ paměti.
|
||||
|
||||
- **Matice sousednosti / adjacency matrix**\
|
||||
Máme matici velikosti $\lvert V \rvert \times \lvert V \rvert$ kde $A_{u,v} = 1$ pokud existuje hrana mezi $u$ a $v$, jinak $A_{u,v} = 0$.
|
||||
|
||||
Dá se pěkně použít k uložení vah.
|
||||
|
||||
- **Matice incidence / incidence matrix**\
|
||||
Máme matici velikosti $\lvert V \rvert \times \lvert E \rvert$ kde $A_{u,e} = 1$ pokud $u$ je vrcholem hrany $e$, jinak $A_{u,e} = 0$.
|
||||
|
||||
Dá se z ní pěkně určit stupeň vrcholu.
|
||||
|
||||
## Prohledávání grafu
|
||||
|
||||
### Prohlédávání do šířky / breadth-first search (BFS)
|
||||
|
||||
Od zadaného vrcholu navštíví nejprve vrcholy vzdálené 1 hranou, poté vrcholy vzdálené 2 hranami, atd.
|
||||
|
||||
- Prohledávání po "vrstvách".
|
||||
- Je implementovaný pomocí _fronty_ (queue / FIFO).
|
||||
- Časová složitost je $\mathcal{O}(\lvert V \rvert + \lvert E \rvert)$.
|
||||
|
||||
```python
|
||||
def dfs(graph: List[List[bool]], stamps: List[int], vertex: int) -> None:
|
||||
if stamps[vertex] == -1:
|
||||
stamps[vertex] = 0
|
||||
stamp = stamps[vertex]
|
||||
for i in range(0, len(graph)):
|
||||
if graph[vertex][i] and stamps[i] != -1:
|
||||
stamps[i] = stamp + 1
|
||||
dfs(graph, stamps, i)
|
||||
```
|
||||
|
||||
### Prohlédávání do hloubky / depth-first search (DFS)
|
||||
|
||||
Od zadaného vrcholu rekurzivně navštěvuje jeho nenavštívené následníky.
|
||||
|
||||
- Prohledání po "slepých uličkách".
|
||||
- Vynořuje se teprve ve chvíli, kdy nemá kam dál (_backtrackuje_).
|
||||
- Je implementovaný pomocí _zásobníku_ (stack / LIFO).
|
||||
- Časová složitost je $\mathcal{O}(\lvert V \rvert + \lvert E \rvert)$.
|
||||
|
||||
```python
|
||||
def bfs(graph: List[List[bool]], stamps: List[int], vertex: int) -> None:
|
||||
stamp = 0
|
||||
queue = deque()
|
||||
queue.append(vertex)
|
||||
while len(queue) > 0:
|
||||
current = queue.popleft()
|
||||
stamps[current] = stamp
|
||||
stamp += 1
|
||||
for i in range(0, len(graph)):
|
||||
if graph[current][i] and stamps[i] == -1:
|
||||
queue.append(i)
|
||||
```
|
||||
|
||||
## Nejkratší vzdálenosti
|
||||
|
||||
Problém nalezení buď nejkratší cesty mezi dvěma vrcholy nebo nejkratší cesty z jednoho vrcholu do všech ostatních.
|
||||
|
||||
- **Relaxace hrany $(u, v)$**\
|
||||
Zkrácení vzdálenosti k vrcholu $v$ průchodem přes vrchol $u$. Musí platit $u\text{.distance} + w(u, v) < v\text{.distance}$. Hrana $(u, v)$ je v takovém případě _napjatá_.
|
||||
|
||||
### Bellman-Fordův algoritmus
|
||||
|
||||
Hledá nejkratší cesty z jednoho vrcholu do všech ostatních.
|
||||
|
||||
- Využívá relaxaci hran.
|
||||
- Funguje i na grafech se zápornými hranami.
|
||||
- Má časovou složitost $\mathcal{O}(\lvert V \rvert \cdot \lvert E \rvert)$.
|
||||
|
||||
```python
|
||||
def bellmanford(graph: List[List[Tuple[int, int]]], s: int) \
|
||||
-> Tuple[bool, List[int], List[int]]:
|
||||
# graph is an adjacency list of tuples (dst, weight)
|
||||
distance = [float('inf') for i in range(0, len(graph))]
|
||||
distance[s] = 0
|
||||
parent = [-1 for i in range(0, len(graph))]
|
||||
|
||||
# relax all edges |V| - 1 times
|
||||
for _ in range(1, len(graph)):
|
||||
for u in range(0, len(graph)):
|
||||
for edge in graph[u]:
|
||||
(v, w) = edge
|
||||
if distance[u] + w < distance[v]:
|
||||
distance[v] = distance[u] + w
|
||||
parent[v] = u
|
||||
|
||||
# check for negative cycles
|
||||
for u in range(0, len(graph)):
|
||||
for edge in graph[u]:
|
||||
(v, w) = edge
|
||||
if distance[u] + w < distance[v]:
|
||||
return (False, None, None)
|
||||
|
||||
return (True, distance, parent)
|
||||
```
|
||||
|
||||
### Dijkstrův algoritmus
|
||||
|
||||
Hledá nejkratší cesty z jednoho vrcholu do všech ostatních.
|
||||
|
||||
- Je podobný BFS, ale používá prioritní frontu.
|
||||
- Funguje **pouze** na grafech **bez záporných** hran.
|
||||
|
||||
**💡 TIP**\
|
||||
Složitost závisí na implementaci prioritní fronty. Je to $\Theta(V)$ insertů, $\Theta(V)$ hledání nejmenšího prvku, $\Theta(E)$ snížení priority.
|
||||
|
||||
**📌 NOTE**\
|
||||
Implementace níže používá pole (resp. Pythoní `list`), tedy složitost je $\Theta(V^2)$, jelikož hledání minima je lineární.
|
||||
|
||||
```python
|
||||
def dijkstra(graph: List[List[Tuple[int, int]]], s: int) \
|
||||
-> Tuple[List[int], List[int]]:
|
||||
# graph is an adjacency list of tuples (dst, weight)
|
||||
distance = [float('inf') for i in range(0, len(graph))]
|
||||
distance[s] = 0
|
||||
parent = [-1 for i in range(0, len(graph))]
|
||||
|
||||
queue = list(range(0, len(graph)))
|
||||
while len(queue) > 0:
|
||||
u = min(queue, lambda v: distance[v])
|
||||
queue.remove(u)
|
||||
for edge in graph[current]:
|
||||
(v, w) = edge
|
||||
if distance[u] + w < distance[v]:
|
||||
distance[v] = distance[u] + w
|
||||
parent[v] = u
|
||||
return (distance, parent)
|
||||
```
|
||||
|
||||
V binární haldě by to bylo $\Theta(V \log V + E \log V)$ a ve Fibonacciho haldě $\Theta(V \log V + E)$.
|
||||
|
||||
Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší cesta mezi dvěma konkrétními vrcholy:
|
||||
|
||||
- Funkce vrátí výsledek, jakmile je cílový vrchol vytažen z fronty.
|
||||
- Můžeme hledat zároveň ze začátku a konce pomocí dvou front a skončit, jakmile se někde potkají.
|
||||
- Můžeme přidat _potenciál_ -- dodatečnou heuristickou váhu.
|
||||
|
||||
**❗ IMPORTANT**\
|
||||
Téhle variantě se říká A\* (A star). Věnuje se mu část otázky [Umělá inteligence v počítačových hrách](../umela-inteligence-v-pocitacovych-hrach/).
|
||||
|
||||
## Kostry
|
||||
|
||||
- **Spanning tree / kostra**\
|
||||
Kostra grafu $G = (V, E)$ je podgraf $T \sube G$ takový, že $V(T) = V(G)$ je $T$ je strom.
|
||||
|
||||

|
||||
|
||||
- **Minimum spanning tree (MST) / minimální kostra**\
|
||||
Je kostra $M$ grafu $G$ s nejmenší možnou váhou. Tedy pro každou kostru $T$ grafu $G$:
|
||||
|
||||
```math
|
||||
w(M) \le w(T)
|
||||
```
|
||||
|
||||
- **Fundamental cycle**\
|
||||
Fundamental cycle je cyklus $C$ v grafu $G$ takový, že odebráním libovolné hrany $e \in C$ získáme kostru.
|
||||
- **Fundamental cutset / řez**\
|
||||
Fundamental cutset je množina hran $D$ v grafu $G$ taková, že přidáním libovolné hrany $e \in D$ získáme kostru.
|
||||
- **Red rule**\
|
||||
Najdi cyklus bez červených hran, vyber v něm **neobarvenou** hranu s **nejvyšší** cenou a obarvi ji červeně.
|
||||
- **Blue rule**\
|
||||
Najdi řez bez modrých hran, vyber v něm **neobarvenou** hranu s **nejmenší** cenou a obarvi ji modře.
|
||||
- **Greedy algoritmus**\
|
||||
Nedeterministicky aplikuj red rule a blue rule, dokud to jde (stačí $n-1$ iterací). Modré hrany tvoří MST.
|
||||
- **Jarníkův / Primův algoritmus**\
|
||||
Speciální případ greedy algoritmu, kdy aplikujeme pouze blue rule. Princip:
|
||||
|
||||
1. Vyber libovolný vrchol $v$ a přidej ho do kostry $S$.
|
||||
2. Opakuj $n-1$ krát:
|
||||
1. Vyber hranu $e$ s nejmenší cenou, která má právě jeden vrchol v $S$.
|
||||
2. Přidej druhý vrchol $e$ do $S$.
|
||||
|
||||
_Složitost_: použijeme binární haldu
|
||||
|
||||
- Inicializace ($\infty$ jako cena hrany mezi prázdnou kostrou a každým vrcholem): $\mathcal{O}( \lvert V \rvert )$
|
||||
- Odstranění minima z binární haldy pro každý vrchol ve $V$: $\mathcal{O}( \lvert V \rvert \log \lvert V \rvert )$
|
||||
- Procházení každé hrany z $E$ a snižování ceny: $\mathcal{O}( \lvert E \rvert \log \lvert V \rvert )$
|
||||
- Celková složitost: $\mathcal{O}( \lvert E \rvert \log \lvert V \rvert )$
|
||||
- S Fibonacciho haldou jde zlepšit na: $\mathcal{O}( \lvert E \rvert + \lvert V \rvert \log \lvert V \rvert )$
|
||||
|
||||
- **Kruskalův algoritmus**\
|
||||
Princip: Seřaď hrany podle ceny vzestupně. Postupně přidávej hrany do kostry, vynechej ty, které by vytvořily cyklus.
|
||||
|
||||
1. Seřad hrany podle ceny vzestupně.
|
||||
2. Použij _union-find_ na udržování komponent grafu.
|
||||
3. Procházej hrany postupně. Pokud oba konce hrany patří do různých množin, přidej ji.
|
||||
|
||||
Je to speciální případ greedy algoritmu.
|
||||
|
||||
_Složitost_:
|
||||
|
||||
- Inicializace union-findu: $\mathcal{O}( \lvert V \rvert )$
|
||||
- Seřazení hran: $\mathcal{O}( \lvert E \rvert \log \lvert E \rvert )$
|
||||
- Pro každou hranu provádíme dvakrát `find` ($\mathcal{O}(\log \lvert V \rvert )$) a eventuálně `union` ($\mathcal{O}(\log \lvert V \rvert )$): $\mathcal{O}( \lvert E \rvert \log \lvert V \rvert )$
|
||||
- Celková složitost: $\mathcal{O}( \lvert E \rvert \log \lvert V \rvert )$
|
||||
|
||||
- **Borůvkův algoritmus**\
|
||||
Je "paralelní". Buduje modré stromy ze všech vrcholů naráz.
|
||||
|
||||
1. Pro každý vrchol inicializuj modrý strom.
|
||||
2. Dokud nemáš jen jeden modrý strom, opakuj _fázi_:
|
||||
1. Pro každý modrý strom najdi nejlevnější odchozí hranu a přidej ji (propojíš tak dva stromy).
|
||||
|
||||
Je to speciální případ greedy algoritmu, který spamuje jen blue rule.
|
||||
|
||||
_Složitost:_
|
||||
|
||||
- Počet komponent v první fázi: $\lvert V \rvert$.
|
||||
- V každé fázi se zmenší počet komponent na polovin. Tím pádem bude $\log \lvert V \rvert$ fází.
|
||||
- Každá fáze zabere $\mathcal{O}( \lvert E \rvert )$ času, protože procházíme všechny hrany.
|
||||
- Celková složitost: $\mathcal{O}( \lvert E \rvert \log \lvert V \rvert )$
|
||||
|
||||
**💡 TIP**\
|
||||
Kruskal sice taky buduje stromy na více místech najednou, ale není "paralelní", protože minimalita kostry spoléhá na to, že hrany jsou seřazené. Borůvka takový požadavek nemá, a proto je paralelizovatelnější.
|
||||
|
||||
**Složitosti algoritmů**
|
||||
|
||||
| Algoritmus |
|
||||
| ---------------------------------------------------------------------- | --------------------------------- | ---------------------------------- |
|
||||
| Časová složitost | Prostorová složitost | Jarník (Prim) s prioritní frontou |
|
||||
| $\mathcal{O}(\lvert E \rvert \log \lvert V \rvert )$ | $\mathcal{O}( \lvert V \rvert )$ | Jarník (Prim) s Fibonacciho haldou |
|
||||
| $\mathcal{O}(\lvert E \rvert + \lvert V \rvert \log \lvert V \rvert )$ | $\mathcal{O}( \lvert V \rvert )$ | Kruskal |
|
||||
| $\mathcal{O}(\lvert E \rvert \log \lvert V \rvert )$ | $\mathcal{O}( \lvert V \rvert )$ | Borůvka |
|
||||
|
||||
## Toky v sítích
|
||||
|
||||
- **Síť toků / flow network**\
|
||||
Je čtveřice $(G, s, t, c)$, kde:
|
||||
|
||||
- $G = (V, E)$ je orientovaný graf,
|
||||
- $s \in V$ je zdroj / source,
|
||||
- $t \in V$ je cíl / stok / sink; $s \neq t$,
|
||||
- $c: E \rightarrow \mathbb{R}^+$ je funkce udávající kapacitu hran.
|
||||
|
||||
- **Network flow / tok**\
|
||||
Je funkce $f: E \rightarrow \mathbb{R}^+$, která splňuje:
|
||||
|
||||
- podmínku kapacity: $(\forall e \in E)(f(e) \ge 0 \land f(e) \leq c(e))$
|
||||
- _tok hranou je nezáporný a nepřevyšuje povolennou kapacitu_
|
||||
- podmínku kontinuity: $(\forall v \in V \setminus \{s, t\})(\sum_{e \in \delta^+(v)} f(e) = \sum_{e \in \delta^-(v)} f(e))$
|
||||
- _tok do vrcholu je stejný jako tok z vrcholu_
|
||||
|
||||
- **Hodnota toku $f$**
|
||||
|
||||
```math
|
||||
\lvert f \rvert = \sum_{(s, v) \in E} f(s, v) = \sum_{(w, t) \in E} f(w, t)
|
||||
```
|
||||
|
||||
### Ford-Fulkerson
|
||||
|
||||
- **Residual network**\
|
||||
Síť, která vzniká, když je už část kapacity hrany využívána tokem $f$. Umožnuje algoritmům změnit přechozí rozhodnutí a získat využitou kapacitu zpět.
|
||||
|
||||
Je to pětice $G_f = (V, E_f, s, t, c_f)$, kde
|
||||
|
||||
- $E_f = \{ e \in E : f(e) < c(e) \} \cup \{ e^R : f(e) > 0 \}$,
|
||||
- pokud $e = (u, v) \in E$, $e^R = (v, u)$,
|
||||
- stem:[
|
||||
c_f(e) = \begin{cases}
|
||||
c(e) - f(e) & \text{ pokud } e \in E \\
|
||||
f(e) & \text{ pokud } e^R \in E
|
||||
\end{cases}
|
||||
]
|
||||
|
||||
- **Augmenting path $P$**\
|
||||
Jednoduchá $s \rightsquigarrow t$ cesta v residuální síti $G_f$.
|
||||
|
||||
**📌 NOTE**\
|
||||
T.j. cesta která může jít i proti směru toku $f$.
|
||||
|
||||
_Bottleneck kapacita_ je nejmenší kapacita hran v augmenting path $P$.
|
||||
|
||||
To krásné na augmenting cestách je, že pro flow $f$ a augmenting path $P$ v grafu $G_f$, existuje tok $f'$ takový, že $\text{val}(f') = \text{val}(f) + \text{bottleneck}(G_f, P)$. Nový tok $f'$ lze získat takto:
|
||||
|
||||
```
|
||||
*Augment*(f, c, P)
|
||||
{
|
||||
delta = bottleneck(P)
|
||||
*foreach*(e in P)
|
||||
{
|
||||
*if*(e in E)
|
||||
{
|
||||
f[e] = f[e] + delta
|
||||
}
|
||||
*else*
|
||||
{
|
||||
f[reverse(e)] = f[reverse(e)] - delta
|
||||
}
|
||||
}
|
||||
*return* f
|
||||
}
|
||||
```
|
||||
|
||||
- **Algoritmus Ford-Fulkerson**\
|
||||
Hledá maximální tok. Augmentuje cestu v residuální síti dokud to jde.
|
||||
|
||||
1. $f(e) = 0$ pro každou $e \in E$.
|
||||
2. Najdi $s \rightsquigarrow t$ cestu $P$ v reziduální síti $G_f$.
|
||||
3. Augmentuj tok podél $P$.
|
||||
4. Opakuj dokud se nezasekneš.
|
||||
|
||||
```
|
||||
*Ford-Fulkerson*(G)
|
||||
{
|
||||
*foreach* (e in E)
|
||||
{
|
||||
f(e) = 0
|
||||
}
|
||||
|
||||
G_f = reziduální síť vzniklá z G vzhledem k toku f
|
||||
*while* (existuje s ~> t cesta v G_f)
|
||||
{
|
||||
f = Augment(f, c, P)
|
||||
Updatuj G_f
|
||||
}
|
||||
*return* f
|
||||
}
|
||||
```
|
||||
|
||||
### Push-Relabel
|
||||
|
||||
- **Pre-flow**\
|
||||
_Ne-tak-docela tok._
|
||||
|
||||
Funkce $f$ taková, že
|
||||
|
||||
- platí _kapacitní podmínka_: $(\forall e \in E)(0 \le f(e) \le c(e))$,
|
||||
- platí _relaxováné zachování toku_: stem:[
|
||||
(\forall v \in V - \{ s, t \})(\sum_{e \text{ do } v} f(e) \ge \sum_{e \text{ ven z } v} f(e))
|
||||
].
|
||||
|
||||
- **Overflowing vertex**\
|
||||
Takový vertex $v \in V - \{ s, t \}$, do kterého více přitéká než odtéká.
|
||||
|
||||
```math
|
||||
\sum_{e \text{ do } v} f(e) > \sum_{e \text{ ven z } v} f(e)
|
||||
```
|
||||
|
||||
- **Excess flow**\
|
||||
To, co je v overflowing vertexu navíc.
|
||||
|
||||
```math
|
||||
e_f(v) = \sum_{e \text{ do } v} f(e) - \sum_{e \text{ ven z } v} f(e)
|
||||
```
|
||||
|
||||
- **Height function**\
|
||||
Funkce $h : V \to \N_0$. Řekneme, že $h$ je _kompatibilní s preflow $f$_, právě když
|
||||
|
||||
- _source_: $h(s) = |V| = n$,
|
||||
- _sink_: $h(t) = 0$,
|
||||
- _height difference_: $(\forall (v, w) \in E_{G_f})(h(v) \le h(w) + 1)$.
|
||||
|
||||
**📌 NOTE**\
|
||||
Pokud mezi dvěma vrcholy $(v, w)$ v reziduální síti vede hrana, pak je $v$ nejvýše o jednu úroveň výš než $w$.
|
||||
|
||||
- **Push operace**\
|
||||
Pro (reziduálně-grafovou) hranu $(v, w)$ se pokusí přesunout excess flow z $v$ do $w$, aniž by porušil (reziduální) kapacitu $(v, w)$.
|
||||
|
||||
```
|
||||
// Assumptions: e_f[v] > 0, c_f( (v, w) > 0) > 0, h[v] > h[w]
|
||||
*Push*(f, h, v, w)
|
||||
{
|
||||
delta_f = min(e_f[v], c_f(v, w))
|
||||
*if*( (v, w) in E)
|
||||
f[(v, w)] += delta_f
|
||||
*else*
|
||||
f[(w, v)] -= delta_f
|
||||
e_f[v] -= delta_f
|
||||
e_f[w] += delta_f
|
||||
}
|
||||
```
|
||||
|
||||
- **Relabel operace**\
|
||||
Zvýší výšku $h(v)$ natolik, aby neporušil kompatibilitu $h$ s $f$.
|
||||
|
||||
```
|
||||
// Assumptions:
|
||||
// - v is overflowing: e_f[v] > 0
|
||||
// - all residual neighbors of v the same height or higher:
|
||||
// forall (v, w) in E_f: h[v] \<= h[w]
|
||||
*Relabel*(f, h, v)
|
||||
{
|
||||
h[v] = 1 + min(h[w] | (v, w) in E_f)
|
||||
}
|
||||
```
|
||||
|
||||
- **Algoritmus Push-Relabel (Goldberg-Tarjan)**\
|
||||
Hledá maximální tok.
|
||||
|
||||
Princip: Pokud je nějaký vrchol overflowing, tak ho pushni nebo relabeluj. Pokud ne, tak jsi našel maximální tok.
|
||||
|
||||
```
|
||||
*Push-Relabel*(V, E, s, t, c)
|
||||
{
|
||||
// initialize preflow -- default values
|
||||
*for*(v in V)
|
||||
{
|
||||
h[v] = 0 // height function
|
||||
e_f[v] = 0 // excess flow
|
||||
}
|
||||
n = |V|
|
||||
h[s] = n
|
||||
|
||||
*for*(e in E)
|
||||
{
|
||||
f[e] = 0 // (pre)flow
|
||||
}
|
||||
|
||||
// initialize preflow -- saturate connections from s
|
||||
*for*( (s, v) in E)
|
||||
{
|
||||
f[(s, v)] = c(s, v) // preflow maxes out all capacity
|
||||
e_f[v] = c(s, v) // presume all of it excess
|
||||
e_f[s] -= c(s, v) // yes, it will be negative
|
||||
}
|
||||
|
||||
// the juicy part
|
||||
*while*(_any vertex is overflowing_)
|
||||
{
|
||||
v = _an overflowing vertex_ (has e_f[v] > 0)
|
||||
*if*(v _has a neighbor_ w _in_ G_f _such that_ h(v) > h(w))
|
||||
{
|
||||
*Push*(f, h, v, w)
|
||||
}
|
||||
else
|
||||
{
|
||||
*Relabel*(f, h, v)
|
||||
}
|
||||
}
|
||||
*return* f
|
||||
}
|
||||
```
|
||||
|
||||
_Korektnost_: V průběhu výpočtu platí:
|
||||
|
||||
- Výška vrcholu nikdy neklesá.
|
||||
- Pre-flow a výšková funkce jsou kompatibilní.
|
||||
|
||||
_Složitost_:
|
||||
|
||||
- Nejvýše $2^n$ Relabelů.
|
||||
- $2nm$ saturujících Push.
|
||||
- $4n^2m$ nesaturujících Push.
|
||||
- Relabel i Push jsou v $\mathcal{O}(1)$.
|
||||
- Celkem: $O(n^2m)$.
|
||||
|
||||
---
|
||||
|
||||
**Srovnání algoritmů Ford-Fulkerson a Push-Relabel**
|
||||
|
||||
| Ford-Fulkerson |
|
||||
| ----------------------- | ------------------------------------ |
|
||||
| Push-Relabel (Goldberg) | global character |
|
||||
| local character | update flow along an augmenting path |
|
||||
| update flow on edges | flow conservation |
|
||||
|
||||
## Maximální párování v bipartitních grafech
|
||||
|
||||
- **Párování / matching**\
|
||||
Množina $M \sube E$ taková, že žádné dvě hrany v $M$ nemají společný vrchol. [matching](#matching)
|
||||
|
||||
Prázdná množina je párováním na každém grafu. Graf bez hran má pouze prázdné párování.
|
||||
|
||||
**Příklad párování, které je zároveň maximální by [RRPPGG](https://commons.wikimedia.org/w/index.php?curid=45306558)**
|
||||
|
||||

|
||||
|
||||
- **Maximální párování**\
|
||||
Takové párování, které má nejvyšší počet hran. Graf může mít několik maximálních párování.
|
||||
- **Perfektní párování**\
|
||||
Takové párování, které páruje všechny vrcholy grafu. Každé perfektní párování je zároveň maximální.
|
||||
- **Maximum cardinality matching (MCM) v bipartitním grafu**\
|
||||
Problém nalezení maximálního párování v grafu. Ve speciálním případě, kdy graf je bipartitní, se tento problém dá převést na problém nalezení maximálního toku v síti: [mcm](#mcm)
|
||||
|
||||
1. Mejmě bipartitní graf $G=(X+Y,E)$.
|
||||
|
||||

|
||||
|
||||
2. Přidej zdroj $s$ a hranu $(s, v)$ pro každý vrchol $v$ z $X$.
|
||||
3. Přidej stok $t$ a ranu $(v, t)$ pro každý vrchol $v$ z $Y$.
|
||||
|
||||

|
||||
|
||||
4. Každé hraně dej kapacitu 1.
|
||||
5. Spusť algoritmus Ford-Fulkerson.
|
||||
|
||||

|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[ib000,1]]] [IB000 Matematické základy informatiky (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/IB000/um/)
|
||||
- [[[ib002,2]]] [IB002 Algoritmy a datové struktury (jaro 2020)](https://is.muni.cz/auth/el/fi/jaro2020/IB002/um/)
|
||||
- [[[ib003,3]]] [IV003 Algoritmy a datové struktury II (jaro 2021)](https://is.muni.cz/auth/el/fi/jaro2021/IV003/um/)
|
||||
- [[[matching,4]]] [Wikipedia: Párování grafu](https://cs.wikipedia.org/wiki/P%C3%A1rov%C3%A1n%C3%AD_grafu)
|
||||
- [[[mcm, 5]]] [Wikipedia: Maximum cardinality matching](https://en.wikipedia.org/wiki/Maximum_cardinality_matching)
|
||||
|
||||
## Další zdroje
|
||||
|
||||
- [Vizualizace max-flow algoritmů](https://visualgo.net/en/maxflow)
|
||||
- [Vizualizace push-relabel](http://www.adrian-haarbach.de/idp-graph-algorithms/implementation/maxflow-push-relabel/index_en.html)
|
@ -1,5 +1,5 @@
|
||||
---
|
||||
title: 8. Modelování a projekce
|
||||
title: Modelování a projekce
|
||||
description: A guide in my new Starlight docs site.
|
||||
---
|
||||
|
||||
|
814
src/content/docs/szmgr/SZP09_zpracovani_obrazu.md
Normal file
814
src/content/docs/szmgr/SZP09_zpracovani_obrazu.md
Normal file
@ -0,0 +1,814 @@
|
||||
---
|
||||
title: "Zpracování rastrového obrazu"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Bodové transformace. Histogram, vyrovnání histogramu, analýza histogramu. Lineární a nelineární filtry. Detekce hran. Fourierova transformace. Vzorkovací teorém, převzorkování, geometrické transformace. Vlnková transformace. Houghova/Radonova transformace.
|
||||
|
||||
_PB130/PV131_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
- **Rastr / bitmapa**\
|
||||
Obraz reprezentovaný pomocí 2D pole _pixelů_. Každý pixel obsahuje jednu (pokud je obraz černobílý) nebo více (typicky RGB nebo CMYK) intenzit. Intenzity jsou zakódovány na _bity_. [raster](#raster)
|
||||
|
||||
> Je to 2D mapa bitů... bitmapa. Get it?
|
||||
|
||||
- **Zpracování obrazu / digital image processing**\
|
||||
Oblast informatiky zabývající se manipulací s obrazy pomocí počítače. Obsahuje třeba: [dip](#dip)
|
||||
|
||||
- zpracování raw dat ze senzorů ve foťácích,
|
||||
- odstranění šumu,
|
||||
- zvýraznění hran,
|
||||
- zvýšení kontrastu,
|
||||
- detekci tváří,
|
||||
- rozpoznávání objektů,
|
||||
- rozpoznávání textu -- _optical character recognition_ (OCR).
|
||||
|
||||
- **Klasifikace transformací**
|
||||
- Neměnící geometrii obrazu
|
||||
- Bodové
|
||||
- Lokální
|
||||
- Globální
|
||||
- Geometrické
|
||||
|
||||
## Bodové transformace
|
||||
|
||||
Transformace hodnot pixelů **nezávisle** na jejich okolí. Nemění velikost obrazu.
|
||||
|
||||
### Homogenní
|
||||
|
||||
Bodové transformace, které **nezávisí** na pozici pixelu v obraze. Je definována pomocí _převodní funkce_ $I'(u, v) \leftarrow f(I(u,v))$. Patří sem třeba:
|
||||
|
||||
- úprava jasu,
|
||||
- úprava kontrastu,
|
||||
- hue, saturation, atd.,
|
||||
- gama korekce,
|
||||
- globální prahování.
|
||||
|
||||
#### Lineární transformace
|
||||
|
||||
Převodní funkce je lineární, definována, jako $f(a) = ka + q$.
|
||||
|
||||
- Identita: $k = 1, q = 0$
|
||||
- Inverze intenzit (negativ): $k = -1, q = a_{max}$
|
||||
- Zvýšení jasu: $k = 1, q > 0$
|
||||
- Snížení jasu: $k = 1, q < 0$
|
||||
- Zvýšení kontrastu: $k > 1, q = 0$
|
||||
- Snížení kontrastu: $0 < k < 1, q = 0$
|
||||
- Lineární roztažení: viz dále
|
||||
- (Percentilové roztažení: viz dále)
|
||||
- **Negativ**\
|
||||
Inverze hodnot pixelů. Nejvyšší hodnota se změní na nejnižší a naopak.
|
||||
|
||||
Pokud maximální intenzita je 255 pak negativ je definován jako:
|
||||
|
||||
```math
|
||||
f(x) = 255 - x
|
||||
```
|
||||
|
||||
- **Lineární roztažení**\
|
||||
Přemapování rozsahu intenzit $(a_\text{low}, a_\text{high})$ na rozsah $(a_\text{min}, a_\text{max})$ pomocí lineární interpolace. Často ke zvýraznění kontrastu.
|
||||
|
||||
```math
|
||||
f(x) = \frac{a_\text{max} - a_\text{min}}{a_\text{high}-a_\text{low}} \cdot (x - a_\text{min}) + a_\text{min}
|
||||
```
|
||||
|
||||
kde $a_\text{low}$ je nejnižší hodnota a $a_\text{high}$ nejvyšší hodnota v obraze. Obvykle $a_\text{min} = 0$ a $a_\text{max} = 255$.
|
||||
|
||||
Alternativně lze použít **percentilové roztažení**, které převede $p$ procent nejnižších a nejvyšších hodnot na $a_\text{min}$ a $a_\text{max}$ (tedy "uřízne" extrémy). není striktně řečeno lineární.
|
||||
|
||||
#### Nelineární transformace
|
||||
|
||||
Převod nelze vyjádřit v lineárním tvaru
|
||||
|
||||
- **Gama korekce**\
|
||||
Nelineární bodová transformace kompenzující vlastnosti lidského oka pro lepší využití bitové hloubky.
|
||||
|
||||
1. Vstupní obraz je normalizován na rozsah $(0, 1)$.
|
||||
2. Každá hodnota $x$ je transformována typicky pomocí $x^\gamma$.
|
||||
3. Výsledný obraz je přeškálován na původní rozsah.
|
||||
|
||||

|
||||
|
||||
- **Kvantizace**\
|
||||
Nelineární bodová transformace, která snižuje bitovou hloubku obrazu. Výsledkem je obraz s menším počtem barev.
|
||||
|
||||
> Může vypadat cool. Viz toon shading.
|
||||
|
||||
- **Prahování / thresholding**\
|
||||
Nelineární bodová transformace, která rozdělí obraz na dvě skupiny podle intenzity. Výsledkem je binární obraz.
|
||||
|
||||
```math
|
||||
f(x) = \begin{cases} 0 & \text{pokud } x < T \\ 1 & \text{pokud } x \geq T \end{cases}
|
||||
```
|
||||
|
||||
kde $T$ je práh. Pokud je $T$ konstanta, pak se jedná o _globální prahování_.
|
||||
|
||||
Prahování se pořádně věnuje otázka [Analýza rastrového obrazu](../analyza-rastroveho-obrazu/).
|
||||
|
||||
- **Paleta**\
|
||||
Můžeme použít funkci či vyhledávácí tabulku pro přemapování existujících hodnot v obrazu na jiné (viz barevné škály u vizualizací).
|
||||
|
||||
### Nehomogenní
|
||||
|
||||
Bodové transformace, které **závisí** na pozici pixelu v obraze. Je definována pomocí _převodní charakteristiky_ $I'(u, v) \leftarrow f(I(u,v), u,v)$. Patří sem třeba:
|
||||
|
||||
- korekce nerovnoměrného osvětlení,
|
||||
- vignette,
|
||||
- přechodové filtry.
|
||||
|
||||
## Histogramy
|
||||
|
||||
Histogram kvantifikuje množství a frekvenci barev obsažených v obraze. Ve statické terminologii je to aproximace hustoty pravděpodobnosti.
|
||||
|
||||
- Hodnota histogramu $H$ v indexu $i$ odpovídá počtu pixelů v obraze s intenzitou $i$.
|
||||
- Šedotónní obraz má jeden histogram. RGB obraz má tři.
|
||||
|
||||
- **Kumulativní histogram**\
|
||||
Kumulativní histogram $\mathbb{H}$ bbsahuje množství pixelů s intenzitou **menší nebo rovnou** než $i$. Ve statické terminologii je to aproximace distribuční funkce.
|
||||
|
||||
```math
|
||||
\mathbb{H} \lbrack i \rbrack = \sum_{j=0}^{i} H \lbrack j \rbrack
|
||||
```
|
||||
|
||||
- **Vyrovnání histogramu / histogram equalization**\
|
||||
Změna obrazu tak, aby jeho kumulativní histogram měl konkrétní tvar, obvykle aby byl lineární. [histogram-eq](#histogram-eq)
|
||||
|
||||
Typicky k tomu využíváme funkci $f(x) = \mathbb{H}[x] \cdot \frac{a_{\text{max}}}{w \cdot h}$, kde $\text{cumhist}$ je kumulativní histogram pro barvu v bodě x, $a_{\text{max}}$ je maximální intenzita a $w \cdot h$ je velikost obrazu.
|
||||
|
||||
**Před vyrovnáním histogramu**
|
||||
|
||||

|
||||

|
||||
|
||||
**Po vyrovnání histogramu**
|
||||
|
||||

|
||||

|
||||
|
||||
**📌 NOTE**\
|
||||
Původní fotku vyfotil [Phillip](https://commons.wikimedia.org/w/index.php?curid=855363) [Capper](https://commons.wikimedia.org/w/index.php?curid=855383).
|
||||
|
||||
- **Analýza histogramu**\
|
||||
Z histogramu lze vysledovat řadu věcí jak manuálně tak automaticky. Často se proto používá jako mezikrok v jiných algoritmech. Lze z něj například zjistit: [histogram](#histogram) [histogram-bbc](#histogram-bbc)
|
||||
|
||||
- průměrný jas,
|
||||
- kontrast,
|
||||
- vztah mezi mediánem a střední hodnotou,
|
||||
- přepaly a podexponované oblasti,
|
||||
- šikmost / skewness.
|
||||
|
||||
## Konvoluční filtry
|
||||
|
||||
- **Filtr**\
|
||||
Filtr je termín ze zpracování signálů (kterýmžto obraz z jisté perspektivy je). Je to zařízení, postup, či transformace, která ze signálu odstraňuje nechtěnné informace. [filter](#filter)
|
||||
- **Šum / noise**\
|
||||
Šum je informace, která v obrazu vznikla kvůli nedokonalosti snímače, přenosu, uložení dat, atd. Ač někdy může vypadat docela cool, obvykle je to nechtěná informace. Podle frekvenční charakteristiky se dělí na:
|
||||
|
||||
- _bílý šum_: má stejnou energii ve všech frekvencích; je to jen matematická abstrakce,
|
||||
- _Poissonův šum / photon noise_: vzniká při náhodném procesu, jako je například dopad světla na snímač,
|
||||
- _Aditivní_: přidává se k signálu; $g = f + n$, kde $f$ je originální funkce signálu a $n$ je šum,
|
||||
- _Impulzní_: nahrazuje některé hodnoty signálu jinými hodnotami; patří sem například _sůl a pepř / salt and pepper noise_.
|
||||
|
||||
- **Konvoluce**\
|
||||
Matematická operace, která vezme dvě funkce $f$ a $g$ a produkuje třetí funkci $h = f * g$ popisující, jak jedna funkce mění tvar té druhé. Je komutativní, takže je jedno, která je _první_ a která je _druhá_. Ve spojité doméně je definována jako: [convolution](#convolution)
|
||||
|
||||
```math
|
||||
(f * g)(t) = \int_{-\infty}^{\infty} \cdot f(\tau) g(t - \tau) d\tau
|
||||
```
|
||||
|
||||
Pokud jsou funkce $f$ a $g$ diskrétní a $g$ navíc je doména (množina povolených vstupů) $g$ konečná a je třeba $\{ -M, -M+1, ..., M-1, M \}$, pak se používá _diskrétní konvoluce_:
|
||||
|
||||
```math
|
||||
(f * g) \lbrack t \rbrack = \sum_{m = -\infty}^\infty f \lbrack m \rbrack \cdot g \lbrack t - m \rbrack
|
||||
```
|
||||
|
||||
Obrazy však mají dvě dimenze, takže se používá dvourozměrná diskrétní konvoluce:
|
||||
|
||||
```math
|
||||
(f * g) \lbrack x, y \rbrack = \sum_{m = -k}^k \sum_{n = -k}^k f \lbrack x - m, x - n \rbrack \cdot g \lbrack m, n \rbrack
|
||||
```
|
||||
|
||||
kde $h$ je _kernel / konvoluční jádro_ dáno jako matice velikosti $(2k + 1) \times (2k + 1)$.
|
||||
|
||||
**⚠️ WARNING**\
|
||||
Všimni si, že kvůli $f \lbrack x - m, x - n \rbrack$ se jádro při aplikaci na obraz překlápí. Kdyby to bylo $f \lbrack x + m, x + n \rbrack$, tak jde o **korelaci**, ne o konvoluci.
|
||||
|
||||
Konvoluce má složitost $O(MNKL)$, kde $M \times N$ je velikost obrazu a $K \times L$ je velikost jádra. Pro velká jádra se složitost blíží $O(M^2 N^2)$.
|
||||
|
||||
Konvoluce je **komutativní**, **asociativní**, **xy separabilní** (lze ji rozdělit na dvě jednorozměrné konvoluce, pokud platí, že $H_{x,y}(i,j) = H_x(i) \cdot H_y(j)$), a **lineární** (tedy lze ji **násobit skalárem** a **sčítat**).
|
||||
|
||||
- **Okrajové hodnoty**\
|
||||
Je důležité si uvědomit, že na okrajích obrazu nelze aplikovat konvoluci tak, jak je definována. Existuje několik způsobů, jak s tímto problémem pracovat:
|
||||
|
||||
- _Doplnění nulami_: okraje se doplní nulami,
|
||||
- _Doplnění nejbližší hodnotou_: okraje se doplní hodnotou nejbližšího pixelu,
|
||||
- _Doplnění zrcadlením_: okraje se doplní hodnotami jako podle zrcadla,
|
||||
- _Doplnění periodickým opakováním_: okraje se doplní hodnotami z opačné strany obrazu.
|
||||
- _Zmenšení okolí pro pixely u krajů obrazu_: pixely mimo obraz se ignorují.
|
||||
|
||||

|
||||
|
||||
### Lineární
|
||||
|
||||
- **Lineární filtr**\
|
||||
Je takový filtr $\Theta: \mathbb{I}^{w \times h} \to \mathbb{I}^{w \times h}$, kde $\mathbb{I}$ je množina povolených hodnot pixelů v obraze a $\mathbb{I}^{w \times h}$ je množina všech obrazů s šířkou $w$ a výškou $h$. Musí splňovat _podmínky linearity_:
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
|
||||
a \cdot \Theta(I) &= \Theta(a \cdot I) \\
|
||||
\Theta(I_1 + I_2) &= \Theta(I_1) + \Theta(I_2)
|
||||
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
kde $I, I_1, I_2$ jsou obrazy a $a$ je skalární hodnota.
|
||||
|
||||
- **Posunutí**\
|
||||
Jednoduchý lineární filtr, který posune obraz o nějaký vektor.
|
||||
|
||||
```math
|
||||
\begin{bmatrix}
|
||||
0 & 0 & 0 \\
|
||||
0 & 0 & 0 \\
|
||||
0 & 0 & 1
|
||||
\end{bmatrix}
|
||||
```
|
||||
|
||||
- **Box filtr / box blur**\
|
||||
Rozmazání pomocí okolních pixelů.
|
||||
|
||||
```math
|
||||
\frac{1}{9} \cdot
|
||||
\begin{bmatrix}
|
||||
1 & 1 & 1 \\
|
||||
1 & 1 & 1 \\
|
||||
1 & 1 & 1
|
||||
\end{bmatrix}
|
||||
```
|
||||
|
||||
- **Gaussian filtr / Gaussian blur**\
|
||||
Rozmazání pomocí okolních pixelů s Gaussovským váhováním, kde $\sigma$ je parametr určující šířku Gaussova zvonu.
|
||||
- **Rozdílové filtry**\
|
||||
Filtry, které počítají rozdíly mezi okolními pixely. Často se využívají pro detekci hran (viz dále).
|
||||
|
||||
### Nelineární
|
||||
|
||||
Nelineární filtry jsou takové filtry, které nejsou lineární. (_Duh._) Tedy nesplňují podmínky linearity.
|
||||
|
||||
## Detekce hran
|
||||
|
||||
Proces, kdy hledání _hran_ v obraze. Hrana je křivka, podél níž pixely výrazně mění intenzitu -- výrazně se mění gradient.
|
||||
|
||||
- Detekce hran je důležitá při identifikaci objektů a počítačovém vidění.
|
||||
- Bývá implementováná pomocí (první, druhé) derivace (resp. numerické diferenciace).
|
||||
- Hrany lze detekovat pomocí konvoluce.
|
||||
|
||||
**❗ IMPORTANT**\
|
||||
Numerické diferenciaci se věnuje otázka [Numerické metody](../numericke-metody/).
|
||||
|
||||
### Podle první derivace (gradientu)
|
||||
|
||||
- **Prewittové operátor / Prewitt operator**\
|
||||
Aproximuje velikost gradientu pomocí **centrálních** konečných diferencí. Skládá se ze dvou konvolucí s jádry:
|
||||
|
||||
```math
|
||||
P_x = \begin{bmatrix} -1 & 0 & 1 \\ -1 & 0 & 1 \\ -1 & 0 & 1 \end{bmatrix} \qquad
|
||||
P_y = \begin{bmatrix} 1 & 1 & 1 \\ 0 & 0 & 0 \\ -1 & -1 & -1 \end{bmatrix}
|
||||
```
|
||||
|
||||
Které se dají odseparovat na:
|
||||
|
||||
```math
|
||||
P_x = \begin{bmatrix} -1 \\ 0 \\ 1 \end{bmatrix} \cdot \begin{bmatrix} 1 & 1 & 1 \end{bmatrix} \qquad
|
||||
P_y = \begin{bmatrix} 1 \\ 1 \\ 1 \end{bmatrix} \cdot \begin{bmatrix} -1 & 0 & 1 \end{bmatrix}
|
||||
```
|
||||
|
||||
Aproximace je pak dána jako:
|
||||
|
||||
```math
|
||||
\lvert \nabla f(m, n) \rvert \approx \sqrt{(P_x * I)^2 + (P_y * I)^2}
|
||||
```
|
||||
|
||||
kde $I$ je vstupní obraz.
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Všimni si podobnosti s Sobelovým operátorem. Jen místo Gaussovského rozmazání používá box filtr.
|
||||
</dd></dl>
|
||||
|
||||
- **Sobelův operátor**\
|
||||
Aproximuje velikost gradientu pomocí **centrálních** konečných diferencí. Skládá se ze dvou konvolucí s jádry:
|
||||
|
||||
```math
|
||||
G_x = \begin{bmatrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{bmatrix} \qquad
|
||||
G_y = \begin{bmatrix} 1 & 2 & 1 \\ 0 & 0 & 0 \\ -1 & -2 & -1 \end{bmatrix}
|
||||
```
|
||||
|
||||
Tato jádra se dají odseparovat na:
|
||||
|
||||
```math
|
||||
G_x = \begin{bmatrix} -1 \\ 0 \\ 1 \end{bmatrix} \cdot \begin{bmatrix} 1 & 2 & 1 \end{bmatrix} \qquad
|
||||
G_y = \begin{bmatrix} 1 \\ 2 \\ 1 \end{bmatrix} \cdot \begin{bmatrix} -1 & 0 & 1 \end{bmatrix}
|
||||
```
|
||||
|
||||
Všimni si, že jeden kernel je Gaussovo rozmázání a druhý jsou centrální diference.
|
||||
|
||||
Aproximace je pak dána jako:
|
||||
|
||||
```math
|
||||
\lvert \nabla f(m, n) \rvert \approx \sqrt{(G_x * I)^2 + (G_y * I)^2}
|
||||
```
|
||||
|
||||
kde $I$ je vstupní obraz.
|
||||
|
||||
- **Robertsův operátor / Roberts cross**\
|
||||
Aproximuje velikost gradientu pomocí konečných diferencí. Detekuje především hrany se sklonem 45°.
|
||||
|
||||
```math
|
||||
\lvert \nabla f(m, n) \rvert \approx \textcolor{red}{\lvert f(m, n) - f(m + 1, n + 1) \rvert} + \textcolor{blue}{\lvert f(m + 1, n) - f(m, n + 1) \rvert}
|
||||
```
|
||||
|
||||
kde barevné výrazy získa dvěma konvolucemi s jádry:
|
||||
|
||||
```math
|
||||
\textcolor{red}{R_x} = \begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix} \qquad
|
||||
\textcolor{blue}{R_y} = \begin{bmatrix} 0 & 1 \\ -1 & 0 \end{bmatrix}
|
||||
```
|
||||
|
||||
- **Robinsonův operátor / Robinson compass mark**\
|
||||
Detekuje hrany pomocí centrální diferencí. Používá osm různých jader, jedno prokaždý směr na kompasu. To mu umožňuje snadno aproximovat nejen velikost ale i směr gradientu.
|
||||
- **Canny edge detector**\
|
||||
Algoritmus pro detekci hran. [canny](#canny) [canny-tds](#canny-tds)
|
||||
|
||||
- Má nízké procento chyb.
|
||||
- Přesně lokalizuje hrany.
|
||||
- Má jednoznačnou odezvu (hrana prostě buď je nebo není).
|
||||
- Ale **neprodukuje** nutně spojité hrany.
|
||||
|
||||
Zjednodušený postup:
|
||||
|
||||
1. Aplikuj Gaussovo rozmazání na vstupní obraz, pro odstranění šumu.
|
||||
2. Spočítej gradient intenzity obrazu (pomocí Roberts, Sobela, ...).
|
||||
3. Non-maximum suppression: zuž hrany na jednopixelovou šířku.
|
||||
4. Double threshold: urči, které pixely jsou _strong_, _weak_ a _non-relevant_.
|
||||
5. Aplikuj hysterezní prahování: spoj _strong_ pixely s _weak_ pixely, pokud je kolem nich _strong_ pixel.
|
||||
|
||||
### Podle druhé derivace
|
||||
|
||||
Hrany lze detekovat pomocí druhé derivace obrazu. Nacházejí se v _nulových bodech / zero crossings_ (tedy v maximech a minimech první derivace).
|
||||
|
||||
- **Divergence**\
|
||||
Divergence je operátor, který vrací skalární hodnotu. Popisuje zda gradient roste či klesá. Je definován jako: [divergence](#divergence)
|
||||
|
||||
```math
|
||||
\text{div} \vec{F} = \nabla \cdot \vec{F} = \frac{\partial F_x}{\partial x} + \frac{\partial F_y}{\partial y} + \frac{\partial F_z}{\partial z}
|
||||
```
|
||||
|
||||
- **Laplaceův operátor / Laplacian**\
|
||||
Laplaceův operátor $\Delta$ hledá hrany pomocí divergence gradientu.
|
||||
|
||||
- Produkuje spojité hrany.
|
||||
- Uzavřené kontury.
|
||||
- Invariantní k otáčení o násobky $\pi/2$.
|
||||
- Ale je velmi citlivý na šum.
|
||||
- Nedetekuje orientaci hrany.
|
||||
|
||||
```math
|
||||
\Delta f = \nabla^2 f = \nabla \cdot \nabla f = f_{xx} + f_{yy}
|
||||
```
|
||||
|
||||
kde $f$ je vstupní obraz.
|
||||
|
||||
Jeho diskrétní aproximace v maticové podobě potom vypadá jako:
|
||||
|
||||
```math
|
||||
|
||||
\begin{bmatrix} 0 & 1 & 0 \\ 1 & -4 & 1 \\ 0 & 1 & 0 \end{bmatrix}
|
||||
```
|
||||
|
||||
- **Laplacian of Gaussian (LoG)**\
|
||||
Kombinace Gaussovského rozmazání a Laplacianu.
|
||||
|
||||
Laplaceův operátor je velmi citlivý na šum. Proto se před jeho použítím obraz často prožene Gaussovským rozmazáním.
|
||||
|
||||
Matice pro LoG je potom dána jako:
|
||||
|
||||
```math
|
||||
\begin{bmatrix}
|
||||
0 & 0 & -1 & 0 & 0 \\
|
||||
0 & -1 & -2 & -1 & 0 \\
|
||||
-1 & -2 & 16 & -2 & -1 \\
|
||||
0 & -1 & -2 & -1 & 0 \\
|
||||
0 & 0 & -1 & 0 & 0
|
||||
\end{bmatrix}
|
||||
```
|
||||
|
||||
Říká se mu _Mexican hat_.
|
||||
|
||||

|
||||
|
||||
## Integrální transformace
|
||||
|
||||
Transformace, která mapuje funkci $f: A \to B$ z jejího původního funkčního prostoru $A \to B$ do nějakého jiného funkčního prostoru $A' \to B'$. Používá se, protože s některými vlastnostmi funkcí je snazší pracovat v jiném prostoru. [integral-transform](#integral-transform)
|
||||
|
||||
Patří sem transformace jako:
|
||||
|
||||
- Fourierova transformace,
|
||||
- vlnková transformace,
|
||||
- Houghova transformace,
|
||||
- Radonova transformace.
|
||||
|
||||
## Fourierova transformace
|
||||
|
||||
> Fourierka je ako more. Je to hromada vlniek.
|
||||
>
|
||||
> — Nika Kunzová
|
||||
|
||||
<dl><dt><strong>💡 TIP</strong></dt><dd>
|
||||
|
||||
3Blue1Brown má skvělý [video o Fourierově transformaci](https://www.youtube.com/watch?v=spUNpyF58BY), ze kterého to pochopíš! _(a evidentně je tak dobrý, že mi Copilot sám nabídl správný link...)_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
Je operace (integrální transformace) při níž je obraz převeden z _prostorové_ do _frekvenční_ domény. A při _inverzní Fourierově transformaci_ obráceně. [fourier](#fourier)
|
||||
|
||||
- Frekvenční doména je složena ze sinusoid s různými frekvencemi a fázemi (indikovaných pomocí polárních souřadnic).
|
||||
- Intenzita pixelu v obrazu frekvenční domény pak udává amplitudu dané sinusoidy.
|
||||
- Roztažení (stretch) funkce v prostorové doméně odpovídá opakování funkce (repetition) ve frekvenční doméně.
|
||||
- Posun (shift) v prostorové doméně ovlivňuje jenom fázi.
|
||||
|
||||
- **Eulerova formule**\
|
||||
Eulerova formule je vztah mezi komplexními čísly a goniometrickými funkcemi.
|
||||
|
||||
```math
|
||||
e^{i \theta} = \cos \theta + i \sin \theta
|
||||
```
|
||||
|
||||
Lidskými slovy říká (viz 3b1b), že komplexní číslo $e^{i t}$ popisuje pohyb po jednotkové kružnici v komplexní rovině proti směru hodinových ručiček. Jedna otáčka je $t = 2 \pi$ radianů.
|
||||
|
||||
- **1D Fourierova transformace**\
|
||||
Eulerovu formuli využijeme při popisu Fourierovy transformace:
|
||||
|
||||
```math
|
||||
\underbrace{\mathcal{F}(u)}_{\substack{\text{FT pro} \\ \text{frekvenci } u}} =
|
||||
\underbrace{\int_{-\infty}^{\infty}
|
||||
\underbrace{f(x)}_{\substack{\text{poloměr} \\ \text{podle} \\ \text{funkce } f}}
|
||||
\underbrace{e^{
|
||||
\underbrace{-}_{\substack{\text{chceme} \\ \text{po směru} \\ \text{hodin}}}
|
||||
\underbrace{i}_{\substack{\text{komplexní} \\ \text{číslo}}}
|
||||
\underbrace{2 \pi}_{\substack{\text{celá} \\ \text{kružnice}}}
|
||||
\underbrace{u}_{\substack{\text{frekvence} \\ \text{ve FT}}}
|
||||
\underbrace{x}_{\substack{\text{čas} \\ \text{ve funkci } f}}
|
||||
}}_{\text{fáze kružnice podle frekvence a času}}
|
||||
dx
|
||||
}_{\text{pro všechna } x \text{ v celém definičním oboru funkce} f}
|
||||
```
|
||||
|
||||
**Forward** (z prostorové do frekvenční domény): [fourier](#fourier)
|
||||
|
||||
```math
|
||||
\begin{align*}
|
||||
|
||||
\mathcal{F}(u) &= \int_{-\infty}^{\infty} f(x) e^{-i 2 \pi u x} dx & \text{ spojitá} \\
|
||||
\mathcal{F}(k) &= \frac{1}{\sqrt{N}} \sum_{m = 0}^{N-1} f(m) e^\frac{-i 2 \pi k m}{N} & \text{ diskrétní}
|
||||
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
**Inverse** (z frekvenční do prostorové domény):
|
||||
|
||||
```math
|
||||
\begin{align*}
|
||||
|
||||
f(x) &= \int_{-\infty}^{\infty} \mathcal{F}(u) e^{i 2 \pi u x} du & \text{ spojitá} \\
|
||||
f(x) & = {1 \over \sqrt N} \sum_{m=0}^{N-1} \mathcal{F}(k) e^{{2 \pi i m k \over N}}
|
||||
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
- **2D Fourierova transformace**\
|
||||
**Forward** (z prostorové do frekvenční domény): [fourier](#fourier)
|
||||
|
||||
```math
|
||||
\begin{align*}
|
||||
|
||||
\mathcal{F}(u, v) &= \int_{-\infty}^{\infty} \int_{-\infty}^{\infty} f(x, y) e^{-i 2 \pi (ux + vy)} dx dy & \text{ spojitá} \\
|
||||
\mathcal{F}(u, v) &= \frac{1}{\sqrt{MN}} \sum_{m=0}^{M-1} \sum_{n = 0}^{N-1} f(x, y) e^{-i 2 \pi \left(\frac{m \cdot u}{M} + \frac{n \cdot v}{N}\right)} & \text{ diskrétní}
|
||||
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
**Inverse** (z frekvenční do prostorové domény):
|
||||
|
||||
```math
|
||||
\begin{align*}
|
||||
|
||||
f(m, n) &= \int_{-\infty}^{\infty} \int_{-\infty}^{\infty} \mathcal{F}(u, v) e^{i 2 \pi (um + vn)} du dv & \text{ spojitá} \\
|
||||
f(m, n) &= \frac{1}{MN}\sum_{k=0}^{M-1} \sum_{l = 0}^{N-1} \mathcal{F}(u, v) e^{i 2 \pi \left(\frac{um}{M} + \frac{vn}{N}\right)} & \text{ diskrétní}
|
||||
|
||||
\end{align*}
|
||||
```
|
||||
|
||||
- **Fast Fourier Transform (FFT)**\
|
||||
Algoritmus pro rychlé výpočty diskrétní Fourierovy transformace (DFT). [fft](#fft)
|
||||
- **Konvoluční teorém**\
|
||||
Říká, že běžné násobení ve frekvenční doméně odpovídá konvoluci v prostorové doméně a obráceně. To je cool, protože konvoluce je pomalá, ale násobení je rychlé. [convolution](#convolution)
|
||||
|
||||
```math
|
||||
\mathcal{F} \{ f * g \} = \mathcal{F} \{ f \} \cdot \mathcal{F} \{ g \}
|
||||
```
|
||||
|
||||
kde $\mathcal{F}$ je Fourierova transformace.
|
||||
|
||||
## Sampling / vzorkování
|
||||
|
||||
Samplování je převod spojitého signálu na diskrétní. [sampling](#sampling)
|
||||
|
||||
- **Převzorkování**\
|
||||
Je proces, kdy na vstupu je **diskrétní** signál s nějakou vzorkovací frekvencí a na výstupu je **diskrétní** signál s **jinou** vzorkovací frekvencí.
|
||||
|
||||
V případě 2D obrazů to může ale nemusí znamenat změnu velikosti obrazu. [image-scaling](#image-scaling)
|
||||
|
||||
- **Vzorkovací teorém / Nyquist-Shannon sampling theorem**\
|
||||
Říká, že chceme-li spojitý signál převést na diskrétní a pak z tohoto diskrétního signálu zrekonstruovat původní spojitý signál, můsíme samplovat s alespoň dvojnásobnou frekvencí než je nejvyšší frekvence v původním signálu. [n-s](#n-s)
|
||||
|
||||
- Původní spojitý signál musí být frekvenčně omezený (band-limited), aby bylo možné v něm určit nejvyšší frekvenci.
|
||||
- Při nesplnění těchto podmínek vzniká aliasing.
|
||||
|
||||
**💡 TIP**\
|
||||
Aliasingu se věnuje část otázky [Renderování s využitím GPU](../renderovani-s-vyuzitim-gpu/).
|
||||
|
||||
**💡 TIP**\
|
||||
Intuitivně je signál hromádka kopečků. Abychom poznali i ty nejužší kopečky -- s nejvyšší frekvencí -- musíme mít dostatečně jemné síto -- koukat na kopečky s dvakrát takovou frekvencí, abychom si všimli, že někde začíná a končí.
|
||||
|
||||
- **Rekonstrukce**\
|
||||
Proces, kdy z diskrétního signálu zpět získáme spojitý signál. [reconstruction](#reconstruction)
|
||||
- **Rekonstrukční filtr**\
|
||||
Filtr pro rekonstrukci signálu.
|
||||
|
||||
- _box_: nejbližší soused,
|
||||
- _tent_: lineární interpolace,
|
||||
- sinc,
|
||||
- Lanczos,
|
||||
- Gaussian.
|
||||
|
||||
## Geometrické transformace
|
||||
|
||||
Geometrická transformace $T$ je bijekce mezi body dvou obrazů $I$ a $J$. Díky tomu, že je to bijekce, k ní musí vždy existovat inverze. [geometric-transform](#geometric-transform)
|
||||
|
||||
```math
|
||||
J \lbrack u, v \rbrack = T(u, v) = I \lbrack x(u, v), y(u, v) \rbrack
|
||||
```
|
||||
|
||||
Patří sem operace jako:
|
||||
|
||||
- posunutí / translace,
|
||||
- rotace,
|
||||
- škálování,
|
||||
- zkosení / shear,
|
||||
- zrcadlení / flip,
|
||||
- deformace / warping (na rozdíl od operací výše není lineární).
|
||||
|
||||
- **Dopředné mapování / forward mapping**\
|
||||
Procházíme pixely v $I$ a hledáme jejich umístění v $J$ (_metoda "Kam s ním?"_).
|
||||
- **Zpětné mapování / backward mapping**\
|
||||
Pro každý pixel $J$ počítáme jeho původní umístění v $I$ (_metoda "Kde je?"_).
|
||||
|
||||
## Vlnková transformace / wavelet transform
|
||||
|
||||
<dl><dt><strong>💡 TIP</strong></dt><dd>
|
||||
|
||||
Opět výborné video, bohužel ne od 3b1b, ale obdobně kvalitně zpracované: [Wavelets: a mathematical microscope](https://www.youtube.com/watch?v=jnxqHcObNK4).
|
||||
|
||||
</dd></dl>
|
||||
|
||||
- **Vlnka / wavelet**\
|
||||
Funkce $\psi$, která je omezená v čase. Je to "brief oscillation". [wavelet](#wavelet)
|
||||
|
||||

|
||||
|
||||
- **Má konečnou energii**:
|
||||
|
||||
```math
|
||||
\int_{-\infty}^{\infty} |\psi(t)|^2 dt < \infty
|
||||
```
|
||||
|
||||
- Splňuje podmínku přípustnosti:
|
||||
|
||||
```math
|
||||
C_\psi = \int_{0}^{\infty} { {|\hat{\psi}(\omega)|^{2}}\over{\omega} } \, \mathrm{d}\omega < \infty
|
||||
```
|
||||
|
||||
kde $\hat{\psi}$ je Fourierova transformace $\psi$. Tato podmínka zajišťuje invertibilitu vlnkové transformace.
|
||||
|
||||
- Z podmínky přípustnosti plyne, že vlnka **musí mít nulovou střední hodnotu**:
|
||||
|
||||
```math
|
||||
\int_{-\infty}^{\infty} \psi(t) \, \mathrm{d}t = 0
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
Vlnková transformace je integrální transformace, která popisuje funkci v **čase** a **frekvenci** zároveň. Popis v čase je dán tím, že vlnky (narozdíl od sinusoid u Fourierky) jsou časově omezené. [wavelet](#wavelet)
|
||||
|
||||
Používá se k:
|
||||
|
||||
- Detekci nespojitosti signálu a jeho derivaci.
|
||||
- Identifikaci okamžitých frekvencí.
|
||||
- Odstranění šumu.
|
||||
- Extrakci příznaků.
|
||||
- Kompresi signálu.
|
||||
|
||||
Základní myšlenka je:
|
||||
|
||||
1. Zvolíme mateřskou vlnku $\psi$ (je spousta různých, ale nejznámnější je Morletova vlnka $\psi(t) = k \cdot \underbrace{e^{i \omega_0 t}}_{\text{Rotace jako u FT}} \cdot \underbrace{e^{\frac{-t^2}{2}}}_{\text{Škála}}$
|
||||
|
||||

|
||||
|
||||
2. Tuto vlnku můžeme posouvat a škálovat pomocí parametrů $a$ a $b$ - $\psi_{a,b} = \psi \frac{t-b}{a}$.
|
||||
|
||||

|
||||
|
||||
3. Posouváme naši vlnkovou funkci po signálu oběma parametry a pro každý bod sledujeme shodu s funkcí. Tu získáme intuitivně, jako integrál součinu vlnky a signálu $\int_{-\infty}^{\infty} y(t) \psi_{a,b}(t) dt$. Pokud se ale podíváme na to, co to znamená ve frekvenční doméně, zjistíme, že to je skalární součin mezi Fourierovou transformací signálu a vlnky $\langle f, \psi_{a,b} \rangle$.
|
||||
|
||||

|
||||
|
||||
4. Pokud toto uděláme pro každý bod časové ($a$) a frekvenční ($b$) domény, dostaneme výsledný obraz vlnkové transformace.
|
||||
|
||||

|
||||
|
||||
5. Ale co to? V reálné části výsledku vidíme podivné vlnky! To je proto, že vlnková funkce je komplexní a ve skutečnosti nám dot product nevrací jednu hodnotu, ale komplexní číslo. Pokud zkoumáme to, pak vidíme, že rotuje kolem středu imaginární roviny. Stačí nám tedy změřit jeho vzdálenost od středu (absolutní hodnotu komplexního čísla) a dostáváme vlnkovou transformaci.
|
||||
|
||||

|
||||
|
||||
Ve výsledku je to fakt jen **dot product funkce $f$ s upravenou vlnkou $\psi_{a,b}$**!
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
\left[\operatorname {W} _{\psi }\,f\right](a,b) &=
|
||||
\langle f,\psi _{a,b}\rangle\\
|
||||
|
||||
&=\int _{-\infty }^{+\infty }\!f(t)\,\psi _{a,b}^{\ast }(t)\,\mathrm {d} t\\
|
||||
|
||||
&=\int _{-\infty }^{+\infty }\!f(t)\,{\frac {1}{\sqrt {a}}}\psi ^{\ast }\left({{t-b} \over {a}}\right)\,\mathrm {d} t\\
|
||||
|
||||
&=f*\psi _{a}^{\ast }(b)\\&={\frac {1}{2\pi }}\langle {\hat {f}},{\hat {\psi }}_{a,b}\rangle ,
|
||||
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
kde:
|
||||
|
||||
- $\psi$ je mateřská vlnka,
|
||||
- $\psi_{a,b}$ je škálovaná a posunutá mateřská vlnka,
|
||||
- $a$ je škálovací parametr,
|
||||
- $b$ je posunutí.
|
||||
- $\hat {f}$ je Fourierova transformace funkce $f$,
|
||||
- $\hat {\psi }$ je Fourierova transformace vlnky $\psi$,
|
||||
- $\langle \cdot ,\cdot \rangle $ je skalární součin,
|
||||
- $\ast $ u $\psi^\ast$ je komplexně sdružená funkce,
|
||||
- $*$ je spojitá konvoluce,
|
||||
- $\psi _{a}(t)={\frac {1}{\sqrt {a}}}\psi \left({{-t} \over {a}}\right)$ je spojitý filtr, který odpovídá vlnce $\psi$, pro dané měřítko $a$.
|
||||
|
||||
Dále platí:
|
||||
|
||||
- Vlnky jsou konstruovány, aby měly vhodné vlastnosti například pro zpracování signálů.
|
||||
- Vlnková transformace je v podstatě konvoluce signálu s vlnkou.
|
||||
|
||||
Představme si například vlnku, která má frekvenci tónu střední C a krátké trvání odpovídající osminové notě. Provedeme-li v pravidelných intervalech konvoluci takovéto vlnky se signálem - nahrávkou písně - pak nám výsledky této konvoluce napoví, kdy byla nota „osminové střední C“ v nahrávce použita.
|
||||
|
||||
Matematicky vzato, k vysoké korelaci vlnky se signálem (vysokému korelačnímu koeficientu) dojde v těch místech (intervalech), kde signál obsahuje informaci o podobné frekvenci, tedy tam, kde je námi zvolené vlnce nejpodobnější. Tento koncept je jádrem mnoha aplikací vlnkové transformace. [others](#others)
|
||||
|
||||
## Houghova transformace
|
||||
|
||||
<dl><dt><strong>💡 TIP</strong></dt><dd>
|
||||
|
||||
Super [minutu a půl dlouhé video, co ti řekne úplně všechno](https://www.youtube.com/watch?v=X1DxCPS1iwA).
|
||||
|
||||
</dd></dl>
|
||||
|
||||
Integrální transformace, která identifikuje přímky v obraze. V rozšířené podobě hledá libovolné tvary zadané parametricky. [hough](#hough)
|
||||
|
||||
- Dlouho byla používána pro detekci čar na silnici pro autonomní řízení aut. (Už ne. Dnes se používají neuronové sítě.)
|
||||
- Pracuje nad binárním obrazem.
|
||||
- Mapuje tvar na bod v parametrickém prostoru.
|
||||
|
||||
- **Houghův prostor**\
|
||||
Prostor je definován jednoduchou rovnicí $x \cdot \cos (\theta) + y \cdot \sin (\theta) = \rho$.
|
||||
|
||||
Bod v prostoru obrázku je reprezentován jako křivka v Houghově prostoru. Bod v Houghově prostoru je reprezentován jako přímka v obrázku.
|
||||
|
||||

|
||||
|
||||
Můžeme promítnout všechny body z obrázku do Houghova prostoru s intenzitou odpovídající intenzitě bodu v obrázku. Pak hledáme body v Houghově prostoru, které mají největší intenzitu. To jsou body, které reprezentují přímky v obrázku.
|
||||
|
||||

|
||||
|
||||
## Radonova transformace
|
||||
|
||||
<dl><dt><strong>💡 TIP</strong></dt><dd>
|
||||
|
||||
Jako je již tradicí, mám pro vás [video](https://www.youtube.com/watch?v=f0sxjhGHRPo)...
|
||||
|
||||
</dd></dl>
|
||||
|
||||
Integrální transformace, která integruje funkci přes přímky. Tedy rozkládá funkci na hromádku parametrů, které definují přímky.
|
||||
|
||||
Užitečná je především inverzní Radonova transformace, která se používá v tomografii ("CTčko"). [radon](#radon)
|
||||
|
||||

|
||||
|
||||
Mějme 3D objekt, který chceme "proskenovat" z různých úhlů $\phi$. Pro každý úhel chceme získat 1D projekci objektu $p(s, \phi)$. Tato projekce je dána integrálem funkce $f(x, y)$ přes přímku.
|
||||
|
||||
Uvažme, že nejprve celý prostor otočíme o úhel $\phi$ a potom provedeme jednoduchou projekci všech bodů na této přímce.
|
||||
|
||||

|
||||
|
||||
```math
|
||||
\begin{pmatrix}
|
||||
x \\
|
||||
y
|
||||
\end{pmatrix}
|
||||
=
|
||||
\begin{pmatrix}
|
||||
\cos \phi & -\sin \phi \\
|
||||
\sin \phi & \cos \phi
|
||||
\end{pmatrix}
|
||||
\begin{pmatrix}
|
||||
s \\
|
||||
u
|
||||
\end{pmatrix}
|
||||
|
||||
\Rightarrow
|
||||
|
||||
\begin{aligned}
|
||||
x = s \cos \phi - u \sin \phi \\
|
||||
y = s \sin \phi + u \cos \phi
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
p(s, \phi) &= \mathcal{R} \{ f(s, \phi) \} \\
|
||||
&= \int_{-\infty}^{\infty} f(x, y) du \\
|
||||
&= \int_{-\infty}^{\infty} f(s \cos \phi - u \sin \phi, s \sin \phi + u \cos \phi) du
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
Pokud vezmeme všechny hodnoty z této projekce, získáme tzv. Sinogram:
|
||||
|
||||

|
||||
|
||||
Inverzní funkce je velice užitečná, ale poměrně složitá, takže doufám, že stačí tato obecná myšlenka.
|
||||
|
||||
---
|
||||
|
||||
**Radon vs Hough**
|
||||
|
||||
| Radon |
|
||||
| ----------------------------------------------------------------------- |
|
||||
| Hough |
|
||||
| Vyvinuta v 1917 |
|
||||
| Vyvinuta v 1962 |
|
||||
| Nejčastěji hledá přímky |
|
||||
| Hledá nějaký tvar zadaný parametricky (přímky, kružnice, elipsy, ...) |
|
||||
| Dopředná transformace nás moc nezajímá tu provádí CT skener kontinuálně |
|
||||
| Dopředná transformace je implementovaná diskrétně |
|
||||
| Hlavním cílem je rekonstrukce obrazu -- inverzní transformace |
|
||||
| Hlavním cílem je detekce tvarů |
|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[pb130,1]]] [PB130 Úvod do digitálního zpracování obrazu (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PB130/)
|
||||
- [[[pv131,2]]] [PV131 Digitální zpracování obrazu (jaro 2023)](https://is.muni.cz/auth/el/fi/jaro2023/PV131/)
|
||||
- [[[raster,3]]] [Wikipedia: Raster graphics](https://en.wikipedia.org/wiki/Raster_graphics)
|
||||
- [[[dip,4]]] [Wikipedia: Digital image processing](https://en.wikipedia.org/wiki/Digital_image_processing)
|
||||
- [[[filter,5]]] [Wikipedia: Filter (signal processing)](<https://en.wikipedia.org/wiki/Filter_(signal_processing)>)
|
||||
- [[[convolution,6]]] [Wikipedia: Convolution](https://en.wikipedia.org/wiki/Convolution)
|
||||
- [[[edge-detection,7]]] [Wikipedia: Edge detection](https://en.wikipedia.org/wiki/Edge_detection)
|
||||
- [[[fourier, 8]]] [Wikipedia: Fourier transform](https://en.wikipedia.org/wiki/Fourier_transform)
|
||||
- [[[fft, 9]]] [Wikipedia: Fast Fourier transform](https://en.wikipedia.org/wiki/Fast_Fourier_transform)
|
||||
- [[[samping, 10]]] [Wikipedia: Sampling (signal processing)](<https://en.wikipedia.org/wiki/Sampling_(signal_processing)>)
|
||||
- [[[scaling, 11]]] [Wikipedia: Image scaling](https://en.wikipedia.org/wiki/Image_scaling)
|
||||
- [[[n-s, 12]]] [Wikipedia: Nyquist–Shannon sampling theorem](https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem)
|
||||
- [[[geometric-transform,13]]] [Wikipedia: Geometric transformation](https://en.wikipedia.org/wiki/Geometric_transformation)
|
||||
- [[[reconstruction, 14]]] [Wikipedia: Signal reconstruction](https://en.wikipedia.org/wiki/Signal_reconstruction)
|
||||
- [[[wavelet,15]]] [Wikipedia: Wavelet transform](https://en.wikipedia.org/wiki/Wavelet_transform)
|
||||
- [[[hough, 16]]] [Wikipedia: Hough transform](https://en.wikipedia.org/wiki/Hough_transform)
|
||||
- [[[radon, 17]]] [Wikipedia: Radon transform](https://en.wikipedia.org/wiki/Radon_transform)
|
||||
- [[[integral-transform, 18]]] [Wikipedia: Integral transform](https://en.wikipedia.org/wiki/Integral_transform)
|
||||
- [[[histogram, 19]]] [Wikipedia: Histogram](https://en.wikipedia.org/wiki/Histogram)
|
||||
- [[[histogram-eq, 20]]] [Wikipedia: Histogram equalization](https://en.wikipedia.org/wiki/Histogram_equalization)
|
||||
- [[[histogram-bbc, 21]]] [Bitesize: Histograms - Higher only](https://www.bbc.co.uk/bitesize/guides/zspfcwx/revision/3)
|
||||
- [[[sobel, 22]]] [Wikipedia: Sobel operator](https://en.wikipedia.org/wiki/Sobel_operator)
|
||||
- [[[canny, 23]]] [Wikipedia: Canny edge detector](https://en.wikipedia.org/wiki/Canny_edge_detector)
|
||||
- [[[canny-tds, 24]]] [Canny Edge Detection Step by Step in Python — Computer Vision](https://towardsdatascience.com/canny-edge-detection-step-by-step-in-python-computer-vision-b49c3a2d8123)
|
||||
- [[[divergence, 25]]] [Wikipedia: Divergence (operátor)](<https://cs.wikipedia.org/wiki/Divergence_(oper%C3%A1tor)>)
|
||||
- [[[dog, 26]]] [Wikipedia: Difference of Gaussians](https://en.wikipedia.org/wiki/Difference_of_Gaussians)
|
||||
- [[[others, 27]]] https://hackmd.io/@fi-muni-viz-2022/SywCznl2t
|
||||
- [[[waveleet, 28]]] [Wikipedia: Vlnka](https://cs.wikipedia.org/wiki/Vlnka)
|
542
src/content/docs/szmgr/SZP10_analyza_obrazu.md
Normal file
542
src/content/docs/szmgr/SZP10_analyza_obrazu.md
Normal file
@ -0,0 +1,542 @@
|
||||
---
|
||||
title: "Analýza rastrového obrazu"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Segmentace obrazu, algoritmy značení komponent, popis objektů, klasifikace objektů. Výpočet mapy vzdáleností. Základy matematické morfologie (dilatace a eroze, otevření a uzavření, hit-or-miss, top-hat, watershed).
|
||||
|
||||
_PB130/PV131_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
- **Typické fáze analýzy obrazu**
|
||||
1. Předzpracování
|
||||
- Potlačení šumu, odstranění nerovnoměrného osvětlení, atd.
|
||||
2. Segmentace
|
||||
- Rozdělení obrazu na oblasti odpovídající objektům.
|
||||
3. Popis
|
||||
- Určení vlastností objektů. Vlastnosti potřebujeme pro klasifikaci.
|
||||
4. Klasifikace
|
||||
- Rozdělení objektů do tříd podle jejich vlastností.
|
||||
5. Porozumění
|
||||
- Pochopení smyslu objektů v obraze.
|
||||
|
||||
## Segmentace obrazu
|
||||
|
||||
Rozdělení definičního oboru obrazu $\Omega$ na _segmenty_ $\Omega = \Omega_0 \cup \Omega_1 \cup \dots \cup \Omega_{n-1}$ (oblasti, regiony, spojené množiny) podle nějaké společné vlastnosti.
|
||||
|
||||
> 1. Regions should be uniform and homogeneous with respect to some characteristic(s).
|
||||
> 2. Adjacent regions should have significant differences with respect to the characteristic on which they are uniform.
|
||||
> 3. Region interiors should be simple and without holes.
|
||||
> 4. Boundaries should be simple, not ragged, and be spatially accurate.
|
||||
>
|
||||
> — Haralick a Shapiro
|
||||
|
||||
Segmentace přiřazuje každému pixelu obrazu jednoznačnou značku (číslo) podle toho, do které komponenty patří. Výsledkem je šedotónový obraz, kde každá komponenta má jinou intenzitu. Oblasti (=regiony) lze reprezentovat pomocí obrysu (=kontury).
|
||||
|
||||
Typickým problémem je rozpoznávání objektů. Možnosti řešení:
|
||||
|
||||
- **Prahování** (často s využitím histogramu)
|
||||
- Shlukovací metody
|
||||
- Metody založené na kompresi
|
||||
- Narůstání regionů (region-growing, split-and-merge)
|
||||
- PDE-based (parametrické a implicitní aktivní křivky)
|
||||
- Variační přístupy (modely Mumford-Shah a Chan-Vese)
|
||||
- Grafové přístupy (graph-cuts, MST, MRF)
|
||||
- **Algoritmus záplava** (watershed)
|
||||
- Hierarchické segmentace
|
||||
- Metody pracující s modelem tvaru (ASM, AAM)
|
||||
- **Neuronové sítě** (zejména konvoluční)
|
||||
|
||||
Před samotnou segmentací je vhodné obraz předpřipravit.
|
||||
|
||||
- **Algoritmy značení komponent / connected-component labeling (CCL)**\
|
||||
Algoritmy, které přiřazují každému pixelu obrazu jednoznačnou značku (číslo) podle toho, do které komponenty patří. Je algoritmickou aplikací teorie grafů na obraz.
|
||||
|
||||
Obraz je převeden na graf, kde každý pixel je vrchol a hrany jsou mezi sousedními pixely. Hrany jsou ohodnoceny podle podobnosti sousedních pixelů. Segmenty jsou pak komponenty souvislosti v grafu.
|
||||
|
||||
**❗ IMPORTANT**\
|
||||
Segmentace je problém nalezení oblastí. CCL je jen jedno z možných řešení.
|
||||
|
||||
### Neuronové sítě
|
||||
|
||||
Moderní přístup, vyžaduje velké množství parametrů a mohou být náročné na trénování, existuje mnoho předtrénovaných modelů.
|
||||
|
||||
**Plně konvoluční sítě** -- Všechny vrstvy jsou konvoluční, typicky Downsample + Upsample. Výstupy můžou být různé podle natrénované sítě.
|
||||
|
||||
### Prahování / thresholding
|
||||
|
||||
> Prahuje se v Prahe často? Badumtsss
|
||||
|
||||
Pixely jsou rozděleny na regiony podle jejich intenzity. Pixely s intenzitou nižší než _threshold / práh_ jsou označeny jako pozadí, ostatní jako popředí.
|
||||
|
||||
Důležitá je volba prahu. Někdy víme procento pixelů, které mají být popředí / pozadí, ale typicky zjistíme z analýzy histogramu.
|
||||
|
||||
- Prahování je jedna z nejjednodušších metod segmentace obrazu.
|
||||
- Práh lze určit manuálně nebo automaticky.
|
||||
|
||||
#### Globální prahování
|
||||
|
||||
Práh je stejný pro celý obraz. Nezávisle na pozici.
|
||||
|
||||
- **Otsuova metoda**\
|
||||
Minimalizace váženého součtu rozptylu intenzit v popředí a pozadí.
|
||||
|
||||
```math
|
||||
\sigma^2_w(t) = q_1(t) \sigma_1^2(t) + q_2(t) \sigma_2^2(t)
|
||||
```
|
||||
|
||||

|
||||
|
||||
Při velkém šumu je problém s analýzou i segmentací
|
||||
|
||||
- **Gradientní prahování**\
|
||||
Práh počítaný jako vážený průměr intenzit, kde váhy odpovídají normalizované velikosti gradientu. Vychází z předpokladu, že gradient má velkou velikost
|
||||
v místech výskytu hran => vyšší váha.
|
||||
|
||||
```math
|
||||
a_{th} = \sum_{u,v} I(u,v) \cdot \frac{|\nabla I(u,v)|}{\sum_{i,j} |\nabla I(i,j)|}
|
||||
```
|
||||
|
||||
- **Unimodální histogram**\
|
||||
Pro obrazy, kde je viditelné jediné výrazné maximum (pro pixely pozadí). Použijeme Trojúhelníkovou metodu:;
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
M &\equiv [m, h(m)] &\text{ globální maximum histogramu}\\
|
||||
N &\equiv [n, h(n)] &\text{ kde } n \text{ je hodnota intenzity s nenulovou četností nejdál od } m\\
|
||||
T &\equiv [t, h(t)] &\text{ bod s největší vzdáleností od přímky } MN
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||

|
||||
|
||||
- **Hysterézní prahování**\
|
||||
Používá dva prahy: _nízký_ a _vysoký_. S pixely mezi nimi zachází _vcelku inteligentně_.
|
||||
|
||||
- Pixely s hodnotou **vyšší** než _vysoký práh_ jsou označeny jako popředí.
|
||||
- Pixely s hodnotou **vyšší** než _nízký práh_ jsou oznaženy jako popředí, pokud obsahují alespoň jeden pixel získaný vysokým prahem.
|
||||
- Všechny ostatní pixely jsou označeny jako pozadí.
|
||||
|
||||

|
||||
|
||||
- **Víceúrovňové prahování**\
|
||||
Pokud je obraz jednoduchá, pak histogram obsahuje více vysokých vrcholů s údolím mezi nimi. Práh lze potom snadno zvolit jako dno těchto údolí.
|
||||
|
||||
#### Lokální (adaptivní) prahování
|
||||
|
||||
Práh se mění podle pozice v obraze. Třeba podle průměru intenzit v okolí.
|
||||
|
||||
### Algoritmus záplava (watershed)
|
||||
|
||||
Přístup k segmentaci obrazu z matematické morfologie, který kombinuje segmentaci pomocí narůstání oblastí a segmentaci založenou na hranách.
|
||||
|
||||
Detaily jsou popsány dále v textu.
|
||||
|
||||
## Popis objektů
|
||||
|
||||
Popis objektů je proces, při kterém se počítají vlastnosti segmentovaných objektů. Tyto vlastnosti jsou později použity pro klasifikaci objektů nebo hledání podobných objektů v databázi (třeba pro _face recognition_).
|
||||
|
||||
- **Popisovač / descriptor**\
|
||||
Funkce, která přiřazuje oblasti obrazu -- objektu -- popis vlastnosti.
|
||||
|
||||
- Preferujeme deskriptory, které jsou invariantní vzhledem k posunu, rotaci, změně měřítka, změně osvětlení, atd.
|
||||
- Existují standardizované sady deskriptorů, např. MPEG-7.
|
||||
|
||||
Descriptory dělíme na:
|
||||
|
||||
- _Globální_: popisují celý obraz.
|
||||
- _Lokální_: extrahují zajímavý rysy z malé části obrazu.
|
||||
- Třeba rohy, lokální struktury, atd.
|
||||
- Není potřeba segmentace.
|
||||
- _Objektové_: popisují objekt.
|
||||
- Třeba barva, textura, tvar, atd.
|
||||
- Potřebujeme segmentaci.
|
||||
|
||||
- **Číselné charakteristiky intentizity**\
|
||||
Průměr, rozptyl, medián, kvantily, maximum, atd. přes intenzity pixelů objektu.
|
||||
- **Velikost / plocha**\
|
||||
Počet pixelů objektu.
|
||||
- **Obvod**\
|
||||
Počet hraničních pixelů objektu.
|
||||
- **Topologické vlastnosti**\
|
||||
Vlastnosti objektu nezávislé na jeho deformaci. Např. počet děr.
|
||||
|
||||
**❗ IMPORTANT**\
|
||||
Pro topologické vlastnosti viz otázka [3D modelování a datové struktury](../3d-modelovani-a-datove-struktury/).
|
||||
|
||||
- **Ohraničující obdélník / bounding box**\
|
||||
Nejmenší obdélník ohraničující objekt.
|
||||
|
||||

|
||||
|
||||
- **Průměr / diameter**\
|
||||
Velikost objektu. Dá se odhadnout z bounding boxu.
|
||||
|
||||
- _Feretův průměr_: délka projekce do daného směru.
|
||||
|
||||

|
||||
|
||||
- **Kruhovost / circularity**\
|
||||
Jak moc je objekt podobný kruhu?
|
||||
|
||||
```math
|
||||
\text{circularity} = 4 \cdot \pi \cdot \text{area} / (\text{perimeter} \cdot \text{perimeter})
|
||||
```
|
||||
|
||||
- **Konvexní obal / convex hull**\
|
||||
Nejmenší konvexní polygon ohraničující objekt.
|
||||
- **Hranice / boundary**\
|
||||
Popisuje okraj objektu. Obvykle je zakódovaná jako posloupnost bodů.
|
||||
- **Geometrický střed / centroid**\
|
||||
Průměr souřadnic pixelů objektu.
|
||||
- **Těžiště / hmotný střed / center of mass**\
|
||||
Vážený průměr souřadnic pixelů objektu. Váhy jsou intenzity pixelů. Pokud je objekt homogenní, je těžiště totožné s geometrickým středem.
|
||||
- **Momenty / moments**\
|
||||
Popisují tvar objektu. Používájí se ale i pro popis pravděpodobnostních rozdělení.
|
||||
|
||||
Moment se obecně řídí vzorcem $m_{pq}(R) = \sum_{(u,v) \in R} I(u,v) \cdot u^p v^q$, kde $I(u,v)$ je intenzita pixelu na pozici $(u,v)$ a $R$ je oblast objektu.
|
||||
|
||||
Vidíme, že obsah odpovídá $m_{00}$ a geometrický střed (=těžiště) $(m_{10}/m_{00}, m_{01}/m_{00})$.
|
||||
|
||||
Můžeme využít **centrální momenty**, které jsou posunuté do těžiště objektu $m_{pq}(R) = \sum_{(u,v) \in R} I(u,v) \cdot (u - \hat{x})^p \cdot (v - \hat{y})^q$
|
||||
|
||||
- _První moment_: střední hodnota / hmotný střed.
|
||||
- _Druhý moment_: rozptyl / moment setrvačnosti.
|
||||
|
||||
- **Moment setrvačnosti / moment of inertia**\
|
||||
Míra setrvačnosti při otáčení kolem těžiště. Popisuje rozložení hmoty okolo těžiště (_odchylku_ od něj v jistém smyslu). Umožňuje určit směr nejdůležitější osy objektu. [image-moment](#image-moment)
|
||||
|
||||
Provazochodci využívají moment setrvačnosti při chůzi po laně.
|
||||
|
||||

|
||||
|
||||
**💡 TIP**\
|
||||
"Moment" nereferuje na čas, ale spíš na svůj starý význam "důležitost". Ve fyzice navíc obvykle souvisí s otáčivým pohybem. [moment](#moment)
|
||||
|
||||
- **Prostorová orientace / spatial orientation**\
|
||||
Směr a velikost delší strany nejmenšího bounding boxu. Lze ji také spočítat pomocí momentů setrvačnosti.
|
||||
- **Podlouhlost / elongatedness / eccentricity**\
|
||||
Poměr mezi délkou a šířkou objektu. Dá se spočítat pomocí momentů setrvačnosti.
|
||||
- **Matice součásného výskytu / co-occurrence matrix**\
|
||||
Matice, která popisuje, jak často se vyskytují dvojice pixelů s danými intenzitami v dané vzdálenosti a směru. Používá se pro popis textury.
|
||||
- **Lokální binární vzory / local binary patterns**\
|
||||
Popisují texturu. Základní myšlenka spočívá v nahrazení pixelu 8-bitovým číslem, které udává výsledek porovnání dané hodnoty s hodnotami v osmi-okolí. Je invariantní vůči jasu a byl rozšířen i na rotační nezávislost.
|
||||
|
||||

|
||||
|
||||
## Klasifikace objektů
|
||||
|
||||
Problém zařazení objektů do jedné z předem daných tříd.
|
||||
|
||||
**❗ IMPORTANT**\
|
||||
Detaily přístupů řešení klasifikace lze nalézt v otázce [Strojové učení](../strojove-uceni/).
|
||||
|
||||
- **Konstrukce formálního popisu / známý algoritmus**\
|
||||
Pokud lze napsat formální popis tříd, lze klasifikátor realizovat přímo pomocí programu.
|
||||
|
||||
Takový formální popis může mít podobu např. konečného automatu, gramatiky, predikátových formulí, atd.
|
||||
|
||||
- **Učení pod dohledem / supervised learning**\
|
||||
Program se nejprve vytrénuje na už oklasifikované množině dat. Poté se použije na nová data. Patří sem např.:
|
||||
|
||||
- Neuronové sítě.
|
||||
- Support vector machines.
|
||||
|
||||
- **Učení bez dohledu / unsupervised learning**\
|
||||
Program se sám naučí rozpoznávat třídy. Patří sem např.:
|
||||
|
||||
- Hierarchické shlukování.
|
||||
- K-means clustering.
|
||||
- Self-organizing maps.
|
||||
|
||||
- **Hierarchické shlukování / hierarchical clustering**\
|
||||
Shlukuje objekty podle konektivity.
|
||||
|
||||
1. Každý objekt je jeden shluk.
|
||||
2. Opakovaně spojujeme dva nejbližší shluky.
|
||||
|
||||

|
||||
|
||||
- **K-means clustering**\
|
||||
Shlukuje objekty podle těžišť. Počet shluků je pevně stanovený na $k$.
|
||||
|
||||

|
||||
|
||||
### Kvalita klasifikace
|
||||
|
||||
- **Typ výsledku**
|
||||
|
||||
- _True positive (TP)_: klasifikátor říká, že objekt do třídy **patří**, a je to tak.
|
||||
- _True negative (TN)_: klasifikátor říká, že objekt do třídy **nepatří**, a je to tak.
|
||||
- _False positive (FP)_: klasifikátor říká, že objekt do třídy **patří**, ale je to **blbost**.
|
||||
- _False negative (FN)_: klasifikátor říká, že objekt do třídy **nepatří**, ale je to **blbost**.
|
||||
|
||||

|
||||
|
||||
- **Precision**
|
||||
|
||||
```math
|
||||
\frac{TP}{TP + FP}
|
||||
```
|
||||
|
||||
- **Sensitivity / recall**
|
||||
|
||||
```math
|
||||
\frac{TP}{TP + FN}
|
||||
```
|
||||
|
||||
- **Specificity**
|
||||
|
||||
```math
|
||||
\frac{TN}{TN + FP}
|
||||
```
|
||||
|
||||
- **Accuracy**
|
||||
|
||||
```math
|
||||
\frac{TP + TN}{TP + TN + FP + FN}
|
||||
```
|
||||
|
||||
- **Ground truth (GT)**\
|
||||
Informace o které víme, že je pravdivá. Její získání se liší problém od problému:
|
||||
|
||||
- _Není známa, je dána odborníky._
|
||||
- Velmi subjektivní, proto se může zapojit více odborníků. Výsledky jsou sločeny hlasováním.
|
||||
- _Je známa, určena z předchozích znalostí._
|
||||
- Získavají se z předchozích měření, nebo získané z jiných zdrojů.
|
||||
- Standardizované testovací objekty, fantomy lidských orgánů, atd.
|
||||
- _Je známa přesně a úplně pro velký soubor dat._
|
||||
- Vstupní objekty i jejich obrázky jsou simulovány.
|
||||
- Digitální fantomy.
|
||||
|
||||
Pomocí GT lze ověřit:
|
||||
|
||||
- _Výsledky segmentace_
|
||||
- GT udává správnou binární masku. Kvalitu segmentačního algoritmu lze měřit pomocí korelačních koeficientů jako je Dice, Jaccard, atd.
|
||||
- _Výsledky měření_: plocha, objem, atd.
|
||||
- GT udává správné hodnoty měřených parametrů. Chyba je dána rozdílem mezi výsledkem a GT.
|
||||
- _Výsledky klasifikace_
|
||||
- GT udává správné třídy. Kvalitu určujeme na základě poměrů TP, TN, FP, FN.
|
||||
- _Statistické výsledky_
|
||||
- GT udává míru výskytu (v procentech) pro každou třídu. Přesnost měříme srovnáním s GT.
|
||||
|
||||
## Mapa vzdáleností
|
||||
|
||||
Mapování, které každému pixelu popředí přiřazuje vzdálenost k nejbližšímu pixelu pozadí. Používá se třeba pro:
|
||||
|
||||
- Oddělení dotýkajících se objektů.
|
||||
- Výpočet morfologických operátorů.
|
||||
- Výpočet geometrických reprezentací a měr: kostra, Voroného diagram, osy souměrnosti, atd.
|
||||
- Navigace robotů.
|
||||
- Porovnávání vzorů.
|
||||
|
||||

|
||||
|
||||
- **Metriky vzdálenosti**
|
||||
|
||||
- Euklidovská $\textcolor{red}{D_E}$.
|
||||
- Taxikářská $\textcolor{blue}{D_4}$.
|
||||
- Šachovnicová $\textcolor{green}{D_8}$.
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
\textcolor{red}{D_E}(\lbrack x_1, y_1 \rbrack, \lbrack x_2, y_2 \rbrack ) &= \sqrt{(x_2 - x_1)^2 + (y_2 - y_1)^2} \\
|
||||
\textcolor{blue}{D_4}(\lbrack x_1, y_1 \rbrack, \lbrack x_2, y_2 \rbrack ) &= |x_2-x_1| + |y_2-y_1| \\
|
||||
\textcolor{green}{D_8}(\lbrack x_1, y_1 \rbrack, \lbrack x_2, y_2 \rbrack ) &= \max(|x_2-x_1|, |y_2-y_1|)
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||

|
||||
|
||||
## Matematická morfologie
|
||||
|
||||
Teorie a techniky pro analýzu geometrických struktur. Jsou založené na teorii množin, topologii, atd. Nejčastěji se aplikuje na digitální binární obrazy, ale dá se použít na grafy, meshe, apod. [morphology](#morphology)
|
||||
|
||||
- **Binární obraz**\
|
||||
Dá se vnímat jako funkce $I: \Omega \rightarrow \{0, 1\}$, kde $\Omega \sub \mathbb{Z}^2$.
|
||||
|
||||
Ale taky to je množina $F = \{ (x, y) | I(x, y) = 1 \}$
|
||||
|
||||
### Základní operátory
|
||||
|
||||
Pracují na každém pixelu a jeho okolí -- strukturním elementu.
|
||||
|
||||
- **Strukturní element / structuring element (SE)**\
|
||||
Množina souřadnic, pomocí které je obraz zpracováván. [pb130](#pb130)
|
||||
|
||||
- Má definovaný _počátek_ -- $(0, 0)$. Schematicky se značí křížkem.
|
||||
- Aktuálně uvažovaná souřadnice do něj nemusí patřit.
|
||||
|
||||

|
||||
|
||||
- **Posunutí množiny**\
|
||||
Nechť $F$ je množina souřadnic. Posunutí $F$ o vektor $b$ je množina:
|
||||
|
||||
```math
|
||||
F_b = \{ s | s = s' + b, s' \in F \}
|
||||
```
|
||||
|
||||
- **Zrcadlení SE**\
|
||||
Překlopení souřadnic podle počátku.
|
||||
|
||||
```math
|
||||
\breve{B} = \{ (-x, -y) | (x, y) \in B \}
|
||||
```
|
||||
|
||||
- **Eroze**
|
||||
|
||||
> **Vejde se celý** SE do obrazu na dané pozici? Pokud ano, ulož pozici.
|
||||
|
||||
Množina bodů takových, že SE posunutý tak, aby počátek odpovídal danému bodu, musí **celý patřit** do vyšetřované množiny.
|
||||
|
||||
```math
|
||||
\Large
|
||||
\varepsilon_B (X) = \{ x | B_x \subseteq X \}
|
||||
```
|
||||
|
||||
kde $B$ je SE a $X$ je vyšetřovaná množina / obraz.
|
||||
|
||||
_"Hloupý" algoritmus_: hledání minima v okolí daném SE.
|
||||
|
||||

|
||||
|
||||
- **Dilatace**
|
||||
|
||||
> **Zasáhne** SE vyšetřovanou množinu při umístění na dané pozici? Pokud ano, ulož pozici.
|
||||
|
||||
Množina bodů takových, že SE posunutý tak, aby počátek odpovídal danému bodu, **aspoň částečně zasáhne** vyšetřovanou množinu.
|
||||
|
||||
```math
|
||||
\Large
|
||||
\delta_B (X) = \{ x | B_x \cap X \neq \emptyset \}
|
||||
```
|
||||
|
||||
kde $B$ je SE a $X$ je vyšetřovaná množina / obraz.
|
||||
|
||||
_"Hloupý" algoritmus_: hledání maxima v okolí daném SE.
|
||||
|
||||

|
||||
|
||||
- **Otevření / opening**
|
||||
|
||||
> **Vejde se celý SE** do vyšetřované množiny na dané pozici? Pokud ano, tak jej **celý ulož** na tuto pozici.
|
||||
|
||||
Snaha o obnovu obrazu po jeho erozi. Je to eroze a pak dilatace s překlopeným SE.
|
||||
|
||||
- Nezávisí na počátku SE.
|
||||
- Odstraňuje jednotlivá lokální maxima, tenké čáry a rozděluje objekty spojené úzkou cestou.
|
||||
|
||||
```math
|
||||
\Large
|
||||
\begin{aligned}
|
||||
|
||||
\gamma_B (X) &= \delta_{\breve{B}} (\varepsilon_B (X)) \\
|
||||
\gamma_B (X) &= \{ B_x | B_x \sube X, x \in X \} \\
|
||||
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
kde $B$ je SE a $X$ je vyšetřovaná množina / obraz.
|
||||
|
||||

|
||||
|
||||
- **Uzavření / closing**
|
||||
|
||||
> **Vejde se SE do pozadí** vyšetřované množiny? Pokud ano, tak jej **celý ulož** do komplementu výsledku.
|
||||
|
||||
Snaha o obnovu obrazu po jeho dilataci. Je to dilatace a pak eroze s překlopeným SE.
|
||||
|
||||
- Nezávisí na počátku SE.
|
||||
- Spojuje husté aglomerace lokálních maxim dohromady, vyplňuje malé dírky a vyhlazuje hranice.
|
||||
|
||||
```math
|
||||
\Large
|
||||
\begin{aligned}
|
||||
|
||||
\theta_B (X) &= \varepsilon_{\breve{B}} (\delta_B (X)) \\
|
||||
\theta_B (X) &= \left\lbrack \bigcup_{x \in X} B_x \sube X^c \right\rbrack^c
|
||||
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
kde $B$ je SE a $X$ je vyšetřovaná množina / obraz.
|
||||
|
||||

|
||||
|
||||
### Pokročilejší-ish operace
|
||||
|
||||
- **Hit-or-miss**\
|
||||
Mějme SE složený ze dvou disjunktních množin. Jedna z nich odpovídá pozadí, druhá objektu / popředí.
|
||||
|
||||
```math
|
||||
\Large
|
||||
B = (B_\text{fg}, B_\text{bg}), B_\text{fg} \cap B_\text{bg} = \emptyset
|
||||
```
|
||||
|
||||

|
||||
|
||||
> **Vejde se první část SE** do vyšetřované množiny na dané pozici a současně **druhá část SE** ji zcela **mine**? Pokud ano, tak ulož tuto pozici
|
||||
|
||||
```math
|
||||
\Large
|
||||
|
||||
\text{HMT}_B(X) = \{ x | (B_\text{fg})_s \sube X, (B_\text{bg})_s \sube X^c \}
|
||||
```
|
||||
|
||||
Používá se k:
|
||||
|
||||
- Nalezení instancí konkrétní konfigure pixelů. Například _izolovaných_ pixelů, které jen tak chillují uprostřed ničeho.
|
||||
- _Vytváření kostry / skeletonizing_: body kosty mají stejnou vzdálenost od hranice objektu.
|
||||
- _Ztenčování / thinning_: převod objektů bez děr na čáry; objektů s dírami na uzavřené smyčky.
|
||||
- _Scvrkávání / shrinking_: převod objektů bez děr na izolované body poblíž jejich těžiště; objektů s dírami na uzavřené smyčky.
|
||||
|
||||

|
||||
|
||||
- **Top-hat transformace**\
|
||||
Morfologické transformace obrazu užitečné např. pro korekci nerovnoměrného osvětlení.
|
||||
|
||||
- _Bílý top-hat_: rozdíl mezi vstupním obrazem a jeho otevřením.
|
||||
- Extrahuje světlé skvrny (lokální maxima) nezávisle na jejich intenzitě, bere v úvahu pouze tvar.
|
||||
- _Černý top-hat_: rozdíl mezi uzavřením a vstupním obrazem.
|
||||
- Extrahuje tmavé skvrny (lokální minima) nezávisle na jejich intenzitě, bere v úvahu pouze tvar.
|
||||
|
||||

|
||||
|
||||
- **Watershed**\
|
||||
Algoritmický přístup k segmentaci skrze matematickou morfologii. Kombinuje segmentaci _narůstáním oblastí_ a _detekcí hran_. [pb130](#pb130)
|
||||
|
||||
- Simulace zvyšování hladiny vody krok za krokem.
|
||||
- Obraz vnímán jako topografický povrch. Ve všech lokálních minimech je "udělána díra" odkud stoupá hladina vody.
|
||||
- Postupně zvyšujeme hladinu za vzniku _bazénů / catchment basins_.
|
||||
- Když už by se měly dva bazény spojit, zabráníme tomu postavením hrází.
|
||||
- Hráze tvoří _čáry rozvodí / watershed lines_.
|
||||
|
||||
Postup:
|
||||
|
||||
1. Vyhlaď obrázek např. pomocí Gaussova filtru.
|
||||
2. Zjisti maximální a minimální intenzitu obrazu: $(a_\text{high}, a_\text{low})$.
|
||||
3. Urči značky pro budoucí objekty (manuálně nebo z lokálních minim).
|
||||
4. Inicializuj binární obraz $B$ vynulováním.
|
||||
5. Pro $a$ od $a_\text{low}$ do $a_\text{high}$:
|
||||
1. Nech narůst oblasti značek, tak aby byly do $B$ přidány pixely s intenzitou $\leq a$.
|
||||
2. Nedovol spojení oblastí různých značek.
|
||||
6. $B$ nyní definuje oblasti objektů. Počet objektů je roven počtu značek.
|
||||
|
||||

|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[pb130,1]]] [PB130 Úvod do digitálního zpracování obrazu (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PB130/)
|
||||
- [[[pv131,2]]] [PV131 Digitální zpracování obrazu (jaro 2023)](https://is.muni.cz/auth/el/fi/jaro2023/PV131/)
|
||||
- [[[image-moment,3]]] [Wikipedia: Image moment](https://en.wikipedia.org/wiki/Image_moment)
|
||||
- [[[moment, 4]]] [Wikipedia: Moment (mathematics)](<https://en.wikipedia.org/wiki/Moment_(mathematics)>)
|
||||
- [[[morphology, 5]]] [Wikipedia: Mathematical morphology](https://en.wikipedia.org/wiki/Mathematical_morphology)
|
||||
|
||||
## Další zdroje
|
||||
|
||||
- Haralick, Shapiro: Image segmentation techniques
|
||||
- [Zhang, Fritts, Goldman: Image segmentation evaluation: A survey of unsupervised methods](https://www.sciencedirect.com/science/article/pii/S1077314207001294#bib46)
|
||||
- [What is the reasoning behind using "moment" in the "moment of inertia"?](https://hsm.stackexchange.com/questions/11433/what-is-the-reasoning-behind-using-moment-in-the-moment-of-inertia)
|
263
src/content/docs/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md
Normal file
263
src/content/docs/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md
Normal file
@ -0,0 +1,263 @@
|
||||
---
|
||||
title: "Grafické principy ve vývoji her (2024)"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Příprava a vývoj scény (grayboxing, zástupné modely (placeholders)). Lokální a globální modely nasvícení. Vykreslování založené na fyzikálních modelech (PBR). Techniky optimalizace výkonu vykreslování (úrovně detailů, řešení viditelnosti objektů (culling), MIP mapy).
|
||||
|
||||
_PB009, PA010, PA213, PV255_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
## Příprava a vývoj scény
|
||||
|
||||
**📌 NOTE**\
|
||||
Poznámky o grayboxingu, iterování, modulárním workflow, atd. jsou z přednášky Lukáše Medka v rámci PV255. [medek](#medek)
|
||||
|
||||
- **Iterace**\
|
||||
Práce v iteracích pomáhá:
|
||||
|
||||
- udržet konzistenci,
|
||||
- mít přehled o objemu práce,
|
||||
- průběžně přídávat obsah a
|
||||
- šetřit čas.
|
||||
|
||||
- **Základní workflow**
|
||||
1. Modelování high-poly a low-poly modelů
|
||||
2. Unwrap
|
||||
3. Tvorba textur a materiálů
|
||||
4. Vypečení map (normály, bump, atd.)
|
||||
5. Aplikace shaderu v engine
|
||||
6. Optimalizace
|
||||
- **Grayboxing**
|
||||
- Rychlý nástřel modelu / scény / prostředí.
|
||||
- Obrovská časová úspora při tvorbě assetů. Místo jejich finální podoby se používají placeholdery (obvykle šedé krabice).
|
||||
- Umožňuje implementovat mechaniky bez nutnosti čekat na assety.
|
||||
- Limituje odpad -- nevyužité assety -- při změnách nebo škrtech.
|
||||
- **Modulární workflow**\
|
||||
Využití malého množství assetů pro vytvoření rozsáhlého prostředí. Nutná promyšlená preprodukce. [modular](#modular)
|
||||
- **Modulární textury**\
|
||||
Textury aplikovatelné na více modelů. Je potřeba na všechna využití myslet při vytváření textury.
|
||||
- **Placeholders**\
|
||||
Zjednodušené / low-poly / koupené / kradené modely nebo šedé / oranžové / libovolné krabice, které jsou v pohodě pro prototyping, ale neměly by být ve finální hře.
|
||||
|
||||
## Modely nasvícení (illumination models)
|
||||
|
||||
- **Lokální osvětlení (local illumination) / direct lighting**\
|
||||
Berou v úvahu jen světlo, které dopadá přímo na daný bod/objekt. Neřeší okolní objekty, ani nepřímé osvětlení. Je založený na empirických znalostech o chování světla, spíš než simulaci fyzikálních zákonů.
|
||||
|
||||
Patří sem Blinn-Phong, pomineme-li jeho ambientní složku.
|
||||
|
||||
- **Globální osvětlení (global illumination)**\
|
||||
Řeší nejen přímé osvětlení, ale i odrazy, lomy, průhlednost, stíny, atd.
|
||||
- **Ambient illumination**\
|
||||
Aproximace globálního osvětlení pomocí konstantní ambientní barvy.
|
||||
- **Ray tracing**\
|
||||
Metoda, kdy simulujeme paprsky světla vycházející ze zdroje světla a dopadající na scénu. Používá se jak k lokální tak globální iluminaci. Počítáme však jen to, co vidí kamera, jelikož posíláme paprsky skrze pixely. Pokud se kamera pohne, musíme znovu paprsky zpravidla počítat znovu.
|
||||
- **Radiosity (metoda osvětlení)**\
|
||||
Metoda, kdy scénu rozdělíme na segmenty a simulujeme "přelévání" světla mezi segmenty. Je vypočetně náročné, ale nezávisí na pozici a směru kamery.
|
||||
|
||||
## Physically based rendering (PBR)
|
||||
|
||||
Physically based rendering (PBR) je způsob renderování, který se snaží co nejvíce aproximovat realitu pomocí fyzikálních modelů světla, stínů, materiálů, očí, atd. [pv227-2022](#pv227-2022) Aproximuje efekty jako absorpci světla nebo jeho rozptyl pod povrchem objektů.
|
||||
|
||||
- **Absorption and scattering / absorpce a rozptyl**\
|
||||
Materiály mohou světlo buď absorbovat (v takovém případě jsou alespoň částěčně průhledné) nebo odrážet a rozptylovat (objekty jsou matné). Většina materiálů kombinuje oba efekty. Světlo se může rozpylovat i pod povrchem (subsurface scattering).
|
||||
- **Reflection / odraz světla**\
|
||||
V nejjednodušším případě se úhel odrazu rovná úhlu dopadu. V realitě úhel odrazu však záleží na mnoha faktorech jako je i vlnová délka světla. Toto chování popisují Fresnelovy rovnice. Znamená to, že odraz má barvu. V praxi používáme Schlickovu aproximaci:
|
||||
|
||||
```math
|
||||
F_\text{Schlick}(F_0, L, N) = F_0 + (1 - F_0) \cdot (1 - L \cdot N)^5
|
||||
```
|
||||
|
||||
kde:
|
||||
|
||||
- $F_0$ je Fresnelův odraz při úhlu 0 (dá se dohledat pro daný materiál),
|
||||
- $L$ je vektor směru světla,
|
||||
- $N$ je vektor normály povrchu.
|
||||
|
||||
**Z určitého úhlu se povrchy, které normálně světlo odráží špatně, jeví jako zrcadla ([tanakawho](https://commons.wikimedia.org/w/index.php?curid=2138545))**
|
||||
|
||||

|
||||
|
||||
- **Refraction / lom světla**\
|
||||
Kovy světlo absorbují, v homogenních materiálech (např. sklo) pokračuje v jiném směru, a v heterogenních materiálech (např. kůži) se světlo rozptýlí a pak absorbuje. Lom světla popisuje Snellův zákon:
|
||||
|
||||
```math
|
||||
\frac{\sin \alpha_1}{\sin \alpha_2} = \frac{v_1}{v_2} = \frac{n_2}{n_1}
|
||||
```
|
||||
|
||||
kde:
|
||||
|
||||
- $\alpha_1$ je úhel dopadu (angle of incidence),
|
||||
- $\alpha_2$ je úhel lomu (angle of refraction),
|
||||
- $v_1$ je rychlost šíření vlnění ve vnějším prostředí,
|
||||
- $v_2$ je rychlost šíření vlnění v prostředí objektu,
|
||||
- $n_1$ je index lomu vnějšího prostředí,
|
||||
- $n_2$ je index lomu prostředí objektu.
|
||||
|
||||

|
||||
|
||||
- **Diffuse lighting**\
|
||||
Když všechno (neabsorbované) světlo opustí objekt ze stejného místa, kam dopadlo.
|
||||
|
||||

|
||||
|
||||
- **Subsurface scattering**\
|
||||
Když neabsorbované světlo opustí objekt z jiného místa, než kam dopadlo.
|
||||
|
||||

|
||||
|
||||
- **Microfacets / mikro-plošky**\
|
||||
Ne všechny objekty jsou ploché. Většina má nerovnosti, které jsou menší než pixel, ale větší než vlnová délka dopadajícího světla, proto je modelujeme nějakou pravděpodobností distribucí (např. Gaussovou).
|
||||
|
||||

|
||||
|
||||
Existuje řada modelů chování microfacet, např. Cook-Torrance, Oren-Nayar, Ashnikmin-Shirley, Normalized Blinn-Phong, atd.
|
||||
|
||||
- **Geometrická atenuace**\
|
||||
Postupná ztráta "intenzity" paprsku v důsledku geometrie objektu.
|
||||
|
||||
- **Shadowing** -- facety zastiňují jiné facety.
|
||||
- **Masking** -- facet nejde vidět, protože ho zastiňuje jiný facet.
|
||||
- **Interreflection** -- světlo se odráží mezi facety, než je odraženo zpátky ke kameře.
|
||||
|
||||
### Fyzikální věličiny radiometrie
|
||||
|
||||
- **Radiant energy / energie záření (Q)**\
|
||||
"Energy per one photon."
|
||||
|
||||
Jednotka: Joule (J)
|
||||
|
||||
- **Radiant flux, radiant power / zářivý tok ($\Phi$)**\
|
||||
"Energy per second." Bezva na popisování síly světel jako jsou žárovky, plošná světla, atd.
|
||||
|
||||
```math
|
||||
\Phi = \frac{\partial Q}{\partial t}
|
||||
```
|
||||
|
||||
Jednotka: Watt (W) = J/s
|
||||
|
||||
- **Irradiance / ozářenost, ozáření (E)**\
|
||||
"Flux through area." Světlo dopadající na jednotku plochy. Kvadraticky se zmenšuje s rostoucí vzdáleností od zdroje. Bezva na popis vzdálených zdrojů jako je slunce.
|
||||
|
||||
```math
|
||||
E = \frac{\partial \Phi}{\partial A}
|
||||
```
|
||||
|
||||
Jednotka: Watt per square meter ($\frac{W}{m^2}$)
|
||||
|
||||
- **Radiosity / radiozita (radiometrická veličina) (J)**\
|
||||
Jako irradiance, ale je to světlo _vycházející_ z jednotky plochy.
|
||||
- **Radiance / zář (L)**\
|
||||
"Flux through a cone of directions from an area." a nebo "Flux through an area from a cone of directions." Nezmenšuje se se zvětšující se vzdáleností od zdroje. Tohle měří senzory.
|
||||
|
||||
```math
|
||||
L = \frac{\partial^2 \Phi}{\partial A_\text{proj} \partial \omega}
|
||||
```
|
||||
|
||||
Jednotka: Watt per square meter per steradian ($\frac{W}{m^2 \cdot sr}$)
|
||||
|
||||
### Bidirectional Reflectance Distribution Function (BRDF)
|
||||
|
||||
Funkce popisující poměr mezi dopajícím a odraženým světlem na povrchu objektu.
|
||||
|
||||
```math
|
||||
f(\vec{l}, \vec{v}) = \frac{\partial L_o(\vec{v})}{\partial E_i(\vec{l})}
|
||||
```
|
||||
|
||||
_Povrch je nasvícen ze směru $\vec{l}$ s ozářením $\partial E(\vec{l})$. $\partial(L_o(\vec{v}))$ je odražená zář ve směru $\vec{v}$._
|
||||
|
||||
Udává pravděpodobnost, že světlo dopadající na povrch ze směru $\vec{l}$ bude odraženo ve směru $\vec{v}$.
|
||||
|
||||
Z pohledu teorie pravděpodobnosti / statistiky to ale není distribuční funkce ale spíš hustota pravděpodobnosti.
|
||||
|
||||
BRDF je řešena pomocí ray tracingu, radiosity, nebo nějakým hybridním řešením.
|
||||
|
||||
## Optimizalizace výkonu vykreslování
|
||||
|
||||
- **Level-of-detail (LOD) / úrovně detailů**\
|
||||
Čím větší vzdálenost, tím méně detailů. [pv255-2022](#pv255-2022)
|
||||
|
||||
Pro každý model máme hierarchii modelů s různým počtem polygonů. V závislosti na vzdálenosti od pozorovatele vybíráme vhodný LOD.
|
||||
|
||||

|
||||
|
||||
Dají se vytvořit _manuálně_ i _automaticky_ (pomocí algoritmů pro mesh reduction / decimation).
|
||||
|
||||
- **Diskrétní LOD**\
|
||||
Existuje fixní počet variant meshe, mezi kterými se přepíná diskrétně. Nevýhodou je "popping" efekt.
|
||||
- **Continous LOD**\
|
||||
Mezi variantami se nepřepíná "ráz naráz", ale postupně tak, že v jeden moment jsou vykresly dva LODy přes sebe a blendovány pomocí alpha kanálu.
|
||||
- **Geomorphic LOD**\
|
||||
Redukuje popping postupnou "proměnnou" jednoho LODu na druhý odebíráním a přidáváním hran. Generuje approximované mezistavy.
|
||||
|
||||
**Geomorphing by [Sirotk](https://commons.wikimedia.org/w/index.php?curid=24515584)**
|
||||
|
||||

|
||||
|
||||
- **Hierarchical LOD**\
|
||||
Seskupuje objekty ve scéně do hierarchie a zjednodušuje celé skupiny objektů najednou. Vede k lepšímu výkonu.
|
||||
- **Texture filtering**\
|
||||
Popisuje, jakým způsobem se pixely textury (texely) mapují na pixely obrazovky / daného polygonu. [texture-mapping](#texture-mapping)
|
||||
|
||||
Součástí problému je potřeba odhadnout, jak velkou plochu polygon zabere na obrazovce.
|
||||
|
||||
- **Mipmapy**
|
||||
|
||||
> multum in parvo -- mnoho v malém prostoru
|
||||
|
||||
V zásadě LOD na texturách. Z velikosti $\delta$ otexturovaného polygonu je LOD $D = \log_2(\max(\delta, 1))$. Výsledek je získán interpolací mezi LODy $\lfloor D \rfloor$ a $\lceil D \rceil$.
|
||||
|
||||
Mimojiné je to tedy přístup k texture filteringu, kdy aproximujeme velikost polygonu pomocí čtverce daného úrovní mipmapy.
|
||||
|
||||
**Separate color channels of a mipmapped texture by [Phorgan1](https://commons.wikimedia.org/w/index.php?curid=27311755)**
|
||||
|
||||

|
||||
|
||||
**💡 TIP**\
|
||||
Jak je patrné z obrázku výše, chytrým uložením je mipmapovaná textura jen o 33 % větší než původní textura. (Nová má velikost $\frac{4}{3}$ té staré.)
|
||||
|
||||
- **Shaderové / GPU optimalizace**\
|
||||
Existuje řada nástrojů, které umožňují debugovat a optimalizovat GPU:
|
||||
|
||||
- _V Unity:_ Rendering Statistics, Frame Debugger
|
||||
- _nVidia Nsight:_ obecné debuggování GPU
|
||||
- _Intel Graphics Performance Analyzers:_ obecné debuggování GPU
|
||||
- _RenderDoc:_ debuggování OpenGL, DirectX a Vulkan
|
||||
|
||||
- **Object culling / ostřelování objektů**\
|
||||
Nalézání podmnožiny objektů ve scéně, která může být vynechána, aniž by viditelně ovlivnila výsledný obraz. Počítání přesné viditelnosti je příliš náročné, proto se používají aproximace známé jako _potentially visible set_ (PVS). [pa010-2021](#pa010-2021)
|
||||
- **Back-face culling**\
|
||||
Vykreslování pouze předních stran polygonů.
|
||||
- **View frustum culling**\
|
||||
Vykreslování pouze objektů, které jsou v zorném poli kamery.
|
||||
- **Occlusion culling**\
|
||||
Vykreslování pouze objektů, které nejsou zakryty jinými objekty.
|
||||
|
||||

|
||||
|
||||
- **Portal culling**\
|
||||
Užitečné, pokud máme statickou scénu, kde jsou některé části viditelné jen z některých jiných částí (např. místnosti v domě). Část dat potřebných pro odstřel tak může být předpočítána.
|
||||
|
||||

|
||||

|
||||
|
||||
- **Obecné zásady**
|
||||
- Nevykreslovat co není nutné (zahazovat na CPU, využívat předchozí snímky)
|
||||
- LODovat
|
||||
- Batching (Unity) -- shlukovat geometrie a vykreslovat naráz
|
||||
- Instancing -- vykreslovat vícero instancí stejného objektu naráz
|
||||
- Minimalizovat počet materiálů (např. spojováním textur).
|
||||
- Vypéct všechni nedynamické (statická světla, stíny, atd.)
|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[medek,1]]]: [Lukáš Medek (CBE), Základní postupy při tvorbě assetů a herního vizuálu](++http://decibel.fi.muni.cz/pv255/2018/slides/PV255_-_06_-_Zakladni_postupy_pri_tvorbe_assetu_a_herniho_vizualu.pdf++)
|
||||
- [[[modular,2]]]: http://wiki.polycount.com/wiki/Modular_environments
|
||||
- [[[pv227-2022, 3]]] [PV227 GPU Rendering (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PV227/)
|
||||
- [[[pv255-2022,4]]] [Chmelík, PV255 Game Development I](https://is.muni.cz/auth/el/fi/podzim2022/PV255/um/)
|
||||
- [[[texture-mapping, 5]]] [Wikipedia: Texture mapping](https://en.wikipedia.org/wiki/Texture_mapping)
|
||||
- [[[pa010-2021,6]]] [Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021)](https://is.muni.cz/auth/el/fi/podzim2021/PA010/um/)
|
387
src/content/docs/szmgr/VPH01_pokrocila_grafika.md
Normal file
387
src/content/docs/szmgr/VPH01_pokrocila_grafika.md
Normal file
@ -0,0 +1,387 @@
|
||||
---
|
||||
title: "Pokročilá počítačová grafika (2023)"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
**⚠️ WARNING**\
|
||||
Tato je stará verze otázky. Nová verze: [Grafické principy ve vývoji her](./VPH01_graficke_principy_ve_vyvoji_her.ad).
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Techniky aproximace objektů. Renderování objemových dat (bodový mrak, techniky rekonstrukce povrchů, přímé renderování objemu). Lokální a globální modely nasvícení. Renderování založené na fyzikálních modelech (PBR). Techniky renderování stínů.
|
||||
|
||||
_PA010, PA213_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
## Techniky aproximace objektů
|
||||
|
||||
3D objekty mohou být definované mnoha miliony polygony či výpočetně náročnými matematickými funkcemi. Pro renderování v reálném čase je tedy žádoucí je zjednodušit a přitom zachovat jejich vzhled -- aproximovat je.
|
||||
|
||||
**❗ IMPORTANT**\
|
||||
Aproximace objektů souvisí s collidery, kterým se částečně věnuje otázka [Grafické a fyzikální principy](../graficke-a-fyzikalni-principy/).
|
||||
|
||||
### Redukce počtu polygonů
|
||||
|
||||
Slučování polygonů (merging) či odstranění polygonů (culling), které nejsou vidět. [pa010-2021](#pa010-2021)
|
||||
|
||||
- **Variational Shape Approximation**
|
||||
|
||||
1. Cluster surface elements (e.g. triangles) into $k$ regions.
|
||||
- Start with random seed.
|
||||
- Apply region growing based on proximity, orientation, etc.
|
||||
- Refine seeds (find best representatives) and repeat until regions stabilize.
|
||||
2. Fit each region into a proxy (e.g. plane) with minimum error.
|
||||
|
||||
- E.g. by using a weighted average of triangle normals.
|
||||
|
||||

|
||||
|
||||
- **Iterative Decimation -- Edge Collapse Simplification**
|
||||
|
||||
1. Přiřaď každé hraně cenu (třeba quadratic error metric -- suma vzdáleností bodu od rovin)
|
||||
2. Zbab se hrany s nejnižší cenou sloučením jejích vrcholů.
|
||||
3. Opakuj, dokud nemáš požadovaný počet polygonů.
|
||||
|
||||

|
||||
|
||||
### Implicitní reprezentace
|
||||
|
||||
Pokud dokážeme model vyjádřit pomocí matematických funkcí, nemusíme ukládat polygonovou síť. Např. koule je definována jako $x^2 + y^2 + z^2 = r^2$. Šetří prostor, plyne z ní však nutnost výpočtu. Ne všechny modely je možné takto vyjádřit jednoduše.
|
||||
|
||||
- **Constructive solid geometry (CSG)**\
|
||||
Dokáže reprezentovat komplexní objekty jako kombinace primitiv (krychle, koule, válec, ...). Tyto primitiva jsou následně transformována (posun, rotace, škálování) a kombinována (sjednocení, průnik, rozdíl).
|
||||
|
||||
Šetří místo, ale je náročnější na výpočetní výkon než polygonová síť.
|
||||
|
||||
### Zjednodušení vzhledu
|
||||
|
||||
Nemusíme zjednodušovat jen povrch/objem modelu, ale i související atributy. Můžeme snížit rozlišení textur, či snížit počet barev v paletě. Pokud používáme PBR, můžeme upravit parametry materiálu nebo použít jednodušší model osvětlení.
|
||||
|
||||
### Bounding Volume Hierarchies (BVH)
|
||||
|
||||
Hierarchie _bounding volumes_ -- jednoduchých objektů jako jsou kostky, koule, apod. -- které obsahují nějakou část objektu / geometrie scény. Používá se k rychlým průchodům scénou, např. při detekci kolizí, ray tracingu, atd. Svým způsobem jde tím pádem také o aproximaci objektů.
|
||||
|
||||
- **Discrete Oriented Polytopes (DOP)**\
|
||||
Generaliace bounding boxu. k-DOP je konvexní polytop -- generalizace mnohoúhelníků ve 2D, mnohostěnů ve 3D atd. -- který vzniká průnikem $k$ bounding slabů -- prostorů mezi dvě paralelními rovinami daných osou a vzdáleností mezi rovinami. Použitých os může být více než je dimenze prostoru. Např. 3D scéna může mít 13-DOP.
|
||||
|
||||
## Renderování objemových dat
|
||||
|
||||
- **Voxel**\
|
||||
Voxel je 3D analogií pixelu -- bod v prostoru, který má určitou hodnotu (např. barvu, intenzitu, ...). Voxelová data mohou být získána (např. pomocí CT, MRI, PET, atd.) nebo být také výsledkem simulace (např. simulace proudění tekutin).
|
||||
- **Objemová data**
|
||||
|
||||
Objemová data jsou definována nejčastěji jako mřížka voxelů.
|
||||
|
||||
Při renderování objemů je třeba vyřešit několik souvisejících problémů s daty:
|
||||
|
||||
- Data s neuniformním vzorkem.
|
||||
- Chybějící data.
|
||||
- Šum a outlieři.
|
||||
|
||||
Kromě pozic mohou surová data obsahovat také normály, barvy, apod.
|
||||
|
||||
### Bodový mrak (point cloud)
|
||||
|
||||
Množina bodů v prostoru, které nemají žádnou strukturu. Nejjednodušší přístup k renderování objemu, kdy se nepokoušíme o žádnou rekonstrukci povrchu. Body však mohou mít různé barvy a průhlednost.
|
||||
|
||||
### Rekonstrukce povrchu
|
||||
|
||||
Ze získaných dat se snažíme vytvořit mesh. Ten lze vyrenderovat tradičním způsobem.
|
||||
|
||||
- **Marching cubes**\
|
||||
Rozděluje prostor na mřížku voxelů. V každém voxelu se pak vyhodnocuje, zda je povrch objektu překročen. Pokud ano, je třeba přidat triangle mesh pro daný voxel. [pa010-2020](#pa010-2020) [marching-cubes](#marching-cubes)
|
||||
|
||||
**Marching cubes by [Ryoshoru](https://commons.wikimedia.org/wiki/File:MarchingCubesEdit.svg)**
|
||||
|
||||

|
||||
|
||||
- **Marching tetrahedra**\
|
||||
Analogický k marching cubes, ale používá místo krychlí čtyřstěny. Řeší problém s některými nejednoznačnými konfiguracemi v marching cubes, a taky nikdy nebyl patentován (kdežto marching cubes ano). [marching-tetrahedra](#marching-tetrahedra)
|
||||
- **Vertex clustering**\
|
||||
Metoda podobná _iterative decimation_ (viz výše), nejprve vytvoříme clustery bodů, poté pro každý vybereme vhodného reprezentanta (např. průměrem, mediánem, quadric error minimization, atd.), pak už jen zbývá mesh "sešít" např. pomocí triangulace. [pa010-2020](#pa010-2020)
|
||||
- **Dual contouring**\
|
||||
Z voxelů se stanou vrcholy (tedy využíváme dualního grafu). Tyto vrcholy jsou ale posunuty tak, že povrch může obsahovat jak ostré hrany tak zaoblené plochy. [dual-contouring](#dual-contouring)
|
||||
- **Delaunay triangulation**\
|
||||
Vytváří trojúhelníkovou síť, tak že žádný bod se nenáchází ve vepsané kružnici žádného trojúhelníku. Maximalizuje nejmenší úhel trojúhelníků. [delaunay-triangulation](#delaunay-triangulation)
|
||||
|
||||

|
||||
|
||||
### Direct volume rendering (přímé renderování objemu)
|
||||
|
||||
Nerekonstruujeme povrch, ale mapujeme data na _optické_ vlastnosti jako je barva a průhlednost. Během renderování se pak využívá path tracing, a tyto vlastnosti se akumulují podél jednotlivých paprsků. [gpugems](#gpugems)
|
||||
|
||||
V realitě tohle chování paprsku popisujeme integrály. V počítačové grafice se ale využívá aproximace pomocí sumy.
|
||||
|
||||
**The Process of Volume Rendering [gpugems](#gpugems)**
|
||||
|
||||

|
||||
|
||||
- **Emmission-absorption model**\
|
||||
Paprsek vstupuje do objemu, kde je absorbován a emitován. Výsledná barva je pak výsledkem akumulace těchto vlastností. V notaci používáme: [pa213](#pa213)
|
||||
|
||||
- $\kappa$ je funkce absorpce,
|
||||
- $q$ je emise.
|
||||
|
||||
- **Optická hloubka / optical depth**\
|
||||
Bezrozměrná veličina $\tau$, která popisuje, jak moc jde "vidět skrz" něco, třeba plyn. Čím větší, tím méně vidíme.
|
||||
|
||||
Z jiné perspektivy je to akumulovaná absorpce na paprsku. Optická hloubka mezi dvěma body $s_1$ a $s_2$ na paprsku je dána jako:
|
||||
|
||||
```math
|
||||
\tau(s_1, s_2) = \int_{s_1}^{s_2} \kappa(s) ds
|
||||
```
|
||||
|
||||
- **Průhlednost / transparency**\
|
||||
Průhlednost popisuje, jak dobře vidíme skrz objem. Upadá exponenciálně s růstem optické hloubky.
|
||||
|
||||
Průhlednost mezi dvěma body $s_1$ a $s_2$ na paprsku je dána jako:
|
||||
|
||||
```math
|
||||
\theta(s_1, s_2) = e^{-\tau(s_1, s_2)}
|
||||
```
|
||||
|
||||
- **Volume rendering integral**\
|
||||
Intenzitu světla $I$ v místě paprsku $s$ počítáme pomocí: [pa213](#pa213)
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
|
||||
I(s) &= I(s_0) \cdot \theta(s_0, s) + \int_{s_0}^s q(s') \cdot \theta(s', s) ds' \\
|
||||
|
||||
&= I(s_0) \cdot e^{-\tau(s_0, s)} + \int_{s_0}^s q(s') \cdot e^{-\tau(s', s)} ds'
|
||||
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
kde:
|
||||
|
||||
- $s_0$ je místo, kde se paprsek dostal dovnitř nějakého světlo-vyzařujícího objemu,
|
||||
- $I(s_0)$ je boundary light, tedy světlo na hranici objemu,
|
||||
- $q(s')$ je emise v bodě $s'$.
|
||||
|
||||

|
||||
|
||||
- **Back-to-front**\
|
||||
Přístup k počítání $I$, kdy paprsky vyhodnocujeme od hranice objemu **dále** od kamery směrem **ke kaměře**.
|
||||
|
||||
Výhoda je, že nemusíme udržovat proměnnou pro průhlednost. Nevyhoda je, že musíme vyhodnotit všechny voxely v cestě paprsku, protože "přepisují" výsledek.
|
||||
|
||||
- **Front-to-back**\
|
||||
Přístup k počítání $I$, kdy paprsky vyhodnocujeme od hranice objemu **blíže** ke kameře směrem **od kamery**.
|
||||
|
||||
Dá se utnout dřív, když víme jistě, že už je výsledek neprůhledný a tedy už se nic nezmění.
|
||||
|
||||
- **Transfer function**\
|
||||
Funkce $T$, která mapuje hodnoty voxelů na barvu a průhlednost. Klasifikuje voxely. [pa213](#pa213)
|
||||
|
||||
## Modely nasvícení (illumination models)
|
||||
|
||||
- **Lokální osvětlení (local illumination) / direct lighting**\
|
||||
Berou v úvahu jen světlo, které dopadá přímo na daný bod/objekt. Neřeší okolní objekty, ani nepřímé osvětlení. Je založený na empirických znalostech o chování světla, spíš než simulaci fyzikálních zákonů.
|
||||
|
||||
Patří sem Blinn-Phong, pomineme-li jeho ambientní složku.
|
||||
|
||||
- **Globální osvětlení (global illumination)**\
|
||||
Řeší nejen přímé osvětlení, ale i odrazy, lomy, průhlednost, stíny, atd.
|
||||
- **Ambient illumination**\
|
||||
Aproximace globálního osvětlení pomocí konstantní ambientní barvy.
|
||||
- **Ray tracing**\
|
||||
Metoda, kdy simulujeme paprsky světla vycházející ze zdroje světla a dopadající na scénu. Používá se jak k lokální tak globální iluminaci. Počítáme však jen to, co vidí kamera, jelikož posíláme paprsky skrze pixely. Pokud se kamera pohne, musíme znovu paprsky zpravidla počítat znovu.
|
||||
- **Radiosity (metoda osvětlení)**\
|
||||
Metoda, kdy scénu rozdělíme na segmenty a simulujeme "přelévání" světla mezi segmenty. Je vypočetně náročné, ale nezávisí na pozici a směru kamery.
|
||||
|
||||
## Physically based rendering (PBR)
|
||||
|
||||
Physically based rendering (PBR) je způsob renderování, který se snaží co nejvíce aproximovat realitu pomocí fyzikálních modelů světla, stínů, materiálů, očí, atd. [pv227-2022](#pv227-2022) Aproximuje efekty jako absorpci světla nebo jeho rozptyl pod povrchem objektů.
|
||||
|
||||
- **Absorption and scattering / absorpce a rozptyl**\
|
||||
Materiály mohou světlo buď absorbovat (v takovém případě jsou alespoň částěčně průhledné) nebo odrážet a rozptylovat (objekty jsou matné). Většina materiálů kombinuje oba efekty. Světlo se může rozpylovat i pod povrchem (subsurface scattering).
|
||||
- **Reflection / odraz světla**\
|
||||
V nejjednodušším případě se úhel odrazu rovná úhlu dopadu. V realitě úhel odrazu však záleží na mnoha faktorech jako je i vlnová délka světla. Toto chování popisují Fresnelovy rovnice. Znamená to, že odraz má barvu. V praxi používáme Schlickovu aproximaci:
|
||||
|
||||
```math
|
||||
F_\text{Schlick}(F_0, L, N) = F_0 + (1 - F_0) \cdot (1 - L \cdot N)^5
|
||||
```
|
||||
|
||||
kde:
|
||||
|
||||
- $F_0$ je Fresnelův odraz při úhlu 0 (dá se dohledat pro daný materiál),
|
||||
- $L$ je vektor směru světla,
|
||||
- $N$ je vektor normály povrchu.
|
||||
|
||||
**Z určitého úhlu se povrchy, které normálně světlo odráží špatně, jeví jako zrcadla ([tanakawho](https://commons.wikimedia.org/w/index.php?curid=2138545))**
|
||||
|
||||

|
||||
|
||||
- **Refraction / lom světla**\
|
||||
Kovy světlo absorbují, v homogenních materiálech (např. sklo) pokračuje v jiném směru, a v heterogenních materiálech (např. kůži) se světlo rozptýlí a pak absorbuje. Lom světla popisuje Snellův zákon:
|
||||
|
||||
```math
|
||||
\frac{\sin \alpha_1}{\sin \alpha_2} = \frac{v_1}{v_2} = \frac{n_2}{n_1}
|
||||
```
|
||||
|
||||
kde:
|
||||
|
||||
- $\alpha_1$ je úhel dopadu (angle of incidence),
|
||||
- $\alpha_2$ je úhel lomu (angle of refraction),
|
||||
- $v_1$ je rychlost šíření vlnění ve vnějším prostředí,
|
||||
- $v_2$ je rychlost šíření vlnění v prostředí objektu,
|
||||
- $n_1$ je index lomu vnějšího prostředí,
|
||||
- $n_2$ je index lomu prostředí objektu.
|
||||
|
||||

|
||||
|
||||
- **Diffuse lighting**\
|
||||
Když všechno (neabsorbované) světlo opustí objekt ze stejného místa, kam dopadlo.
|
||||
|
||||

|
||||
|
||||
- **Subsurface scattering**\
|
||||
Když neabsorbované světlo opustí objekt z jiného místa, než kam dopadlo.
|
||||
|
||||

|
||||
|
||||
- **Microfacets / mikro-plošky**\
|
||||
Ne všechny objekty jsou ploché. Většina má nerovnosti, které jsou menší než pixel, ale větší než vlnová délka dopadajícího světla, proto je modelujeme nějakou pravděpodobností distribucí (např. Gaussovou).
|
||||
|
||||

|
||||
|
||||
Existuje řada modelů chování microfacet, např. Cook-Torrance, Oren-Nayar, Ashnikmin-Shirley, Normalized Blinn-Phong, atd.
|
||||
|
||||
- **Geometrická atenuace**\
|
||||
Postupná ztráta "intenzity" paprsku v důsledku geometrie objektu.
|
||||
|
||||
- **Shadowing** -- facety zastiňují jiné facety.
|
||||
- **Masking** -- facet nejde vidět, protože ho zastiňuje jiný facet.
|
||||
- **Interreflection** -- světlo se odráží mezi facety, než je odraženo zpátky ke kameře.
|
||||
|
||||
### Fyzikální věličiny radiometrie
|
||||
|
||||
- **Radiant energy / energie záření (Q)**\
|
||||
"Energy per one photon."
|
||||
|
||||
Jednotka: Joule (J)
|
||||
|
||||
- **Radiant flux, radiant power / zářivý tok ($\Phi$)**\
|
||||
"Energy per second." Bezva na popisování síly světel jako jsou žárovky, plošná světla, atd.
|
||||
|
||||
```math
|
||||
\Phi = \frac{\partial Q}{\partial t}
|
||||
```
|
||||
|
||||
Jednotka: Watt (W) = J/s
|
||||
|
||||
- **Irradiance / ozářenost, ozáření (E)**\
|
||||
"Flux through area." Světlo dopadající na jednotku plochy. Kvadraticky se zmenšuje s rostoucí vzdáleností od zdroje. Bezva na popis vzdálených zdrojů jako je slunce.
|
||||
|
||||
```math
|
||||
E = \frac{\partial \Phi}{\partial A}
|
||||
```
|
||||
|
||||
Jednotka: Watt per square meter ($\frac{W}{m^2}$)
|
||||
|
||||
- **Radiosity / radiozita (radiometrická veličina) (J)**\
|
||||
Jako irradiance, ale je to světlo _vycházející_ z jednotky plochy.
|
||||
- **Radiance / zář (L)**\
|
||||
"Flux through a cone of directions from an area." a nebo "Flux through an area from a cone of directions." Nezmenšuje se se zvětšující se vzdáleností od zdroje. Tohle měří senzory.
|
||||
|
||||
```math
|
||||
L = \frac{\partial^2 \Phi}{\partial A_\text{proj} \partial \omega}
|
||||
```
|
||||
|
||||
Jednotka: Watt per square meter per steradian ($\frac{W}{m^2 \cdot sr}$)
|
||||
|
||||
### Bidirectional Reflectance Distribution Function (BRDF)
|
||||
|
||||
Funkce popisující poměr mezi dopajícím a odraženým světlem na povrchu objektu.
|
||||
|
||||
```math
|
||||
f(\vec{l}, \vec{v}) = \frac{\partial L_o(\vec{v})}{\partial E_i(\vec{l})}
|
||||
```
|
||||
|
||||
_Povrch je nasvícen ze směru $\vec{l}$ s ozářením $\partial E(\vec{l})$. $\partial(L_o(\vec{v}))$ je odražená zář ve směru $\vec{v}$._
|
||||
|
||||
Udává pravděpodobnost, že světlo dopadající na povrch ze směru $\vec{l}$ bude odraženo ve směru $\vec{v}$.
|
||||
|
||||
Z pohledu teorie pravděpodobnosti / statistiky to ale není distribuční funkce ale spíš hustota pravděpodobnosti.
|
||||
|
||||
BRDF je řešena pomocí ray tracingu, radiosity, nebo nějakým hybridním řešením.
|
||||
|
||||
## Techniky renderování stínů
|
||||
|
||||
Stíny jsou důležité, jelikož:
|
||||
|
||||
- zvyšují věrohodnost scény,
|
||||
- jsou indikátorem vzdálenosti objektů od sebe -- hloubky scény,
|
||||
- mohou dávat informaci o objektech, které jsou mimo zorné pole kamery nebo ukryté za jinými objekty,
|
||||
- popisují tvar objektu, na který jsou promítány.
|
||||
|
||||
- **Hard shadows / "ostré" stíny**\
|
||||
Rozlišují jen, zda je bod osvětlený nebo ne. Neřeší se, jak moc je osvětlený. Týká se bodových světel.
|
||||
|
||||

|
||||

|
||||
|
||||
- **Soft shadows / "měkké" stíny**\
|
||||
Rozlišují i částečně osvětlené oblasti. Týká se světel, která mají plochu.
|
||||
|
||||

|
||||

|
||||
|
||||
- **Planar shadows**\
|
||||
Vykreslí objekt ještě jednou projektovaný na danou plochu.
|
||||
|
||||
- Použitelné na velké plochy jako je rovná podlaha či stěny.
|
||||
- Blinn (1988)
|
||||
- Jednoduché a rychlé.
|
||||
- Nedá se použít na sebevržené stíny, stíny vržené na jiné objekty, kulaté plochy, atd.
|
||||
|
||||
- **Fake shadows and Projective textures**\
|
||||
Použitelné pro velice málo velmi velkých dopadových objektů.
|
||||
|
||||
1. Vyrenderuj objekt černobíle z pohledu světla a ulož do textury.
|
||||
2. Projektuj tuhle texturu na **každý** objekt, na který má dopadat stín.
|
||||
|
||||
- **Shadow maps**\
|
||||
Renderuje scénu z pohledu světla, ale ukládá si do textury jen hloubku. Při vykreslování scény z pohledu kamery sampleuje texturu a porovnává vzdálenost od světla s hloubkou v textuře. Pokud je větší, je bod ve stínu.
|
||||
|
||||

|
||||
|
||||
**❗ IMPORTANT**\
|
||||
Shadow mapám se důkladně věnuje otázka [Renderování s využitím GPU](../renderovani-s-vyuzitim-gpu/)
|
||||
|
||||
- **Shadow volumes**\
|
||||
Počítá stíny ve 3D. Shadow volume explicitně popisuje objem prostoru ve stínu nějakého polygonu.
|
||||
|
||||
1. Pro každý shadow caster, vyrob shadow volume.
|
||||
2. Pro každý fragment, počítej do kolika objemů paprsek z kamery do fragmentu vstoupí (+1) a z kolika vystoupí (-1). Pokud je výsledek > 0, pak je fragment ve stínu, pokud je 0 tak je osvětlený.
|
||||
|
||||

|
||||
|
||||
Prakticky se používá Stencil Buffer Algorithm, kdy renderujeme pro každý objekt nejprve front faces a pak back faces. Tenhle přístup je problematický, pokud je kamera ve stínu, ale řešitelný pokud obrátíme pořádí objektů -- jdeme od nekonečna ke kameře (Z-fail, Carmack’s reverse).
|
||||
|
||||
- **Soft shadows**\
|
||||
Existuje množství algoritmů. Například shadow mapy s Percentage Closer Filtering (PCF). Jsou ale výpočetně náročnější než hard shadows.
|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[pa010-2021,1]]] Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021)
|
||||
- [[[pa010-2020,2]]] Sochor: PA010 Intermediate Computer Graphics (podzim 2020)
|
||||
- [[[pa213, 3]]] PA213 Advanced Computer Graphics
|
||||
- [[[notes-pa010,4]]] [Moje poznámky z PA010 (podzim 2020)](/fi/pa010/)
|
||||
- [[[manifold-wiki,5]]] [Wikipedia: Topological manifold](https://en.wikipedia.org/wiki/Topological_manifold)
|
||||
- [[[klein-bottle,6]]] [Konrad Polthier: Imaging maths - Inside the Klein bottle ](https://plus.maths.org/content/imaging-maths-inside-klein-bottle)
|
||||
- [[[genus,7]]] [Saul Schleimer: Notes on the complex of curves](https://www.researchgate.net/publication/228393582_Notes_on_the_complex_of_curves)
|
||||
- [[[gpugems,8]]] [GPU Gems: Volume Rendering Techniques](https://developer.nvidia.com/gpugems/gpugems/part-vi-beyond-triangles/chapter-39-volume-rendering-techniques)
|
||||
- [[[marching-cubes,9]]] [Marching cubes: A high resolution 3D surface construction algorithm](https://dl.acm.org/doi/10.1145/37402.37422)
|
||||
- [[[marching-tetrahedra,10]]] [Wikipedia: Marching tetrahedra](https://en.wikipedia.org/wiki/Marching_tetrahedra)
|
||||
- [[[dual-contouring,11]]] [Dual Contouring Tutorial](https://www.boristhebrave.com/2018/04/15/dual-contouring-tutorial/)
|
||||
- [[[delaunay-triangulation,12]]] [Wikipedia: Delaunay triangulation](https://en.wikipedia.org/wiki/Delaunay_triangulation)
|
||||
- [[[pv227-2022, 13]]] [PV227 GPU Rendering (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PV227/)
|
||||
|
||||
## Další zdroje
|
||||
|
||||
- https://pdfs.semanticscholar.org/49a5/5176f4b9c5480621de92551deb2f1566b1c7.pdf
|
||||
- https://redirect.cs.umbc.edu/~olano/class/435-06-8/illum.pdf
|
||||
- https://blogs.nvidia.com/blog/2022/08/04/direct-indirect-lighting/
|
@ -0,0 +1,82 @@
|
||||
---
|
||||
title: "Fyzikální principy ve vývoji her (2024)"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Typy fyzikálních simulací a jejich využití ve hrách (tuhá tělesa, deformovatelná tělesa, částice). Dynamika tuhých těles (síly, tření). Objekty pro detekci kolizí (“colliders”, typy, limity), kolizní vrstvy. Detekce kolizí (diskrétní a spojitá detekce, obvyklé problémy, využití v herních mechanikách).
|
||||
|
||||
_PV255_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
## Fyzikální simulace
|
||||
|
||||
- **Rigid body**\
|
||||
Aproximace reálného fyzikálního tělesa. Předpokládá uniformní hostotu a **neřeší:**
|
||||
|
||||
- deformace objektu,
|
||||
- aerodynamičnost tvaru.
|
||||
|
||||
Nicméně **řeší**:
|
||||
|
||||
- dynamiku (část mechaniky, která se zabývá příčinami pohybu),
|
||||
- kolize,
|
||||
- klouby.
|
||||
|
||||
- **Soft body**\
|
||||
Deformovatelný objekt.
|
||||
- **Fyzikální enginy**
|
||||
- PhysX (Nvidia) -- Unity, Unreal Engine.
|
||||
- Bullet -- Blender, Paradox engine.
|
||||
- Havok
|
||||
- Box2D
|
||||
|
||||
## Objekty pro detekci kolizí
|
||||
|
||||
V principu funguje detekce kolizí tak, že v každém kroku fyzikální simulace: [pa199-2022](#pa199-2022)
|
||||
|
||||
1. dojde ke kontrole, zda se dva objekty dotýkají -- či mají společný průnik,
|
||||
2. pokud ano a kolize jsou pro dané objekty povoleny, dojde k výpočtu kolizních dat (normála, hloubka průniku, atd.),
|
||||
3. ostatní systémy mohou reagovat na kolizi (např. způsobit explozi miny).
|
||||
|
||||
- **Fáze**
|
||||
1. Broad phase -- hledání kandidátů na kolize
|
||||
- Např. pokud se dotýkají AABB nebo jsou objekty v přibližně stejné oblasti.
|
||||
- Využívají se struktury pro vyhledávání jako octree, k-D tree, BSP, atd, které je potřeba aktualizovat každé iteraci fyzikální simulace.
|
||||
2. Narrow phase -- kontrola zda se kandidáti fakt srazili.
|
||||
- **Sweep and prune**\
|
||||
Algoritmus pro broad phase.
|
||||
- **Gilbert-Johnson-Keerthi (GJK)**\
|
||||
Algoritmus pro narrow phase. Rozhoduje zda dva konvexní tvary mají společný průnik.
|
||||
- **Primitivní collidery**\
|
||||
Výpočty s nimi jsou rychlé.
|
||||
|
||||
- krabice (AABB),
|
||||
- koule,
|
||||
- kapsle,
|
||||
- válec.
|
||||
|
||||
**Primitivní collidery v Unity**
|
||||
|
||||

|
||||
|
||||
- **Mesh collider**\
|
||||
Neprimitivní collider objekt. Obvykle konvexní obal nějakého meshe. Vypočetně náročné.
|
||||
- **Compound collider**\
|
||||
Collider složený z vícero primitivních colliderů. Rychlejší než mesh collider. Použitelný i na nekonvexní objekty.
|
||||
- **Quickhull**\
|
||||
Algoritmus pro výpočet konvexního obalu.
|
||||
- **Statické objekty**\
|
||||
Terén, budovy, a podobné nehybné objekty. Nepůsobí na něj fyzikální síly, ale fungují jako collidery. Necollidují však vzájemně. Mívají komplexní tvar.
|
||||
- **Dynamické objekty**\
|
||||
Působí na ně fyzika. Měly by mít jednodušší collidery.
|
||||
- **Discrete collision detection**\
|
||||
Kolize se detekují v každém kroku fyzikální simulace. Výpočetně nenáročné, ale může docházet k "tunelování" objektů skrz jiné objekty.
|
||||
- **Continous collision detection (CCD)**\
|
||||
Kolize se detekují v "průběhu pohybu" objektů -- pomocí supersamplingu, raycastingu, swept spheres, atd. Výpočetně náročné.
|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[pa199-2022,9]]] [Chmelík, Trtík, PA199 Advanced Game Development](https://is.muni.cz/auth/el/fi/podzim2022/PA199/um/)
|
327
src/content/docs/szmgr/VPH02_graficke_a_fyzikalni_principy.md
Normal file
327
src/content/docs/szmgr/VPH02_graficke_a_fyzikalni_principy.md
Normal file
@ -0,0 +1,327 @@
|
||||
---
|
||||
title: "Grafické a fyzikální principy (2023)"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
**⚠️ WARNING**\
|
||||
Tato je stará verze otázky. Nová verze: [Fyzikální principy ve vývoji her](./VPH02_fyzikalni_principy_ve_vyvoji_her.ad).
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Příprava a vývoj scény, grayboxing, zástupné modely (placeholders). Optimalizace výkonu vykreslování (úrovně detailů, odstřelování objektů, MIP mapy). Využití shaderů pro efekty ve hrách. Sledování paprsků, objekty pro detekci kolizí, fyzika hadrové panenky.
|
||||
|
||||
_PA010, PA199, PA213, PV255_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
## Příprava a vývoj scény
|
||||
|
||||
**📌 NOTE**\
|
||||
Poznámky o grayboxingu, iterování, modulárním workflow, atd. jsou z přednášky Lukáše Medka v rámci PV255. [medek](#medek)
|
||||
|
||||
- **Iterace**\
|
||||
Práce v iteracích pomáhá:
|
||||
|
||||
- udržet konzistenci,
|
||||
- mít přehled o objemu práce,
|
||||
- průběžně přídávat obsah a
|
||||
- šetřit čas.
|
||||
|
||||
- **Základní workflow**
|
||||
1. Modelování high-poly a low-poly modelů
|
||||
2. Unwrap
|
||||
3. Tvorba textur a materiálů
|
||||
4. Vypečení map (normály, bump, atd.)
|
||||
5. Aplikace shaderu v engine
|
||||
6. Optimalizace
|
||||
- **Grayboxing**
|
||||
- Rychlý nástřel modelu / scény / prostředí.
|
||||
- Obrovská časová úspora při tvorbě assetů. Místo jejich finální podoby se používají placeholdery (obvykle šedé krabice).
|
||||
- Umožňuje implementovat mechaniky bez nutnosti čekat na assety.
|
||||
- Limituje odpad -- nevyužité assety -- při změnách nebo škrtech.
|
||||
- **Modulární workflow**\
|
||||
Využití malého množství assetů pro vytvoření rozsáhlého prostředí. Nutná promyšlená preprodukce. [modular](#modular)
|
||||
- **Modulární textury**\
|
||||
Textury aplikovatelné na více modelů. Je potřeba na všechna využití myslet při vytváření textury.
|
||||
- **Placeholders**\
|
||||
Zjednodušené / low-poly / koupené / kradené modely nebo šedé / oranžové / libovolné krabice, které jsou v pohodě pro prototyping, ale neměly by být ve finální hře.
|
||||
|
||||
## Optimizalizace výkonu vykreslování
|
||||
|
||||
- **Level-of-detail (LOD) / úrovně detailů**\
|
||||
Čím větší vzdálenost, tím méně detailů. [pv255-2022](#pv255-2022)
|
||||
|
||||
Pro každý model máme hierarchii modelů s různým počtem polygonů. V závislosti na vzdálenosti od pozorovatele vybíráme vhodný LOD.
|
||||
|
||||

|
||||
|
||||
Dají se vytvořit _manuálně_ i _automaticky_ (pomocí algoritmů pro mesh reduction / decimation).
|
||||
|
||||
- **Diskrétní LOD**\
|
||||
Existuje fixní počet variant meshe, mezi kterými se přepíná diskrétně. Nevýhodou je "popping" efekt.
|
||||
- **Continous LOD**\
|
||||
Mezi variantami se nepřepíná "ráz naráz", ale postupně tak, že v jeden moment jsou vykresly dva LODy přes sebe a blendovány pomocí alpha kanálu.
|
||||
- **Geomorphic LOD**\
|
||||
Redukuje popping postupnou "proměnnou" jednoho LODu na druhý odebíráním a přidáváním hran. Generuje approximované mezistavy.
|
||||
|
||||
**Geomorphing by [Sirotk](https://commons.wikimedia.org/w/index.php?curid=24515584)**
|
||||
|
||||

|
||||
|
||||
- **Hierarchical LOD**\
|
||||
Seskupuje objekty ve scéně do hierarchie a zjednodušuje celé skupiny objektů najednou. Vede k lepšímu výkonu.
|
||||
- **Texture filtering**\
|
||||
Popisuje, jakým způsobem se pixely textury (texely) mapují na pixely obrazovky / daného polygonu. [texture-mapping](#texture-mapping)
|
||||
|
||||
Součástí problému je potřeba odhadnout, jak velkou plochu polygon zabere na obrazovce.
|
||||
|
||||
- **Mipmapy**
|
||||
|
||||
> multum in parvo -- mnoho v malém prostoru
|
||||
|
||||
V zásadě LOD na texturách. Z velikosti $\delta$ otexturovaného polygonu je LOD $D = \log_2(\max(\delta, 1))$. Výsledek je získán interpolací mezi LODy $\lfloor D \rfloor$ a $\lceil D \rceil$.
|
||||
|
||||
Mimojiné je to tedy přístup k texture filteringu, kdy aproximujeme velikost polygonu pomocí čtverce daného úrovní mipmapy.
|
||||
|
||||
**Separate color channels of a mipmapped texture by [Phorgan1](https://commons.wikimedia.org/w/index.php?curid=27311755)**
|
||||
|
||||

|
||||
|
||||
**💡 TIP**\
|
||||
Jak je patrné z obrázku výše, chytrým uložením je mipmapovaná textura jen o 33 % větší než původní textura. (Nová má velikost $\frac{4}{3}$ té staré.)
|
||||
|
||||
- **Shaderové / GPU optimalizace**\
|
||||
Existuje řada nástrojů, které umožňují debugovat a optimalizovat GPU:
|
||||
|
||||
- _V Unity:_ Rendering Statistics, Frame Debugger
|
||||
- _nVidia Nsight:_ obecné debuggování GPU
|
||||
- _Intel Graphics Performance Analyzers:_ obecné debuggování GPU
|
||||
- _RenderDoc:_ debuggování OpenGL, DirectX a Vulkan
|
||||
|
||||
- **Object culling / ostřelování objektů**\
|
||||
Nalézání podmnožiny objektů ve scéně, která může být vynechána, aniž by viditelně ovlivnila výsledný obraz. Počítání přesné viditelnosti je příliš náročné, proto se používají aproximace známé jako _potentially visible set_ (PVS). [pa010-2021](#pa010-2021)
|
||||
- **Back-face culling**\
|
||||
Vykreslování pouze předních stran polygonů.
|
||||
- **View frustum culling**\
|
||||
Vykreslování pouze objektů, které jsou v zorném poli kamery.
|
||||
- **Occlusion culling**\
|
||||
Vykreslování pouze objektů, které nejsou zakryty jinými objekty.
|
||||
|
||||

|
||||
|
||||
- **Portal culling**\
|
||||
Užitečné, pokud máme statickou scénu, kde jsou některé části viditelné jen z některých jiných částí (např. místnosti v domě). Část dat potřebných pro odstřel tak může být předpočítána.
|
||||
|
||||

|
||||

|
||||
|
||||
- **Obecné zásady**
|
||||
- Nevykreslovat co není nutné (zahazovat na CPU, využívat předchozí snímky)
|
||||
- LODovat
|
||||
- Batching (Unity) -- shlukovat geometrie a vykreslovat naráz
|
||||
- Instancing -- vykreslovat vícero instancí stejného objektu naráz
|
||||
- Minimalizovat počet materiálů (např. spojováním textur).
|
||||
- Vypéct všechni nedynamické (statická světla, stíny, atd.)
|
||||
|
||||
## Využití shaderů pro efekty ve hrách
|
||||
|
||||
- **Toon / cel shading**\
|
||||
Toon shading používá jen několik ruzných "kroků" intezity barev. Cel shading prý přidává kontury, ale zdá se, že ty termíny jsou spíš synonyma. [pa010-2020](#pa010-2020) [cel](#cel)
|
||||
|
||||
**Cel-shaded Utah Teapot by [NicolasSourd](https://commons.wikimedia.org/w/index.php?curid=1788125)**
|
||||
|
||||

|
||||
|
||||
- **Color grading**\
|
||||
Využívá se look-up table (LUT) pro jednotnou barevnou korekci. [zeleny](#zeleny) [color-grading](#color-grading)
|
||||
- **Marschner Hair**\
|
||||
Shader, co používá Pixar pro vlasy a chlupy postavený na výzkumu Steva Marschnera. Má tři složky: odraz \(R), průchod skrz (TT), vnitřní odraz (TRT). [zeleny](#zeleny) [hair](#hair)
|
||||
- **Hloubka obrazu / depth of field**\
|
||||
Fyzikálně korektní bokeh. Simuluje fotoaparát včetně clony (F-stop), velikosti snímače (full-frame, APS-C, atd.), ohniskové vzdálenosti, počtu lamel, atd. [zeleny](#zeleny)
|
||||
|
||||

|
||||
|
||||
**💡 TIP**\
|
||||
Circle of Confusion (CoC) je kruh způsobený imperfektním zaostřením. Měřením CoC foťáky určují depth of field. [coc](#coc)
|
||||
|
||||
## Ray tracing / sledování paprsků
|
||||
|
||||
Ray tracing jsou techniky, které trasují paprsky světla napříč scénou.
|
||||
|
||||
- Jsou pomalejší než empirické modely jako Blinn-Phong,
|
||||
- Jsou limitované na jeden úhel pohledu (pomineme-li hacky).
|
||||
- Ray tracing zvládá odrazy, refrakci a další chování světla věrohodněji.
|
||||
|
||||
**The first bounce of the ray-tracing algorithm schematic by [Henrik](https://commons.wikimedia.org/w/index.php?curid=3869326)**
|
||||
|
||||

|
||||
|
||||
- **Path tracing**\
|
||||
Monte Carlo technika, kdy pro každý pixel je do scény vysláno množství paprsků. Když paprsek narazí na objekt, je buď absorbován, odražen nebo zlomen -- což je zvoleno náhodně.
|
||||
|
||||
Rozdíl oproti klasickému ray tracingu je právě v oné náhodnosti. Klasický ray tracing počítá _všechny_ odražené i zlomené paprsky, které trasuje ke každému ze světelných zdrojů. Path tracing poskytuje "jen" statistický vzorek z nich.
|
||||
|
||||
- **Využití**
|
||||
- Animované filmy
|
||||
- Vizuální efekty
|
||||
- Architektonické vizualizace
|
||||
- Hry
|
||||
- **Spatial data structure**\
|
||||
Datové struktury popisujicí objekty v prostoru. Volba vhodné struktury je klíčová pro efektivitu ray tracingu, ale je fajn i pro všední průchod scénou. [bvh-rt](#bvh-rt)
|
||||
|
||||

|
||||
|
||||
- **Bounding volume hierarchy (BVH)**\
|
||||
Hierarchická reprezentace scény, díky které průchod scénou zredukován z $\mathcal{O}(n)$ na $\mathcal{O}(\log n)$ ($n$ je počet objektů ve scéně). Dá se stavět top-down nebo bottom-up. [bvh-rt](#bvh-rt)
|
||||
|
||||
Chceme od ní dvě věci:
|
||||
|
||||
1. Rychlý průchod a dotazování na průnik mezi objemy.
|
||||
2. Rychlou kostrukci a aktualizace.
|
||||
|
||||
- **Surface Area Heuristic (SAH)**\
|
||||
Metrika udávající cenu průchodu BVH. Používá se v řadě různých BVH algoritmů a jejich evaluaci.
|
||||
|
||||
Mějme následující scénu:
|
||||
|
||||

|
||||
|
||||
Pravděpodobnost, že paprsek trefí $L$ je $\color{red} p_L = \frac{SA(L)}{SA(N)}$. Analogicky $\color{green} p_R = \frac{SA(R)}{SA(N)}$.
|
||||
|
||||
Cena průchodu uzlem BVH je pak:
|
||||
|
||||
```math
|
||||
C(N) =
|
||||
\begin{cases}
|
||||
c_T + \textcolor{red}{p_L \cdot C(L)} + \textcolor{green}{p_R \cdot C(R)} & \text{ pro vnitřní uzel} \\
|
||||
c_I \cdot t_N & \text{ pro list}
|
||||
\end{cases}
|
||||
```
|
||||
|
||||
kde:
|
||||
|
||||
- $c_T$ je cena průchodu vnitřním uzlem,
|
||||
- $c_I$ je cena kontroly průniku,
|
||||
- $t_N$ je počet trojúhelníků v listu,
|
||||
|
||||
Celková cena BVH je pak:
|
||||
|
||||
```math
|
||||
C(T) = \frac{1}{SA(T)} \cdot \left\lbrack c_T \textcolor{darkred}{\sum_{N \in \text{inner nodes} SA(N)}} + c_I \textcolor{blue}{\sum_{N \in \text{leaves}} SA(N) \cdot t_N} \right\rbrack
|
||||
```
|
||||
|
||||
Modrý výraz je konstantní, tmavě červený se snažíme minimalizovat volbou BVH algoritmu.
|
||||
|
||||
- **Agglomerative Clustering**\
|
||||
Bottom-up metoda, kdy se jednotlivé trojúhelníky postupně shlukují do clusterů. Strom trvá déle postavit, ale je efektivnější ho procházet.
|
||||
- **Morton Codes**\
|
||||
Pro efektivní hledání nejbližších bodů se využívá křivek vyplňujících prostor. Jednou takovou je Mortonova Z-křivka.
|
||||
|
||||
**Four iterations of the Z-order curve by [David Eppstein](https://commons.wikimedia.org/w/index.php?curid=3879675)**
|
||||
|
||||

|
||||
|
||||
## Fyzikální simulace
|
||||
|
||||
**❗ IMPORTANT**\
|
||||
Renderování založenému na fyzikálních principech se věnuje část otázky [Pokročilá počítačová grafika](../pokrocila-pocitacova-grafika/).
|
||||
|
||||
- **Rigid body**\
|
||||
Aproximace reálného fyzikálního tělesa. Předpokládá uniformní hostotu a **neřeší:**
|
||||
|
||||
- deformace objektu,
|
||||
- aerodynamičnost tvaru.
|
||||
|
||||
Nicméně **řeší**:
|
||||
|
||||
- dynamiku (část mechaniky, která se zabývá příčinami pohybu),
|
||||
- kolize,
|
||||
- klouby.
|
||||
|
||||
- **Soft body**\
|
||||
Deformovatelný objekt.
|
||||
- **Fyzikální enginy**
|
||||
- PhysX (Nvidia) -- Unity, Unreal Engine.
|
||||
- Bullet -- Blender, Paradox engine.
|
||||
- Havok
|
||||
- Box2D
|
||||
|
||||
## Objekty pro detekci kolizí
|
||||
|
||||
V principu funguje detekce kolizí tak, že v každém kroku fyzikální simulace: [pa199-2022](#pa199-2022)
|
||||
|
||||
1. dojde ke kontrole, zda se dva objekty dotýkají -- či mají společný průnik,
|
||||
2. pokud ano a kolize jsou pro dané objekty povoleny, dojde k výpočtu kolizních dat (normála, hloubka průniku, atd.),
|
||||
3. ostatní systémy mohou reagovat na kolizi (např. způsobit explozi miny).
|
||||
|
||||
- **Fáze**
|
||||
1. Broad phase -- hledání kandidátů na kolize
|
||||
- Např. pokud se dotýkají AABB nebo jsou objekty v přibližně stejné oblasti.
|
||||
- Využívají se struktury pro vyhledávání jako octree, k-D tree, BSP, atd, které je potřeba aktualizovat každé iteraci fyzikální simulace.
|
||||
2. Narrow phase -- kontrola zda se kandidáti fakt srazili.
|
||||
- **Sweep and prune**\
|
||||
Algoritmus pro broad phase.
|
||||
- **Gilbert-Johnson-Keerthi (GJK)**\
|
||||
Algoritmus pro narrow phase. Rozhoduje zda dva konvexní tvary mají společný průnik.
|
||||
- **Primitivní collidery**\
|
||||
Výpočty s nimi jsou rychlé.
|
||||
|
||||
- krabice (AABB),
|
||||
- koule,
|
||||
- kapsle,
|
||||
- válec.
|
||||
|
||||
**Primitivní collidery v Unity**
|
||||
|
||||

|
||||
|
||||
- **Mesh collider**\
|
||||
Neprimitivní collider objekt. Obvykle konvexní obal nějakého meshe. Vypočetně náročné.
|
||||
- **Compound collider**\
|
||||
Collider složený z vícero primitivních colliderů. Rychlejší než mesh collider. Použitelný i na nekonvexní objekty.
|
||||
- **Quickhull**\
|
||||
Algoritmus pro výpočet konvexního obalu.
|
||||
- **Statické objekty**\
|
||||
Terén, budovy, a podobné nehybné objekty. Nepůsobí na něj fyzikální síly, ale fungují jako collidery. Necollidují však vzájemně. Mívají komplexní tvar.
|
||||
- **Dynamické objekty**\
|
||||
Působí na ně fyzika. Měly by mít jednodušší collidery.
|
||||
- **Discrete collision detection**\
|
||||
Kolize se detekují v každém kroku fyzikální simulace. Výpočetně nenáročné, ale může docházet k "tunelování" objektů skrz jiné objekty.
|
||||
- **Continous collision detection (CCD)**\
|
||||
Kolize se detekují v "průběhu pohybu" objektů -- pomocí supersamplingu, raycastingu, swept spheres, atd. Výpočetně náročné.
|
||||
|
||||
## Fyzika hadrové panenky
|
||||
|
||||
Specifický pohyb postav bezvědomí. Kombinuje animace a fyziku. Je založená na:
|
||||
|
||||
- skeletal systém (rig) -- kostra postavy,
|
||||
- joint restriction -- kloubech,
|
||||
- rozdělení postavy na skupiny rigid bodies,
|
||||
- springs and dampers -- pružiny a tlumiče.
|
||||
|
||||
**The first "ragdoll falling downstairs" (1997) [ragdolls](#ragdolls)**
|
||||
|
||||

|
||||
|
||||
- **Featherstone’s algorithm**\
|
||||
Algoritmus pro výpočet dynamiky stromovité struktury propojených článků.
|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[medek,1]]]: [Lukáš Medek (CBE), Základní postupy při tvorbě assetů a herního vizuálu](++http://decibel.fi.muni.cz/pv255/2018/slides/PV255_-_06_-_Zakladni_postupy_pri_tvorbe_assetu_a_herniho_vizualu.pdf++)
|
||||
- [[[modular,2]]]: http://wiki.polycount.com/wiki/Modular_environments
|
||||
- [[[pa010-2020,3]]] Sochor: PA010 Intermediate Computer Graphics (podzim 2020)
|
||||
- [[[cel,4]]] https://en.wikipedia.org/wiki/Cel_shading
|
||||
- [[[zeleny,5]]] [Jan Zelený, Grafické efekty](++http://decibel.fi.muni.cz/pv255/2018/slides/PV255_-_09_-_Graficke_efekty.pdf++)
|
||||
- [[[hair,6]]] https://www.fxguide.com/fxfeatured/pixars-renderman-marschner-hair/
|
||||
- [[[color-grading,7]]] [Using Look-up Tables for Color Grading](https://docs.unrealengine.com/5.2/en-US/using-look-up-tables-for-color-grading-in-unreal-engine/)
|
||||
- [[[coc,8]]] https://en.wikipedia.org/wiki/Circle_of_confusion
|
||||
- [[[pa199-2022,9]]] [Chmelík, Trtík, PA199 Advanced Game Development](https://is.muni.cz/auth/el/fi/podzim2022/PA199/um/)
|
||||
- [[[quickhull,10]]] [Barber, Dopkin, Huhdanpaa: The Quickhull Algorithm for Convex Hulls](https://dl.acm.org/doi/pdf/10.1145/235815.235821)
|
||||
- [[[ragdolls,11]]] http://www.animats.com/
|
||||
- [[[bvh-rt,12]]] [Bittner: Bounding Volume Hierarchies for Ray Tracing](https://is.muni.cz/auth/el/fi/jaro2022/PA213/um/slides/BoundingVolumeHierarchiesforRayTracing.pdf)
|
||||
- [[[path-tracing,13]]] [Path Tracing vs. Ray Tracing, Explained](https://www.techspot.com/article/2485-path-tracing-vs-ray-tracing/)
|
||||
- [[[bvh,14]]] [Pharr, Jakob, Humphreys; Physically Based Rendering: From Theory To Implementation; Chapter 4: Bounding Volume Hierarchies](https://www.pbr-book.org/3ed-2018/Primitives_and_Intersection_Acceleration/Bounding_Volume_Hierarchies)
|
||||
- [[[pv255-2022,15]]] [Chmelík, PV255 Game Development I](https://is.muni.cz/auth/el/fi/podzim2022/PV255/um/)
|
||||
- [[[pa010-2021,16]]] [Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021)](https://is.muni.cz/auth/el/fi/podzim2021/PA010/um/)
|
||||
- [[[texture-mapping, 17]]] [Wikipedia: Texture mapping](https://en.wikipedia.org/wiki/Texture_mapping)
|
336
src/content/docs/szmgr/VPH03_herni_design_i.md
Normal file
336
src/content/docs/szmgr/VPH03_herni_design_i.md
Normal file
@ -0,0 +1,336 @@
|
||||
---
|
||||
title: "Herní design I"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
====
|
||||
Hra, videohra, desková hra, digitální hra, počítačová hra, hračka, hádanka, puzzle, divadelní hra. Typologie typů hráče, cílová skupina. Herní zážitek, herní smyčka, herní dynamika, herní mechanika. Herní zaháčkování (hook), herní kotva (anchor). Proces prototypování her, ověřování herního designu. Činnosti herní/ho designérky/a (kreativní, abstraktní, analytické, systematické, komunikační).
|
||||
|
||||
_PA215, PA216_
|
||||
|
||||
> Game design is an idea. An idea is worthless. An idea is not playable.[pa215-2022](#pa215-2022) [pa215-2019](#pa215-2019)
|
||||
>
|
||||
> — ZZ
|
||||
|
||||
> Game design is like a recipe...
|
||||
>
|
||||
> It looks fine, but you can’t eat it...
|
||||
>
|
||||
> Well it can be eaten, but it doesn’t fill you up.
|
||||
>
|
||||
> — Taky ZZ
|
||||
|
||||
== Hra
|
||||
|
||||
> Hra... je zbytečný termín.
|
||||
>
|
||||
> — Určitě ne ŽŽ
|
||||
|
||||
Definice hry je stále aktivní proces, ale zjednodušeně je to něco, co se dá _hrát_.
|
||||
|
||||
> A game is a problem-solving activity, approached with a playful attitude.
|
||||
>
|
||||
> — Jesse Schell
|
||||
|
||||
> A game is a **system** in which **players** engage in an **artificial conflict** defined by **rules**, that results in a **quantifiable outcome**.
|
||||
>
|
||||
> — Salen & Zimmerman
|
||||
|
||||
> Every game is a mental model, a simple mental model of reality, that is easily stored, considered, and manipulated.
|
||||
>
|
||||
> — ZZ? Asi.
|
||||
|
||||
**Vlastnosti her [schell](#schell)**
|
||||
|
||||
1. Games are **entered willfully**.
|
||||
2. Games have **goals**.
|
||||
3. Games have **conflict**.
|
||||
4. Games have **rules**.
|
||||
5. Games **can be won and lost**.
|
||||
6. Games are **interactive**.
|
||||
7. Games have **challenge**.
|
||||
8. Games **can create their own internal value**.
|
||||
9. Games **engage players**.
|
||||
10. Games are **closed, formal systems**.
|
||||
|
||||
Hry se dají (poměrně hnidopišsky a rozhodně ne jednoznačně) rozdělit na:
|
||||
|
||||
- **Hra**\
|
||||
Něco, co se dá hrát.
|
||||
- **Hračka**\
|
||||
Předmět, který slouží ke hraní.
|
||||
- **Videohra**\
|
||||
Něco, co se dá hrát na obrazovce.
|
||||
- **Desková hra**\
|
||||
Typ stolní hry (hra která se hraje na stole) která se hraje na herním plánu (šachy, dáma, člověče nezlob se).
|
||||
Další typy stolních her jsou karetní hry, hry s kostkami, hry s tužkou a papírem...
|
||||
Moderní hry jsou často kombinací více typů stolních her.
|
||||
- **Digitální hra**\
|
||||
Něco, co se dá hrát na obrazovce a řídí ji nějaký program.
|
||||
- **Počítačová hra (PC game)**\
|
||||
Digitální videohra určená pro osobní počítač (PC).
|
||||
- **Konzolová hra (console game)**\
|
||||
Digitální videohra určená pro herní konzoli (PlayStation, Xbox, Nintendo Switch, ...).
|
||||
|
||||
Useless fun fact: _Xbox_ je zkratka pro _DirectX Box_. DirectX zastřešuje několik API jako je _Direct3D_, _DirectPlay_, _DirectSound_, _DirectInput_ atd.
|
||||
|
||||
Takže _Xbox X_ je vlastně _DirectX Box X_. Microsoft fakt neumí pojmenovávat věci.
|
||||
|
||||
- **Hádanka**\
|
||||
Hádanka je drobný slovesný projev v podobě hříčky, která v náznaku předkládá určitý problém, k jehož řešení lze dospět důvtipem nebo logickou úvahou [hadanka](#hadanka).
|
||||
- **Puzzle**\
|
||||
V češtině se slovo _puzzle_ používá pro označení skládaček, ale v herním průmyslu se pod tímto slovem rozumí hlavolam - problém, který musí hráč vyřešit.
|
||||
- **Divadelní hra**\
|
||||
Stejně jako hra se odehrává ve fiktivním světě, obsahuje konflikt a cíl. Většinou ale nemá interaktivní prvky.
|
||||
|
||||
== Typy hráčů
|
||||
|
||||
Lidi jsou různí a různí lidi hrají různé hry různě.
|
||||
|
||||
**Bartleho taxonomie**
|
||||
|
||||
- **Socializer**\
|
||||
Interaguje s ostatními hráči. Je pyšný na to, že se s ostatními hráči přátelí, že má kontakty a vliv.
|
||||
|
||||
What happened? I missed it, I was talking.
|
||||
|
||||
- **Killer**\
|
||||
Působí na ostatní hráče. Záleží mu na jeho skillech a reputaci.
|
||||
|
||||
Die!
|
||||
|
||||
- **Achiever**\
|
||||
Snaží se dosáhnout cílů ve světě. Záleží mu na jeho postavení v rámci herní hierarchie a na tom, jak rychle se tam dostal.
|
||||
|
||||
Only 4211 points to go!
|
||||
|
||||
- **Explorer**\
|
||||
Snaží se objevovat a poznávat svět. Je hrdý na hloubku svých znalostí o světě.
|
||||
|
||||
> I haven’t tried that one, what’s it do?
|
||||
|
||||
**Bartle’s Taxonomy of Players [pa215-2022](#pa215-2022)**
|
||||
|
||||

|
||||
|
||||
=== Cílová skupina
|
||||
Neexistuje hra, která by se líbila všem. Cílová skupina je skupina lidí, které se snažíme oslovit. Může být definována věkem, zájmy, zkušenostmi, atp.
|
||||
|
||||
== Komponenty hry
|
||||
|
||||
Na hru se dá dívat z mnoha různých perspektiv: [pa215-2019](#pa215-2019)
|
||||
|
||||
| Component |
|
||||
| --------------------------- | ------------------- | --------------------- |
|
||||
| Type | Example | Experience |
|
||||
| Outer layer / aesthetic | Fear | Loops |
|
||||
| Gameplay / motivation / ... | Opening doors | Dynamics / strategies |
|
||||
| Gameplay depth | Hiding in the light | Actions |
|
||||
| Game mechanics | Lantern / light | Goals |
|
||||
| Motivation | To survive | Elements |
|
||||
| Components / aesthetic | Castle | System(s) |
|
||||
|
||||
=== Herní zážitek (Experience)
|
||||
|
||||
Games are only means for a greater goal - creating experience.
|
||||
|
||||
Games are not experiences, they are artifacts people play with while / to create experience.
|
||||
|
||||
Hry dovedou navodit řadu různých herních zážitků, které můžeme různými způsoby kategorizovat.
|
||||
|
||||
**❗ IMPORTANT**\
|
||||
Herní zážitky souvisí s pojmem obtížnost, kterému se věnuje část otázky [Herní design II](../herni-design-ii/).
|
||||
|
||||
==== LeBlanc’s Eight Kinds of Fun
|
||||
|
||||
**💡 TIP**\
|
||||
Taky označované jako _Taxonomy of Game Pleasures_ a _herní "pošušňáníčka"_. [pa215-2019](#pa215-2019)
|
||||
|
||||
Game designer Marc LeBlanc rozdělil herní zážitky do osmi kategorií: [leblanc](#leblanc)[mda](#mda)
|
||||
|
||||
- **Sensation**\
|
||||
Game as sense-pleasure: beautiful visuals, good audio, tactile pleasure.
|
||||
- **Fantasy**\
|
||||
Game as make-believe: sense of place, immersion, suspension of disbelief.
|
||||
- **Narrative**\
|
||||
Game as unfolding story: sense of drama, rising tension.
|
||||
- **Challenge**\
|
||||
Game as obstacle course: compelling struggle.
|
||||
- **Fellowship**\
|
||||
Game as social framework: shared intense experience, community.
|
||||
- **Discovery**\
|
||||
Game as uncharted territory: exploration, revealing the hidden, variety.
|
||||
- **Expression**\
|
||||
Game as soap box: customization, self-representation.
|
||||
- **Submission / masochism**\
|
||||
Game as mindless pastime: submission to game structures, mutual agreement to "play".
|
||||
|
||||
=== Herní smyčky (Loops)
|
||||
_Herní smyčka_ je opakovatelná posloupnost akcí / částí gameplaye. Většina velkých her má víc než jednu smyčku různých žánrů, které jsou vágně (a nebo vůbec) propojené.
|
||||
|
||||
=== Herní dynamika (Dynamics)
|
||||
Strategie, způsoby hraní. Chování hráče, které se noří z toho, jak používá mechaniky.
|
||||
|
||||
=== Element / Ludeme
|
||||
Základní jednotka hry. Třeba L-pohyb koně v šachu.
|
||||
|
||||
=== Herní mechaniky
|
||||
Podobně jako termín _hra_, ani _herní mechanika_ nemá jednoznačnou definici.
|
||||
|
||||
- Základní herní elementy, se kterými hráč interaguje úmyslně.
|
||||
- Pravidla, která řídí, co za akce hráč může dělat, a jak hra na jeho akce reaguje.
|
||||
|
||||
=== Game goals
|
||||
|
||||
- _Konkrétní_: Hráč musí pochopit a být schopný jasně vysvětlit, co jsou zač a jak jich chce dosáhnout.
|
||||
- _Dosažitelné_: Hráč musí mít pocit, že je schopný cíl dosáhnout.
|
||||
- _Naplňující_: Hráč musí mít pocit, že cíl má smysl, a to ještě předtím, než ho dosáhne, aby měl motivaci.
|
||||
|
||||
== Game Design Anchor and Hook
|
||||
|
||||
=== Herní zaháčkování (Hook)
|
||||
Něco nové, co hru odlišuje od ostatních her. Taky lze nazvat unique selling point.
|
||||
|
||||
=== Herní kotva (Anchor)
|
||||
Něco známeho, povědomého pro hráče.
|
||||
|
||||
== Prototypování her
|
||||
Designér iterativně vytváří hrubé verze hry, které testuje a upravuje. Prototyp je osekaná verze hry, která obsahuje mechaniky, ale ne nutně grafiku. Prototyp lze využít k ověření herního designu - je hra zábavná?
|
||||
|
||||
**❗ IMPORTANT**\
|
||||
Testováním se více zabývá otázka [Herní design II](../herni-design-ii/).
|
||||
|
||||
== Game Designer
|
||||
|
||||
> Artist = inner calling = intimate.
|
||||
>
|
||||
> To create a game is not intimate.
|
||||
>
|
||||
> In a small team it is possible.
|
||||
>
|
||||
> Team = too many voices.
|
||||
>
|
||||
> Team = work together.
|
||||
>
|
||||
> — ZZho slidy z Herního inkubátoru
|
||||
|
||||
- **Cíl**
|
||||
- ~~Cílem game designera je vytvořit hru.~~
|
||||
- ~~Cílem game designera je vytvořit nějaký zážitek.~~
|
||||
- Cílem game designera je vytvořit artefakt (hru), která vytváří nějaký zážitek.
|
||||
- Game designer není zodpovědný za celou hru. Je jen jednou z mnoha rolí, které se na tvorbě hry podílejí. [badges](#badges)
|
||||
- **Role**
|
||||
- Analyzuje hru jako systém objektů, relací, příčin a následků.
|
||||
- Designuje změny, modeluje následky, rozhoduje, posuzuje produkční rizika.
|
||||
- Komunikuje. Hájí hru před ne-designery.
|
||||
|
||||
=== Kreativní činnost
|
||||
|
||||
Nejlepším nástrojem game designera je tužka a papír. Papírový prototyp je pro začátek dost.
|
||||
|
||||
Kromě nich ale existuje:
|
||||
|
||||
- [Twine](https://twinery.org/),
|
||||
- [Bitsy](http://www.bitsy.org/#0,0),
|
||||
- [Flickgame](https://www.flickgame.org/).
|
||||
|
||||
=== Abstraktní činnost
|
||||
|
||||
Game designer produkuje taky hromady abstraktních teorií o herním designu.
|
||||
|
||||
> Design theory is like coffee.
|
||||
>
|
||||
> - You can get it on **every corner**.
|
||||
> - It’s expensive whether it’s **high or low quality**.
|
||||
> - It’s a **fuel for magic**.
|
||||
> - **Without doing something with it it’s useless**.
|
||||
|
||||
> — Ano, stále ZZ
|
||||
|
||||
=== Analytická činnost
|
||||
|
||||
...je tak trochu psychoanalýza.
|
||||
|
||||
> By deep listening to your own self, that is, **observing**, **evaluating**, and **describing** your own experiences, **you can make rapid, decisive judgements** about what is and is not working in your game, **and why** it is or is not working.
|
||||
>
|
||||
> — Jesse Schell
|
||||
|
||||
Ale bacha na mylné závěry. Game designeři mají často zvláštní chutě.
|
||||
|
||||
=== Systematická činnost -- game balancing
|
||||
|
||||
Při balancování hry designer úmyslně ničí svoji hru, aby odhalil její hranice. [pa215-2022](#pa215-2022)
|
||||
|
||||
**Doporučení**
|
||||
|
||||
- Změň jen **jednu věc**. Neměň víc věcí najednou.
|
||||
- Dělej **velké** změny parametrů (MinMaxuj).
|
||||
- **Zapisuj** si co děláš, protože pamatovat si to fakt nebudeš.
|
||||
- Chápej **numerické / elementální atributy** svojí hry.
|
||||
|
||||
=== Komunikační činnost
|
||||
Zjednodušit a předat informace o tom co fungeje a co ne ostatním. Musí umět obhájit své návrhy.
|
||||
|
||||
== The Core Game Ontology
|
||||
|
||||
**📌 NOTE**\
|
||||
Ontologie -- disciplína zabývající se bytím a základními pojmy jako je realita, existence, atp.
|
||||
|
||||
Lehký slovník pro popis her. [cgo](#cgo) Hodí se při komunikaci s klienty, nevyvojáři a nehráči. [pa216-2020](#pa216-2020)
|
||||
|
||||
**The Core Game Ontology [cgo](#cgo)**
|
||||
|
||||

|
||||
|
||||
- **Visuals**\
|
||||
Any visual output of the game, which range from photorealistic, to caricaturize, to abstract visuals.
|
||||
- **Audio**\
|
||||
Includes background music such as a fully orchestrated soundtrack, sound effects, rewarding sounds and voice-acted dialogue.
|
||||
- **Narrative**\
|
||||
Contains the interactive story of a game which makes up the game’s plot.
|
||||
- **Game Design**\
|
||||
Contains all the game’s mechanics that define the game’s rules, which provide the structures and frames for play (for example winning and losing conditions) and actions available to the player.
|
||||
- **Level Design**\
|
||||
Includes the architecture of the spatial navigation of levels which determine how the player agent can progress from one point in the game to another.
|
||||
- **Gameplay**\
|
||||
Consists of the players strategies whilst playing a game.
|
||||
|
||||
== Žánry
|
||||
|
||||
Herní žánry jsou jednoduchou, byť ne zcela přesnou, klasifikací her podle jejich herních mechanik a herních smyček. [genre](#genre) Hrá může zapadat do jednoho nebo více žánrů. Jsou jimi například:
|
||||
|
||||
- **Platformer**\
|
||||
Hra, ve které se hráč pohybuje po platformách a překonává překážky.
|
||||
- **Role-playing game (RPG)**\
|
||||
Hra, ve které hráč hraje za postavu, kterou je pro něj předpřipravena nebo si ji sám vytvořil, a která se vyvíjí a získává nové schopnosti.
|
||||
- **Rhythm game**\
|
||||
Hra, ve které hráč musí reagovat na hudbu.
|
||||
- **Puzzle game**\
|
||||
Hra, ve které hráč řeší hlavolamy.
|
||||
- **Simulation game**\
|
||||
Napodobenina nějakého systému z reálného světa.
|
||||
- **Strategy game**\
|
||||
Hráč se dostává do role vojevůdce a musí se rozhodovat, které jednotky poslat do boje.
|
||||
- **Adventure game**\
|
||||
Příběh je to hlavní. Často kombinuje prvky RPG a puzzle her.
|
||||
- **First-person shooter (FPS)**\
|
||||
Hra, ve které hráč vidí svět očima postavy, kterou hraje, a střílí (převážně) své nepřátele.
|
||||
- **Rogue-like**\
|
||||
Hra, ve které hráč prochází náhodně generovanými úrovněmi a snaží se přežít co nejdéle. Po smrti začíná znovu.
|
||||
|
||||
== Zdroje
|
||||
|
||||
- [[[pa215-2022,1]]] https://is.muni.cz/auth/el/fi/podzim2022/PA215/index.qwarp
|
||||
- [[[pa215-2019,2]]] https://is.muni.cz/auth/el/fi/podzim2019/PA215/um/
|
||||
- [[[schell,3]]] Jesse Schell, _The Art of Game Design: A Book of Lenses_
|
||||
- [[[hadanka,4]]] https://cs.wikipedia.org/wiki/H%C3%A1danka
|
||||
- [[[leblanc,5]]] http://algorithmancy.8kindsoffun.com/
|
||||
- [[[mda,6]]] https://users.cs.northwestern.edu/~hunicke/pubs/MDA.pdf
|
||||
- [[[badges,7]]] https://kumu.io/gamebadges/gamebadges
|
||||
- [[[cgo,8]]] https://autosemanticgame.institutedigitalgames.com/ontologies/core-game-ontology/
|
||||
- [[[pa216-2020,9]]] https://is.muni.cz/auth/el/fi/jaro2020/PA216/index.qwarp
|
||||
- [[[genre,10]]] https://en.wikipedia.org/wiki/Video_game_genre
|
||||
|
||||
== Další zdroje
|
||||
|
||||
- [Greg Costikyan: I Have No Words & I Must Design: Toward a Critical Vocabulary for Game](http://www.costik.com/nowords2002.pdf)
|
320
src/content/docs/szmgr/VPH04_herni_design_ii.md
Normal file
320
src/content/docs/szmgr/VPH04_herni_design_ii.md
Normal file
@ -0,0 +1,320 @@
|
||||
---
|
||||
title: "Herní design II"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Jednotka herního designu, návrh designu hry, designový dokument hry. Teoretické koncepty herní analýzy - magický kruh (Huizinga), kybertext (Aarseth), plynutí (flow; Csikszentmihalyi). Symetrické a nesymetrické (kompetitivní) hry, dominantní strategie. Narativ, vyprávění, příběh, hraní (gameplay). Tutoriál (návod/naučení), onboarding (organické/neinvazivní naučení hry), foreshadowing (před-naznačování). Testování herního zážitku (cílové skupiny (focus), obecné testování hry (play)).
|
||||
|
||||
_PA215, PA216_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
## Návrh hry
|
||||
|
||||
- **Jednotka herního designu**
|
||||
|
||||
Jednotkou herního designu se rozumí dokument, který popisuje část hry (textový popis, obrázky) z pohledu designera, artisty, programátora...
|
||||
|
||||
- **Návrh designu hry**
|
||||
- **Designový dokument**
|
||||
|
||||
Obsahuje základní informace o hře v čitelné formě pro negamedesignery (třeba pro CEO). Měl by obsahovat:
|
||||
|
||||
- target audience, žánr, target platform, pro kolik bude hráčů...
|
||||
- high concept statement - krátký popis hry
|
||||
** What does the player do?
|
||||
** Why do they do it?
|
||||
** Where do they do it?
|
||||
** What are the constraints on the player?
|
||||
** What sort of emotion is this game trying to evoke in the player?
|
||||
** How is this game unique? What differentiates it from other games?
|
||||
- feature set
|
||||
- competition - podobné hry
|
||||
- inovation - co hra přináší nového (art, design, technologie, ...)
|
||||
- scope management - omezení rozsahu hry tak aby se zvládla vyrobit
|
||||
\*\* must have, should have, could have, won’t have
|
||||
|
||||
## Teoretické koncepty herní analýzy
|
||||
|
||||
### Magický kruh Johana Huizingy
|
||||
|
||||
> In a very basic sense, the magic circle of a game is where the game takes place. To play a game means entering into a magic circle, or perhaps creating one as a game begins.
|
||||
>
|
||||
> — Salen & Zimmerman
|
||||
|
||||
Magický kruh je "prostor", ve kterém neplatí obyčejná pravidla reality a místo toho platí sada pravidel "herního světa". Ač magický kruh funguje na jednu stranu jako štít před realitou, je vlastně poměrně průchozí a nechává vnější realitu prosakovat do té herní. [magic-circle-wiki](#magic-circle-wiki) [rules-of-play](#rules-of-play)
|
||||
|
||||
Byť ten termín zmínil jako první Huizinga, zadefinovali a zpopularizovali ho až Salen a Zimmerman. [zimmerman-essay](#zimmerman-essay)
|
||||
|
||||
### Kybertext
|
||||
|
||||
Kybertext byl popsán Espenem Aarsethem v jeho knize _Cybertext: Perspectives on Ergodic Literature_ (1997). Ergodická literatura je taková, která vyžaduje od čtenáře aktivní účast, aby mohl text vůbec přečíst. Kybertext je podkategorie ergodické literatury, kde čtenář musí dělat rozhodnutí, která ovlivňují, jak se text vyvíjí [ergodic-literature-wiki](#ergodic-literature-wiki).
|
||||
|
||||
In ergodic literature, nontrivial effort is required to allow the reader to traverse the text. If ergodic literature is to make sense as a concept, there must also be nonergodic literature, where the effort to traverse the text is trivial, with no extranoematic responsibilities placed on the reader except (for example) eye movement and the periodic or arbitrary turning of pages.
|
||||
|
||||
### Obtížnost hry a Flow
|
||||
|
||||
Hry můžou mít různou obtížnost. Ta se dá mnohdy explicitně nastavit v menu, nebo může být adaptivní a přizpůsobovat se okolnostem (zkušenosti hráče, počet spoluhráčů, atd.). Další možností je mít několik stupňů obtížnosti zároveň vedle sebe (projití příběhu vs. získání všech achievementů).
|
||||
|
||||
> Starting the game at a higher than normal difficulty introduces the concept of **Darwinian Difficulty**, which can be summarized by the motto **adapt or die**.
|
||||
>
|
||||
> — Josh Bycer
|
||||
|
||||
- **Absolutní obtížnost ($\text{AD}$)**\
|
||||
To, co jsme nadesignovali.
|
||||
- **Vnímaná (perceived) obtížnost ($\text{PD}$)**\
|
||||
To, jak obtížná hra přijde hráči.
|
||||
|
||||
```math
|
||||
\text{PD} = \text{AD} - \text{power provided} - \text{in-game experience}
|
||||
```
|
||||
|
||||
#### Flow channel
|
||||
|
||||
**💡 TIP**\
|
||||
Termín, se kterým přišel Mihaly Csikszentmihalyi _[me-high cheek-sent-me-high]_.
|
||||
|
||||
Balanc mezi nudou a přílišnou obtížností.
|
||||
|
||||
- Hráč má jasný cíl.
|
||||
- Nic hráče nerozpytuje.
|
||||
- Hráč má přímou zpětnou vazbu.
|
||||
- Hra je pro hráče stále výzvou.
|
||||
|
||||

|
||||
|
||||
## Teorie her
|
||||
|
||||
**⚠️ WARNING**\
|
||||
Game design != Game theory
|
||||
|
||||
Teorie her se na _hry_ dívá jako na matematické modely, které popisují chování nějakých racionálních agentů.[wiki](#wiki)
|
||||
|
||||
### Typy her
|
||||
|
||||
V teorii her se hry dělí na:
|
||||
|
||||
- **Kooperativní**\
|
||||
V kooperativních hrách jsou závazky mezi hráči vynucovány externě (např. skrze zákon či pravidla hry).
|
||||
- **Nekooperativní (kompetitivní)**\
|
||||
U nekooperativních her jsou hráči zodpovědní za dodržování vzájemných závazků sami, ale nic je k tomu nenutí.
|
||||
- **Symetrická**\
|
||||
V symetrických hrách mají všichni hráči stejné možnosti. Jinými slovy, nezáleží na tom, **kým** hráč je, ale jakou strategii zvolí. Většina symetrických her je krátká, jelikož při delším hraní mají hráči různé strategické možnosti, a tak se hra stává _de facto_ asymetrickou.
|
||||
|
||||
Příkladem symetrické hry jsou například kámen-nůžky-papír, prisoner’s dilema.
|
||||
|
||||
Z pohledu game designu stačí, že mají hráči stejné možnosti. Tedy například šachy jsou symetrické z pohledu game designéra, ale z pohledu teorie her ne, protože bílý začíná a má tedy výhodu.
|
||||
|
||||
- **Asymetrická**\
|
||||
V případě asymetrických her **neplatí**, že strategie výhodná pro jednoho hráče bude výhodná, i když ji aplikuje někdo jiný. Většina her je asymetrických, ale to neznamená, že nejsou statisticky vyvážené.
|
||||
|
||||
Z pohledu game designu jde o hry, kde má každý hráč jiné možnosti. Hráč si například vybírá postavu s různými schopnostmi nebo má jiné cíle než ostatní hráči.
|
||||
|
||||
- **Zero-sum**\
|
||||
Zero-sum hry jsou takové, kde zisk jednoho hráče je ztrátou druhého. Například poker, kde výhra jednoho hráče je ztrátou ostatních hráčů.
|
||||
- **Non-zero-sum**\
|
||||
Celkový výsledek hry není nula. Výhra jednoho hráče neznamená nutně prohru druhého hráče.
|
||||
|
||||
### Dominantní strategie
|
||||
|
||||
> In designing an asymmetric game, **you must test the mechanics for each type of competitor against every other possible type of competitor to make sure that none has a dominant strategy**. This lengthy and involved procedure makes it more likely that a mistake will get past the testers.
|
||||
>
|
||||
> — Adams (2009)
|
||||
|
||||
> The rock-paper-scissors (or RPS) mechanism is a classic design technique for avoiding dominant strategies and forms the basis for balancing player strategies in many games.
|
||||
>
|
||||
> — Adams (2009)
|
||||
|
||||
Z pohledu teorie her je dominantní strategie taková strategie, která je pro hráče nejlepší, bez ohledu na to, jak se chovají ostatní hráči.
|
||||
|
||||
V dobře vybalancované _Player-vs-Player_ (PvP) hře:
|
||||
|
||||
- Náhoda sice může hrát roli, ale nesmí znehodnotit hráčovy skilly.
|
||||
- Skoro nikdy nedochází k remíze, obzvlášť mezi hráči s nevyrovnanými dovednostmi.
|
||||
- Si hráči myslí, že hra je fér.
|
||||
|
||||
## Narrative design
|
||||
|
||||
Game desiner může využít libovolné herní elementy k tomu, aby komunikoval nějaký příběh. Vytváří ho mixováním game designových a narativních nástrojů. Jsou jimy například: [pa215-2022](#pa215-2022)
|
||||
|
||||
- text,
|
||||
- video,
|
||||
- audio,
|
||||
- animation,
|
||||
- film sequences,
|
||||
- graphical user interface (GUI),
|
||||
- architecture,
|
||||
- system itself (procedural rhetoric),
|
||||
- players themselves (fandom, other texts, ...).
|
||||
|
||||
**Interactivity with the narrative game [zagalo](#zagalo)**
|
||||
|
||||

|
||||
|
||||
---
|
||||
|
||||
- Vyprávění ve videohrách může mít mnoho podob a nebo tam nebýt vůbec.
|
||||
- Pokud hráč nechce "naslouchat" příběhu, tak příběh nebude komunikován a tím pádem se vůbec nestane.
|
||||
|
||||
- **Poselství (message)**\
|
||||
Téma, obklopené lorem, které se posouvá ke konfliktu.
|
||||
- **Svět**\
|
||||
Kontext zahrnující prostředí a objekty. Všechno spojoje.
|
||||
- **Postavy**\
|
||||
Osobnosti, jejich prezentace a akce. Spojují svět a události.
|
||||
- **Události**\
|
||||
Jednotlivé věci, které se dějí a vytváří zápletku. Spojují formu a obsah.
|
||||
|
||||
### Story vs Narrative
|
||||
|
||||
- **Fabula (~ story)**\
|
||||
The raw material of the story.
|
||||
|
||||
Má zápletku, postavy, lore, story arc, atd.
|
||||
|
||||
- **Syuzhet (~ narrative)**\
|
||||
The way the story is organized.
|
||||
|
||||
Každé médium nabízí jiné nástroje k tomu, jak příběh vyprávět. Má specifické techniky, prostředí, rozhraní, možnosti přizpůsobení, atd.
|
||||
|
||||
### Struktura
|
||||
|
||||
- **Lineární (3-bodová struktura, Monomyth / Hero’s journey)**
|
||||
|
||||
1. Setup -- expozice, počáteční incident.
|
||||
2. Konfrontace -- překážky, krize.
|
||||
3. Rozuzlení -- vyvrcholení, závěr.
|
||||
|
||||
> [The] hero’s journey, or the monomyth, is the common template of stories that involve a hero who goes on an adventure, is victorious in a decisive crisis, and comes home changed or transformed.
|
||||
>
|
||||
> — Wikipedia: Hero's journey
|
||||
|
||||
- **Nelineární**
|
||||
|
||||
...will watch the other endings on YouTube.
|
||||
|
||||
- **Smíšená**\
|
||||
Lineární v některých místech, nelineární v jiných.
|
||||
|
||||
### Emergentní vyprávění
|
||||
|
||||
Příběhy, které nenavrhl vývojář, ale vznikají z interakce mezi hráčem (či hráči) a hrou. Liší se tak od _embedded_ vyprávění, kde jsou momenty předem skriptované, i když se větví. [rules-of-play](#rules-of-play)
|
||||
|
||||
V emergentním vyprávění je příběh důsledkem toho, že hra je dostatečně komplexní systém. V takovém systému jsou akce _coupled_ -- vzájemně propojené, rekurzivně se ovlinující. A jsou také závislé na kontextu: hráč se zachová jinak, když narazí na specifický druh nepřítele v závislosti na tom, co se mu stalo posledně.
|
||||
|
||||
- **Content generation**\
|
||||
Některé hry umožňují hráčům vytvářet nebo přidávat vlastní obsah. Toto velice často podporuje emergentní vyprávění. Možnost měnit věci, zvyšuje entropii / kreativní chaos a podporuje tak fandom, prosumerismus.
|
||||
|
||||
**📌 NOTE**\
|
||||
Prosumer = producer + consumer
|
||||
|
||||
## Tutoriál a onboarding
|
||||
|
||||
> Playing a game is a learning experience.
|
||||
>
|
||||
> — Celia Hodent
|
||||
|
||||
Jak tutoriál tak onboarding učí hráče, jak hru hrát. Onboarding je širší pojem, který zahrnuje i tutoriál. Tutoriál je jeho konkrétní, často velice explicitní formou.
|
||||
|
||||
- **Onboarding**
|
||||
- A process of teaching the player how to play a game.
|
||||
- A design of goals and obstacles to teach the player how to play a game.
|
||||
- A design of an early gameplay to motivate the player to play a game. [pa215-2019](#pa215-2019)
|
||||
- A design of gameplay to motivate the player to achieve mastery.
|
||||
|
||||
> [...] it’s incredibly powerful to teach a player how to play the game, in-game, because that way they quickly take ownership over what happens.
|
||||
>
|
||||
> — Miyamoto
|
||||
|
||||
- **Limitace hráče**
|
||||
|
||||
- Fyzické (např. ovladač, klávesnice, myš)
|
||||
- Kognitivní (např. paměť, pozornost)
|
||||
- Senzorické (např. zrak, sluch, hmat)
|
||||
|
||||
<dl><dt><strong>⚠️ WARNING</strong></dt><dd>
|
||||
|
||||
Pozor na kognitivní overload!
|
||||
</dd></dl>
|
||||
|
||||
<dl><dt><strong>💡 TIP</strong></dt><dd>
|
||||
|
||||
Doporučuje se učit hráče **maximálně** tři věci najednou. Může to být třeba:
|
||||
|
||||
1. Jak aktivovat nějakou schopnost.
|
||||
2. Jak ji použít jako reakci na nepřítele.
|
||||
3. A jak navíc uhýbat před projektily, zatímco ji používám.
|
||||
</dd></dl>
|
||||
|
||||
- **Tutoriál**\
|
||||
Typicky jeden nebo více levelů, kdy jsou hráči dány informace, jak hru hrát. Tyto levely jsou často vytrženy ze zbytku hry a nejsou součástí vyprávění a herního světa.
|
||||
|
||||
Některé tutoriály se naopak snaží být nenápadné a zakomponované do světa a příběhu (třeba Portal 2). Občas dokonce parodují své explicitní protějšky (např. Far Cry 3 nebo Undertale).
|
||||
|
||||
- **Foreshadowing**\
|
||||
Foreshadowing je technika, při které hráč dostává clues o tom, co se bude dít dál. Původně je to termín z literatury, ale používá se ve všech médiích. V game designu jej lze použít pro naznačení toho, na co se má hráč připravit (třeba boss fight), nebo naznačit hráči jeho cíl (třeba hrad na kopci nad městem).
|
||||
|
||||
## Testování hratelnosti
|
||||
|
||||
Hru je třeba testovat na hráčích, nejlépe takových, kteří jsou target audience a sami nejsou vývojáři.
|
||||
|
||||
### Iterativní design
|
||||
|
||||
Proces, kdy je game design testován na hráčích po celou dobu vývoje. A to často.
|
||||
|
||||
> 1. Think of an Idea.
|
||||
> 2. Try it out.
|
||||
> 3. Keep changing it and testing it until it seems good enough.
|
||||
>
|
||||
> — Jesse Schell
|
||||
|
||||
> Iterative design is a **play-based design process**. Emphasizing **playtesting** and **prototyping**, iterative design is a method in which **design decisions are made based on the experience of playing a game while it is in development**.
|
||||
>
|
||||
> — Salen & Zimmerman
|
||||
|
||||
> - **The Rule of the Loop**\
|
||||
> The more times you test and improve your design, the better your game will be.
|
||||
>
|
||||
> - How can I make every loop count?
|
||||
> - How can I loop as fast as possible?
|
||||
>
|
||||
> — Jesse Schell
|
||||
|
||||
### Playtesting
|
||||
|
||||
- **Playtest**
|
||||
|
||||
> A test in which a product is played, or played with, to assess its **quality**, **safety**, or **marketability**.
|
||||
>
|
||||
> — Oxford Dictionary
|
||||
|
||||
> Playtesting is a method of quality control that **takes place at many points during the video game design process**. A selected group of users play **unfinished** versions of a game to work out **flaws** in gameplay, level design and other basic elements, as well as to discover and resolve **bugs** and **glitches**.
|
||||
>
|
||||
> — Technopedia
|
||||
|
||||
- **Focus test**\
|
||||
A playtest of a game by a particular focus group.
|
||||
|
||||
---
|
||||
|
||||
> - Playtest before you think you are ready.
|
||||
> - Don’t explain.
|
||||
> - Take notes.
|
||||
> - Shut Up.
|
||||
> - Notice everything.
|
||||
>
|
||||
> — Pozzi & Zimmerman
|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[magic-circle-wiki,1]]] https://en.wikipedia.org/wiki/Magic_circle_(virtual_worlds)
|
||||
- [[[rules-of-play,2]]] Salen, Katie & Zimmerman, Eric. Rules of Play: Game Design Fundamentals. 2003.
|
||||
- [[[zimmerman-essay,3]]] [Eric Zimmerman: Jerked Around by the Magic Circle - Clearing the Air Ten Years Later](https://www.gamedeveloper.com/design/jerked-around-by-the-magic-circle---clearing-the-air-ten-years-later)
|
||||
- [[[ergodic-literature-wiki,4]]] https://en.wikipedia.org/wiki/Ergodic_literature
|
||||
- [[[wiki,5]]] https://en.wikipedia.org/wiki/Game_theory
|
||||
- [[[pa215-2022,6]]] https://is.muni.cz/auth/el/fi/podzim2022/PA215/index.qwarp
|
||||
- [[[zagalo,7]]] https://www.slideshare.net/nzagalo/videogame-narrative
|
||||
- [[[pa215-2019,8]]] https://is.muni.cz/auth/el/fi/podzim2019/PA215/um/
|
||||
- [[[fuck-rules,9]]] [Don’t follow these rules!: A Primer for Playtesting, Nathalie Pozzi and Eric Zimmerman](https://static1.squarespace.com/static/579b8aa26b8f5b8f49605c96/t/5962a494bebafbc89ca001b6/1499636884792/A+Primer+for+Playtesting.pdf)
|
405
src/content/docs/szmgr/VPH05_vyvoj_her.md
Normal file
405
src/content/docs/szmgr/VPH05_vyvoj_her.md
Normal file
@ -0,0 +1,405 @@
|
||||
---
|
||||
title: "Vývoj her"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Architektura herního engine (jednotlivé moduly a jejich význam). Herní rozhraní (fyzická, virtuální, typy vstupních a výstupních zařízení, mapování). Audio ve hrách (propagace zvuku ve scéně, digitální zvuk, PCM, latence, mixování zvuků). Síťová vrstva (přenosová rychlost, latence, obousměrné zpoždění, jitter a ztráta dat), metody redukce latence, TCP vs. UDP.
|
||||
|
||||
_PV255_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
## Architektura herního enginu
|
||||
|
||||
Herní engine je software, který slouží jako základ pro vývoj her. Obsahuje spoustu modulů, které se starají o různé aspekty hry. Moduly jsou spíše obecné a engine lze využít pro různé hry.
|
||||
|
||||
I přes to, že je game engine obecný, neznamená to, že v něm dokážeme (rozumně) vytvořit jakoukoliv hru. Existují různě specializované enginy ve kterých vytvoříme hry určitého žánru, ale i obecné enginy, ve kterých jde vytvořit téměř všechno.
|
||||
|
||||
- **Low-level moduly**
|
||||
- Core
|
||||
- Řídí základní funkce - inicializace, řízení paměti, konfigurace...
|
||||
- Zdroje a souborový systém
|
||||
- Hra potřebuje načítat spoustu dat v nejrůznějších formátech a pro různá využití (různé textury, meshe, animace, audio, level data...).
|
||||
- Každý soubor by se měl do paměti načíst ideálně jen jednou.
|
||||
- Wrapper pro file systém - programátor nemusí řešit různé operační systémy.
|
||||
- Off-line část - tak, aby se se soubory dobře pracovalo, zároveň se řeší převod na formáty, které jsou pro hru efektivnější.
|
||||
- Runtime část - načítání/odnačítání souborů do paměti, správa paměti.
|
||||
- Game loop
|
||||
- Značná část kódu běží v nekonečné smyčce. Rychlost smyčky je dána prioritou a náročností výpočtů (např. grafika 60 Hz, fyzika 50 Hz, AI 5 Hz).
|
||||
- Na většinu výpočtů je omezený čas jen několik milisekund (60 Hz ~ 16 ms).
|
||||
- Ve hře lze měřit milion různých časů - reálný čas, čas ve hře, pauza, čas animace, čas mezi snímky, CPU time budget...
|
||||
- Human Interface
|
||||
- Input / Output
|
||||
- Mapování vstupů na akce
|
||||
- Podpora vývoje a debugování
|
||||
- Logs, warnings, errors
|
||||
- Profiling
|
||||
- Crash reporty
|
||||
- Debug gizmos (debug ray, box, sphere...)
|
||||
- Debug menu a konzole
|
||||
- **Zvkuk**\
|
||||
Speciální engine pro zvuk, často middleware jako FMOD nebo Wwise.
|
||||
- **Graphics**\
|
||||
Zařizuje vykreslování grafiky, osvětlení, stíny, postprocessing, atd.
|
||||
- **Physics**\
|
||||
Zajišťuje fyziku - kolize, gravitace, interakce s objekty, atd.
|
||||
|
||||
## Herní rozhraní
|
||||
|
||||
Herní rozhraní je to, co přijímá od hráče nějaký vstup (input device) nebo mu vrací nějaký výstup (output device). Někdy zvládá zařízení obě funkce zaráz - např. volant je jistě vstupní zařízení, ale může zároveň podporovat force feedback, tedy výstup. [pv255](#pv255)
|
||||
|
||||
### Fyzická rozhraní
|
||||
|
||||
_Fyzická rozhraní_ jsou všechny možné ovladače, klávesnice, myš, joystick, volant, kytara, ale taky výstupy jako monitor, reproduktory, dotykový display, atd. Zkrátka to, na co si hráč sáhne.
|
||||
|
||||
- **Digitální**\
|
||||
Posílají binární signály. Jsou buď stisknuté nebo ne. Typickým příkladem je klávesnice, ale taky tlačítka na gamepadu, myši, atd.
|
||||
- **Analogová**\
|
||||
Posílají spojité signály. Typickým příkladem je analogový joystick, ale taky např. tlačítka na gamepadu, která mohou mít různou intenzitu stisku. Patří sem, ale taky motion sensory jako kinect, gyroskop, akcelerometr, atd.
|
||||
|
||||
**📌 NOTE**\
|
||||
Mechanické klávesnice, které mnohdy taky posílají spojité signály, zdá se nikdo zatím moc nepoužil.
|
||||
|
||||
### Virtuální rozhraní
|
||||
|
||||
Na _virtuální rozhraní_ si hráč nesáhne. Jsou to všemožná menu, inventáře, interaktivní objekty, atd.
|
||||
|
||||
- **GUI -- graphical user interface**\
|
||||
Obecný low-level pojem pro všechny abstraktní interaktivní formulářovité objekty, které se zobrazují na obrazovce, ale většinou nejsou přímo herními objekty.
|
||||
- **HUD -- head-up display**\
|
||||
Virtuální rozhraní, která má hráč neustále na očích, ale nejsou (často) součástí herních objektů. Např. životy, zásoby munice, minimapa, atd.
|
||||
- **Diegetická (dynamická) rozhraní**\
|
||||
UI prvky, které jsou součástí herního světa. Např. interaktivní terminál, který ovládá hráč, nebo hologramy, které se zobrazují v prostoru. Dopomáhají k imerzi, ale mohou hráče frustrovat jelikož bývají pomalejší (protože animace) a mohou být obtížně čitelné. [ui](#ui)
|
||||
|
||||
**Fallout 3**
|
||||
|
||||

|
||||
|
||||
- **Nediegetická (statická) rozhraní**\
|
||||
Jsou "mimo" herní svět, přilepená k obrazovce, a jsou abstraktní, nesouvisí přímo s herním světem.
|
||||
|
||||
**World of Warcraft**
|
||||
|
||||

|
||||
|
||||
- **Meta rozhraní**\
|
||||
Jsou sice mimo herní svět, ale alespoň s ním souvisí. Třeba telefon v GTA IV.
|
||||
|
||||
**GTA IV**
|
||||
|
||||

|
||||
|
||||
**💡 TIP**\
|
||||
[Meta](https://about.meta.com) rozhraní != Oculus Quest
|
||||
|
||||
- **Spatial (prostorová) rozhraní**\
|
||||
Nejsou "bežnou" součástí herního světa, ale nejsou ani mimo něj.
|
||||
|
||||
**Forza**
|
||||
|
||||

|
||||
|
||||
### Virtuální realita (VR)
|
||||
|
||||
Virtuální realita hranici mezi fyzickými a virtuálními rozhraními tak trochu stírá. Hráči si sice nemohou sáhnout na virtuální rozhraní, ale mohou se na ně dívat z blízka a sahat na ně ovladači nebo je ovládat gesty.
|
||||
|
||||
### Brain computer interaction (BCI)
|
||||
|
||||
BCI je technologie, která umožňuje ovládat počítač přímo pomocí myšlenek. V současnosti je to spíše sci-fi, ale v budoucnu by to mohlo být další rozhraní, které by se dalo použít ve hrách.
|
||||
|
||||
### UI vs. UX
|
||||
|
||||
Zjednodušeně, UI řeší vizuální stránku rozhraní, kdežto UX tu funkční. Realita je ale složitější, neboť vizuál a funkčnost se mnohdy vzájemně ovlivňují.
|
||||
|
||||
- **UI -- user interface**\
|
||||
UI řeší vizuální prvky, které se zobrazují na obrazovce. Konkrétně se zaobírá jejich vzhledem, umístěním, "feelem". Zahrnuje například: [figma](#figma)
|
||||
|
||||
- Layout
|
||||
- Typografii
|
||||
- Barevnou paletu
|
||||
- Interaktivní prvky: tlačítka, checkboxy, radio buttony, comboboxy, selecty, dropdowny, nebo nedejbože datetimepickery.
|
||||
|
||||
- **UX -- user experience**\
|
||||
UX řeší prvky, které se zobrazují na obrazovce, ale zabývá se tím, _jak_ je uživatelé používají, a jestli splňují svůj účel. Zahrnuje třeba: [figma](#figma)
|
||||
|
||||
- Průzkum uživatelských očekávání a konkurence
|
||||
- Wireframy a prototypování
|
||||
- Testování
|
||||
|
||||
### Mapování
|
||||
|
||||
Relace mezi vstupem a jeho významem. Např. stisknutí klávesy "W" => pohyb vpřed. Mapování funguje i ve virtuální vrstvě: kliknutí na křížek => zavření okna.
|
||||
|
||||
V ideálním případě si může hráč "přemapovat" vstupy podle svých preferencí. (Není nic horšího než když se vám pokazí D a přijdete tak o možnost chodit doprava. Hádám ale, že tohle stejně není primární účel...)
|
||||
|
||||
Problém s mapováním je při podpoře různých vstupních zařízení. "B" má jiné umístění na klávesnici, Xbox ovladači, switchi a na playstation ovladači vůbec není. Hra by měla brát tenhle fakt v potaz a nejen vybrat správné tlačítko, ale měla by i hráči zobrazit správné ikony.
|
||||
|
||||
## Audio ve hrách
|
||||
|
||||
Audio je důležité pro vytvoření atmosféry a imerze. Většina her má nějaký zvuk, ať už je to hudba (tvoří mood), zvuky prostředí (tvoří mood a zároveň informuje hráče), nebo dialogy postav (příběh).
|
||||
|
||||
### Propagace zvuku ve scéně
|
||||
|
||||
Zvuk lze ve scéně propagovat různými způsoby s různou složitostí. Nejjednodušší varianta nijak neřeší scénu a jen přehraje zvuk (2D zvuk). Pro lepší imerzi je vhodné použít různé efekty které modelují propagaci zvuku skrz prostředí (3D zvuk).
|
||||
|
||||
- **Distance attenuation**\
|
||||
Zvuk se zeslabuje s vzdáleností. V reálném světě je zeslabení kvadratické, ve hrách se pro aproximaci používá i lineární zeslabení.
|
||||
- **Propagation**\
|
||||
Oběkty ve scéně mohou zvuk blokovat, odrážet a zeslabovat.
|
||||
|
||||
- Occlusion - zvuk je blokován překážkou.
|
||||
- Attenuation - zvuk je zeslaben překážkou.
|
||||
- Obstruction - přímá cesta zvuku je blokována, ale zvuk se může dostat k posluchači přes odraz. Zvuk přichází z jiného směru, než je zdroj.
|
||||
- Exclusion - existuje jen přímá cesta, nepříme cesty jsou blokovány.
|
||||
|
||||
- **Ozvěna a dozvuk**\
|
||||
Zvuk se odráží od překážek a dostává se k uchu několikrát po sobě. Tomuto efektu se říká také "wet sound".
|
||||
|
||||
- Přímí zvuk - zvuk, který přijde přímo od zdroje.
|
||||
- Dozvuk - zvuk, který se odráží od blízkých překážek. Člověk jej vnímá jakou souvyslý zvuk.
|
||||
- Ozvěna - zvuk, který se odráží od vzdálených překážek. Člověk ji vnímá jako zopakování původního zvuku.
|
||||
|
||||
- **Dopplerův efekt**\
|
||||
Výška tónu se mění podle relativní rychlosti zdroje a posluchače. V praxi si tohoto jevu můžete všimnout například při projíždění sanitky - když se blíží, je slyšet vyšší tón, než když se vzdaluje.
|
||||
- **Spoždění**\
|
||||
Zvuk se šíří určitou rychlostí. Čím dál je zdroj, tím déle trvá, než zvuk dorazí k posluchači.
|
||||
|
||||
### Digitální zvuk
|
||||
|
||||
Zvuk v normálním světě je spojitá funkce času (analog). V počítačích se ale reprezentuje jako diskrétní hodnoty.
|
||||
|
||||
- **Vzorkování**\
|
||||
Spojitá funkce se vzorkuje v pravidelných intervalech. Vzniknou tak diskrétní body v čase.
|
||||
- **Kvantizace**\
|
||||
Původní signál může nabývat jakékoliv hodnoty, počítač má jen omezenou přesnost. Proto se musí naměřená hodnota převést na hodnotu z nějaké vybrané množiny povolených hodnot.
|
||||
- **PCM -- pulse-code modulation**\
|
||||
Formát zvukových dat, kde zvuk je reprezentován jako posloupnost jednotlivých naměřených hodnot v rozmezí [-1, 1]. Posloupnost obsahuje k-tice hodnot, kde k je počet kanálů (mono, stereo, 5.1, atd.). Zvuková karta dokáže tuto posloupnost převést zpět na analogový signál pro reproduktory.
|
||||
- **Latence**\
|
||||
Zvuková karta dostává data v bufferu a až poté zvuk přehraje. Latence je doba mezi tím, kdy se zvuk pošle a kdy jde zvuk reálně slyšet. Čím menší buffer, tím menší latence, ale vyšší nároky na procesor, který buffer plní. Pokud by zvuková karta nedostala data včas, zvuk bude poškozený. Proto audio callback (funkce, která plní buffer) bývá obvykle v separátním vlákně s vysokou prioritou, které bere předpřipravená data z fronty, která obsahuje předem dekódované zvuky (dekódování je časově náročné).
|
||||
- **Mixování**\
|
||||
Mixování je třeba, pokud chceme přehrát několik zvuků naráz (např. výstřel za běhu při epické hudbě). Jednotlivé zvuky se sčítají, ale může tak dojít k přetečení z intervalu [-1, 1] => musí se nějak opravit.
|
||||
|
||||
Při mixování lze aplikovat i různé efekty (např. změna hlasitosti, ozvěna, změna frekvence). Efekty lze aplikovat na jednotlivé kanály nebo na celý mix. Vznikne tak přímí acyklický graf efektů a mixérů.
|
||||
|
||||
## Síťová vrstva
|
||||
|
||||
Síťová hra nemusí být multiplayer, a multiplayer hra nemusí být síťová.
|
||||
|
||||
### Krátké opakování ze sítí
|
||||
|
||||
- **ISO/OSI model**
|
||||
- Fyzická vrstva - kabely, konektory, modulace signálu...
|
||||
- Linková vrstva - spojení mezi dvěma sousedními uzly (MAC adresy), detekce chyb...
|
||||
- Síťová vrstva - spojení mezi systémy, které spolu nesousedí (směrování), adresace (IP)...
|
||||
- Transportní vrstva - doručení mezi koncovými uzly, zaručuje kvalitu (TCP, UDP)...
|
||||
- Relační vrstva - organizace a synchronizace komunikace mezi systémy...
|
||||
- Prezentační vrstva - formátování, komprese, šifrování...
|
||||
- Aplikační vrstva - konkrétní aplikace a služby (HTTP, FTP, SSH, DNS, ...).
|
||||
- **IP network**\
|
||||
Graf po kterém putují pakety dat. Data putují přes několik routerů, které se snaží najít nejkratší cestu k cíli. Kvůli konečné rychlosti světla dochází při přenosu ke spoždění.
|
||||
- **Posílání dat přes TCP**
|
||||
- Přijaté data jsou seřazena do správného pořadí.
|
||||
- Pokud nějaký paket chybí, je znovu odeslán.
|
||||
- Základní kontrola chyb (checksum).
|
||||
- Množství dat je omezeno a upravuje se podle chování sítě.
|
||||
- **Posílání dat přes UDP**
|
||||
- Data jsou posílána bez záruky doručení.
|
||||
- Data mohou dorazit v jiném pořadí, než byla odeslána.
|
||||
- Nemá žádnou kontrolu chyb.
|
||||
- **Přenosová rychlost**\
|
||||
Maximální množství dat, které může být přeneseno za jednotku času. Měří se v bit/s a odvozených jednotkách (kbit/s, Mbit/s, Gbit/s).
|
||||
- **Latence**\
|
||||
Doba, která uplyne mezi odesláním dat a doručením dat. Měří se v ms.
|
||||
- **Obousměrné zpoždění (round-trip time, RTT, lag)**\
|
||||
Doba, která uplyne mezi odesláním dat a doručením zpět.
|
||||
- **Jitter**\
|
||||
Variabilita latence. Pokud je jitter vysoký, může dojít k nepředvídatelným zpožděním.
|
||||
- **Ztráta paketů**\
|
||||
Procento ztracených paketů.
|
||||
|
||||
### Metody redukce latence
|
||||
|
||||
Stav hry u jednotlivých hráčů a na serveru jsou desynchronizovány kvůli latenci. Jako "správný" stav hry se bere typicky stav na serveru.
|
||||
|
||||
**State inconsistency due to latency [netwok-delay](#netwok-delay).**
|
||||
|
||||

|
||||
|
||||
Určitě všichni máme zkušenosti s tím, že se teleportujeme zpět, někdo nás zastřelí, když už jsme za rohem, nebo naopak po někom střelíme a protihráče kulka nezasáhne...
|
||||
|
||||
- **Player prediction**
|
||||
- Server má správný stav hry, dělá výpočty a periodicky posílá stav hry hráčům.
|
||||
- Hráč odesílá akce serveru, ale zároveň sám simuluje hru na základě vlastních vstupů a stavu hry. Klient tak predikuje, jak uvidí server jeho jednotky. Pokud stav sedí, pokračuje se dál v simulaci, pokud ne, stav se upraví podle toho, co řekl server.
|
||||
- **Opponent prediction (dead reckoning)**\
|
||||
Podobný jako player prediction, ale hráčův stroj simuluje a porovnává stav hry všech hráčů a jiných simulovaných objektů. Pokud se stav neshoduje, klient si upraví stav hry podle toho, co řekl server.
|
||||
|
||||
Pro objekty řízené serverem funguje dobře, ale pro ostatní hráče je často nepřesný a proto vznikají artefakty jako náhlé změny směru a rychlosti. Tento problém lze vyřešit například interpolací - stav se plynule interpoluje mezi dvěma známými stavy. To ale přináší ještě větší spoždění.
|
||||
|
||||
- **Lag compensation (time warp)**\
|
||||
Snaží se vyřešit problém, kdy hráč střílí na místo, kde byl protihráč v minulosti, ale kvůli latenci se protihráč už posunul.
|
||||
|
||||
- Server si drží historii stavů hry a odhaduje spoždění hráčů.
|
||||
- Když hráč střílí, server se podívá do historie a zjistí, kde byl protihráč v době, kdy hráč střílel.
|
||||
|
||||
- **Data compression**\
|
||||
Méně dat = rychlejší přenos a zpracování.
|
||||
|
||||
- Delta compression - server posílá jen věci, co se změnili.
|
||||
- Interest management - server posílá jen věci, které hráči zajímají. Navíc může prioritizovat data podle toho, jak důležitá jsou (na základě vzdálenosti, viditelnosti, rychlosti pohybu).
|
||||
- Komprese vlastností objektů - např. rotace jako 3 floaty místo čtyř, pozice s nižší přesností, atd.
|
||||
|
||||
- **Vizuální triky**\
|
||||
Akce trvá delší dobu, během které se zobrazuje animace, která zakrývá spoždění. Např. když hráč střílí, zobrazí se animace výstřelu, která trvá déle, než je spoždění.
|
||||
|
||||
### TCP vs. UDP
|
||||
|
||||
TCP má spoustu skvělých vlastností které ho ale zpomalují. Hry proto často používají UDP a řeší si problémy s doručením dat samy.
|
||||
|
||||
- **Ztráta paketů**\
|
||||
Pokud TCP nedoručí packet opakuje jeho odeslání, což může spomalit doručení celé zprávy. Hra nemusí čekat na znovu odeslaný paket, data stejně zachvíli přijdou znovu spolu s novým stavem.
|
||||
- **Packet order**\
|
||||
TCP zachovává pořadí paketů, takže musí čekat na doručení všech předchozích paketů. Pkud hra dokáže zpracovávat pakety nezávisle, ušetří tím čas.
|
||||
- **Basic error detection**\
|
||||
TCP má kontrolní součet, který kontroluje, zda data dorazila v pořádku. Hra může korektnost dat ověřit na základě obsahu - např. zda změna pozice je v rámci rozumného limitu.
|
||||
|
||||
## Další věci ze staré verze otázky
|
||||
|
||||
## Produkční fáze
|
||||
|
||||
### 1. Pre-produkce
|
||||
|
||||
Během _pre-produkce_, která obvykle trvá týdny až měsíce (nebo roky v nejmenovaných případech) jde o to příjít na: [cg](#cg)
|
||||
|
||||
- O čem hra má být.
|
||||
- Kdo je její cílovka.
|
||||
- Co za podobné hry existuje.
|
||||
- Kdo na ní bude pracovat.
|
||||
- Jak dlouho bude vývoj trvat.
|
||||
- Kolik to celé bude stát a kdo to zaplatí.
|
||||
|
||||
Během pre-produkce typicky vzniká řada věcí:
|
||||
|
||||
- **Pitch document**\
|
||||
Základní popis hry, který se používá pro prezentaci investorům, vydavatelům, atd.
|
||||
- **Game Design Document (GDD)**\
|
||||
Žijící, stále se měnící dokument popisující aktuální představu o hře. Užitečný pro udržení konzistentní představy o hře mezi členy týmu.
|
||||
- **Moodboard**\
|
||||
Kolekce obrázků vykradených z jiných děl. Má vyjádřit náladu, atmosféru, styl, navrhované hry.
|
||||
- **Concept art**\
|
||||
Vizuální návrhy postav, prostředí, objektů, atd.
|
||||
- **Prototyp**\
|
||||
Zbastlená verze (části) hry s placeholder assety. Má testovat herní mechaniky.
|
||||
|
||||
### 2. Produkce
|
||||
|
||||
_Produkce_ je nejdelší fáze vývoje, kdy je potřeba všechno vyrobit a složit dohromady. Může trvat až několik (desítek) let. Jelikož ne všechno se v pre-produkci dá předvídat, hra je během produkce stále testována a upravována. [cg](#cg)
|
||||
|
||||
Produkce prochází mnoha milníky:
|
||||
|
||||
- **Prototyp**\
|
||||
To, co vyleze z pre-produkce.
|
||||
- **Greybox**\
|
||||
Hra je hratelná, ale všechno jsou jenom šedé kostky. Šetří čas a peníze, protože se nemusí dělat finální grafika, která by se stejně nejspíš musela zahodit.
|
||||
- **First playable**\
|
||||
By měla člověku dát trochu lepší představu o tom, jak se ta hra bude hrát, a cca i jak bude vypadat.
|
||||
- **Vertical slice**\
|
||||
Plně hratelný a ografikovaný vzorek hry. Často se používá při prezentaci hry investorům.
|
||||
- **Pre-alpha**\
|
||||
Většina věcí je hotová, ale ještě se může hodně změnit. Hra je hratelná, ale plná chyb. Content ještě může být ořezán nebo doplněn.
|
||||
- **Alpha**\
|
||||
Hra je "hotová" ve smyslu, že hypoteticky obsahuje všechno, co má mít. Dá se zahrát od začátku do konce. Assety můžou chybět nebo nebýt `final_final`, ale funkcionalita by tam měla být všechna.
|
||||
- **Beta**\
|
||||
Masová genocida brouků. Do této fáze se často zapojuje velké množství tzv. testerů -- masochistických, neplacených semi-dobrovolníků, kteří brouky pomáhají hledat, aby je mohli vývojáři zmasakrovat. Testeři mnohdy přichází z řad rodiny a přátel vývojářů, nebo jsout to studenti herních oborů.
|
||||
- **Gold master**\
|
||||
Hra je ready k vypálení na CDčko, disketu nebo vinyl.
|
||||
|
||||
### 3. Post-produkce
|
||||
|
||||
Jakmile hra vyjde, malý tým vývojářů se stará o opravování chyb, vydávání patchů a DLCčka. Nicméně, záleží na business modelu, pokud je hra "live service", pak mívá celý tým, který řeší její provoz, marketing, komunikaci s komunitou hráčů, atd.
|
||||
|
||||
## Principy monetizace
|
||||
|
||||
Monetizace je proces extrakce finančních prostředků z videoherního, interaktivního produktu či služby. Zkrátka, když už má někdo hru, chce ji nějakým způsobem prodat. [monetization](#monetization)
|
||||
|
||||
- **Premium**\
|
||||
Tradiční jednorázová platba buď v kamenném obchodě (retail) nebo online (digital download). Hra je poté hráči k dispozici "navždy". Vývojáři mohou vydávat DLCčka, která se prodávají zvlášť. Speciální případ je crowdfunding, kdy hráči platí za hru ještě předtím, než je hotová, a mnohdy dostanou nějaké bonusy.
|
||||
- **Gratis a/nebo open-source**\
|
||||
Hra je zdarma a její zdrojový kód může být dokonce veřejně dostupný. Hráči mohou hru upravovat a distribuovat dál.
|
||||
|
||||
Hry se do tohoto modelu většinou spadnou až po dostatečně dlouhé době (abandonware).
|
||||
|
||||
**💡 TIP**\
|
||||
Víš, že sem spadá třeba [Quake](https://github.com/id-Software/Quake), [DOOM](https://github.com/id-Software/DOOM) nebo [Wolfenstein 3D](https://github.com/id-Software/wolf3d)?
|
||||
|
||||
- **Games as a service (GaaS)**\
|
||||
Různé taktiky, jak hru monetizovat i po té, co si ji hráč koupil, aby za ni platil kontinuálně. Mezi tyto taktiky patří např. subscripce, mikrotransakce, reklamy, atd.
|
||||
- **Subscription model / předplatné / pay-to-pay**\
|
||||
Hráči platí pravidelně (měsíčně, ročně) za přístup k hře. Hra je poté hráči k dispozici po celou dobu, kdy platí.
|
||||
- **Freemium**\
|
||||
Hra je zdarma, ale je značně omezená, a snaží se hráče dotlačit k tomu, aby si ji koupil.
|
||||
- **Free-to-play**\
|
||||
Hra je "zdarma", ale obsahuje mikrotransakce. Hry se liší v tom, zda mikrotransakce ovlivňují hratelnost (pay-to-win) nebo jsou pouze kosmetické. Existuje mnoho druhů mikrotransakcí, např.: lootboxy, DLCčka, season passy, atd.
|
||||
- **Reklama / advertising**\
|
||||
Hra je zdarma, ale obsahuje reklamu. Reklama může být vložena do hry (např. billboardy v GTA) nebo může být zobrazena před nebo po hraní.
|
||||
|
||||
## Procedurální generování assetů
|
||||
|
||||
Procedurální generování je technika, která umožňuje generovat herní assety (mapy, modely, textury, zvuky, atd.) pomocí algoritmů. Výhodou je, že se nemusí všechno vytvářet ručně, ale na druhou stranu je třeba vytvořit algoritmy, které to umí. Výsledky procedurálního generování bývají často nepředvídatelné, což je ne vždycky žádoucí.
|
||||
|
||||
- **Noise**\
|
||||
Množina funkcí generujících pseudo-náhodné hodnoty, které jsou spojité. Používá se při generování terénu, obláčků, všemožných textur, zkrátka všude.
|
||||
- **Perlin noise**\
|
||||
Noise, který vymyslel Ken Perlin, když pracoval na filmu Tron (1982) v Disney. Má tu krásnou vlastnost, že není patentovaný. [perlin](#perlin)
|
||||
- **Simplex noise**\
|
||||
Vylepšený Perlin noise, který taky vymyslel Ken Pelin. Tenhle už si patentovat nechal. [perlin](#perlin)
|
||||
- **L-systém**\
|
||||
Něco, co náramně připomíná formální gramatiku, ale aplikuje to pravidla v jedné iteraci "paralelně" na všechny aplikovatelné symboly. Používá se při generování stromů, rostlin, a obecně věcí, co mají větvě.
|
||||
|
||||
## Serious games
|
||||
|
||||
_Serious games_ jsou hry, jejichž hlavním účelem není zábava. Cílí na vzdělávání, mentální zdraví, marketing, trénink v oblasti průmyslu, atd.
|
||||
|
||||
Serious games se dají dělit podle jejich cíle:
|
||||
|
||||
- **Předávání informací**\
|
||||
Využitím narativních prvků, puzzlů, hádanek a podobně, může hra předat hráči historický kontext.
|
||||
|
||||
Třeba _Papers, Please_, nebo _This War of Mine_.
|
||||
|
||||
- **Trénink**\
|
||||
Hra může být simulací nějakého procesu, který se v reálném světě děje.
|
||||
|
||||
Třeba simulace letu, řízení nějakého průmyslového procesu, nebo lékařského postupu.
|
||||
|
||||
**📌 NOTE**\
|
||||
Chce se mi zmínit [Surgeon Simulator](https://store.steampowered.com/app/233720/surgeon_simulator/), ale to nejspíš není nejlepší příklad.
|
||||
|
||||
- **Zvýšení povědomí a změna chování**\
|
||||
Například aplikace o globálním oteplování, třídění odpadu, nebo o zdravém životním stylu.
|
||||
- **Zvýšení motivace**\
|
||||
Například aplikace, která hráče motivuje k pohybu, nebo aplikace, která hráče motivuje k učení se jazykům.
|
||||
|
||||
Třeba [_Duolingo_](https://www.duolingo.com/).
|
||||
|
||||
## Gamification
|
||||
|
||||
_Gamifikace_ je o použití designových principů a mechanik, které se osvědčily v "obyčejných" hrách cílících na zábavu, v jiných oblastech. Úmyslem je zpříjemnit činnosti, které by jinak byly nudné, a tak zvýšit produktivitu práce.
|
||||
|
||||
Gamifikace ale mnohdy zůstává u jednoduchých herních prvků, jako jsou achievementy, leaderboardy, nebo jiné formy odměňování. Naopak, serious games se snaží využít herních principů do hloubky, aby hráč musel k získání odměny vynaložit nějakou snahu. [serious-terminology](#serious-terminology) Gamifikace je proto často brána jako manipulativní a opovrženihodná.
|
||||
|
||||
## Zdroje
|
||||
|
||||
- Nové části otázky je vypracována dle prezentací z předmětu [PV255](https://is.muni.cz/auth/el/fi/podzim2022/PV255/um/lec/).
|
||||
- [[[netwok-delay,1]]] https://is.muni.cz/auth/el/fi/podzim2022/PV255/um/lec/Networking_in_computer_games.ppsx
|
||||
- [[[cg,2]]] https://www.cgspectrum.com/blog/game-development-process
|
||||
- [[[g2,3]]] https://www.g2.com/articles/stages-of-game-development
|
||||
- [[[monetization,4]]] https://en.wikipedia.org/wiki/Video_game_monetization
|
||||
- [[[pv255, 5]]] https://www.fi.muni.cz/~xchmeli1/PV255/materials.cgi
|
||||
- [[[ui,6]]] https://www.gamedeveloper.com/design/user-interface-design-in-video-games
|
||||
- [[[figma, 7]]] https://www.figma.com/resource-library/difference-between-ui-and-ux/
|
||||
- [[[perlin, 8]]] https://en.wikipedia.org/wiki/Perlin_noise
|
||||
- [[[serious, 9]]] https://grendelgames.com/what-are-serious-games/
|
||||
- [[[serious-terminology, 10]]] https://grendelgames.com/serious-games-terminology/
|
||||
- [[[serious-types, 11]]] https://grendelgames.com/what-are-the-five-types-of-serious-games/
|
556
src/content/docs/szmgr/VPH06_ai_ve_hrach.md
Normal file
556
src/content/docs/szmgr/VPH06_ai_ve_hrach.md
Normal file
@ -0,0 +1,556 @@
|
||||
---
|
||||
title: "Umělá inteligence v počítačových hrách"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Pohyb, kinematický a dynamický pohyb. Hledání cest, algoritmy prohledávání grafu, A\* s jeho datovými strukturami a heuristikami, reprezentace herního světa, hierarchické hledání cest. Rozhodování, rozhodovací stromy, stavové automaty, stromy chování, cílem orientované chování. Taktická a strategická umělá inteligence, navigační body a taktika, taktická analýza. Deskové hry, minimax algoritmy, Monte Carlo prohledávání.
|
||||
|
||||
_PA217_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
## Pohyb
|
||||
|
||||
Postavy ve hrách se často hýbou, tedy mění svoji pozici a orientaci v herním světě. Mnohdy je žádoucí, aby se pohybovaly věrohodně:
|
||||
|
||||
- zpomalovaly,
|
||||
- zrychlovaly,
|
||||
- vyhýbaly se překážkám,
|
||||
- utíkaly před nepřáteli,
|
||||
- interagovaly s prostředím.
|
||||
|
||||
- **Pozice**\
|
||||
Tradičně je dána jako vektor $(x, z)$ nebo $(x, y, z)$.
|
||||
- **Orientace**\
|
||||
Obvykle v radiánech. Desetinné číslo z intervalu $\lbrack 0, 2\pi )$.
|
||||
- **Rychlost / velocity**\
|
||||
Změna pozice. Vektor $(x, z)$ nebo $(x, y, z)$.
|
||||
- **Úhlová rychlost / angular velocity / "rotace"**\
|
||||
Změna rotace. Desetinné číslo z intervalu $\lbrack 0, 2\pi )$.
|
||||
- **Agent**\
|
||||
Postava / objekt / entita vykonávájí pohyb a činící rozhodnutí.
|
||||
|
||||
### Kinematický pohyb
|
||||
|
||||
Postavy se prostě pohybují bez ohledu na fyzikální korektnost.
|
||||
|
||||
- Charakter má pozici, orientaci, rychlost a úhlovou rychlost.
|
||||
- Nemá zrychlení - rychlost se může měnit okamžitě.
|
||||
- Orientace může být počítána podle směru rychlosti.
|
||||
- Výhodou je jednoduchost a předvídatelnost.
|
||||
- Nevýhodou je, že pohyb nemusí být věrohodný.
|
||||
- Příkladem je pohyb většiny postav ovládaných hráčem. Pokud hráč pustí `W`, chce obvykle zastavit hned.
|
||||
|
||||
- **Update**\
|
||||
V každém frame:
|
||||
|
||||
```csharp
|
||||
void Update(float deltaTime)
|
||||
{
|
||||
Position += Velocity * deltaTime;
|
||||
Orientation = (Orientation + (AngularVelocity * deltaTime))
|
||||
% (2 * Math.PI);
|
||||
Velocity += SteeringLinear * deltaTime;
|
||||
AngularVelocity = (AngularVelocity + (SteeringAngular * deltaTime))
|
||||
% (2 * Math.PI);
|
||||
}
|
||||
```
|
||||
|
||||
- **Algoritmy kinematického pohybu**
|
||||
- _Seek_: agent se snaží dostat k cíli. (`velocity = (target.pos - character.pos).normalized * maxSpeed`)
|
||||
- _Flee_: agent se snaží dostat od cíle. (`velocity = (character.pos - target.pos).normalized * maxSpeed`)
|
||||
- _Arrival_: agent se snaží dostat k cíli a zpomaluje, když je blízko.
|
||||
- _Wander_: agent se hýbe náhodně - náhodně mění rotaci a jde neustále vpřed. (`rotation = ranom(0, 1) - random(0, 1) * maxRotation`)
|
||||
|
||||
### Dynamický pohyb
|
||||
|
||||
Postavy mění rychlost a zatáčí podle fyzikálních zákonů. Oproti kinematickému pohybu obsahují zrychlení (lineární i úhlové) - plynule zrychlují, dosahují maximální rychlosti a plynule zpomalují.
|
||||
|
||||
#### Řízení chování / steering behaviors
|
||||
|
||||
Jednoduché algoritmy pro pohyb. Jsou škálovatelné a předvídatelné, ale mají problém s lokálními pastmi (zaseknou se a neví, jak ven). Základními algoritmy jsou:
|
||||
|
||||
- **Seek**\
|
||||
Přímočárý... doslova. Najde vektor mířící k cíli a aplikuje je jej jako steering.
|
||||
|
||||
**Seek schematic [steering](#steering)**
|
||||
|
||||

|
||||
|
||||
- **Flee**\
|
||||
Jako seek, ale **od** cíle místo k cíli.
|
||||
- **Align**\
|
||||
Agent se snaží zarovnat svou orientaci s cílem.
|
||||
- **Velocity matching**\
|
||||
Agent se snaží mít stejnou rychlost jako cíl.
|
||||
|
||||
Pomocí těchto základních algoritmů lze vytvořit složitější chování:
|
||||
|
||||
- **Arrival**\
|
||||
Jako seek, ale začne zpomalovat, když je blízko cíle, takže jej "nepřestřelí".
|
||||
|
||||
**Arrival schematic [steering](#steering)**
|
||||
|
||||

|
||||
|
||||
- **Departure**\
|
||||
Flee, ale agent zpomalí, jakmile je dostatečně daleko od cíle.
|
||||
- **Pursue**\
|
||||
Agent pronásleduje agenta. Najde vektor mířící k cíli a aplikuje jej jako steering. Pokud se cítí obzvlášť chytrý, může předvídat, kterým směrem se cíl bude ubírat.
|
||||
|
||||
Příklad: predátor loví kořist.
|
||||
|
||||
- **Evade**\
|
||||
Agent se vyhýbá agentovi. Jako pursue, ale snaží se cíli vyhnout.
|
||||
|
||||
Příklad: kořist se vyhýbá predátorovi.
|
||||
|
||||
- **Wander**\
|
||||
Agent se hýbe náhodně. Není to ale tak jednoduché, jak se zdá, protože nechceme, aby sebou agent jen házel ze strany na stranu. Jako seek, ale k cíli se v každém kroku přidává drobný náhodný posun.
|
||||
- **Obstacle avoidance / vyhýbání se překážkám**\
|
||||
Agent detekuje, zda se v blízké době srazí s překážkou -- ray castingem, testy na overlapping -- a pokud ano, najde cíl, který je mimo překážku a aplikuje _seek_.
|
||||
|
||||
Má problém s úzkými překážkami a pastmi.
|
||||
|
||||
- **Path following**\
|
||||
Agent směřuje ne _jen_ k pouhému bodu, ale k _nejbližšímu_ bodu na dané cestě a ten _seekuje_.
|
||||
- **Predictive path following**\
|
||||
Agent předvídá, kde bude za krátkou chvíli a hledá _nejbližší_ bod na dané cestě k **této predikci**. Pohyb je plynulejší.
|
||||
- **Cohesion**\
|
||||
Agent se snaží být blízko ostatním agentům ve skupině. Jeho target je průměrná pozice blízkých agentů.
|
||||
- **Separation**\
|
||||
Agent se snaží udržet si odstup od ostatních agentů ve skupině. Jde o Evade, jehož síla je závislá na vzdálenosti od ostatních agentů.
|
||||
|
||||
Jednotlivé steering behaviors se dají kombinovat:
|
||||
|
||||
- _Blending_: provádí více steering behaviors najednou a výsledný vektor je jejich váženým průměrem.
|
||||
- _Arbitration_: volí jedno steering behavior, které má absolutní moc.
|
||||
|
||||
- **Flocking / chování hejna**\
|
||||
Blenduje 3 chování, díky kterým se agenti drží pohromadě a pohybují se jako hejno.
|
||||
|
||||
- _Separation / oddělení_: agent se snaží nenarážet do ostatních agentů v daném okolí.
|
||||
- _Alignment / zarovnání_: pohybuj se (průměrně) stejným směrem a rychlostí jako ostatní agenti v okolí.
|
||||
- _Cohesion / soudržnost_: pohybuj se směrem ke středu hmoty hejna.
|
||||
|
||||
## Pathfinding / hledání cest
|
||||
|
||||
Pathfinding řeší problém s agenty, kteří se chytají do pastí. Umožňuje jim naplánovat si cestu okolo konkávních oblastí i pomalu se měnících překážek. Není však užitečný v oblastech, které se často mění, a proto je kombinován se steering behaviors.
|
||||
|
||||
Pathfinding vnímá scénu jako graf, ve kterém hledá (obvykle nejkratší) cestu.
|
||||
|
||||
**Opakování [Grafových problémů](../../szb/grafove-problemy/)**
|
||||
|
||||
- **Graf $G$**\
|
||||
Dvojice $(V, E)$, kde $V$ je množina uzlů a $E$ je množina hran mezi nimi.
|
||||
- **Orientovaný / directed graf**\
|
||||
Záleží na směru hran.
|
||||
- **Neorientovaný / undirected graf**\
|
||||
Na směru hran nezáleží.
|
||||
- **Vážený / weighted graf**\
|
||||
Hrany mají cenu / váhu.
|
||||
- **Breadth-first search / prohledávání do šířky (BFS)**\
|
||||
Prouzkoumává nejprve uzly v okolí počátečního uzlu, pak teprve uzly v okolí těchto uzlů, atd.
|
||||
- **Depth-first search / prohledávání do hloubky (DFS)**\
|
||||
Prozkoumej jednoho souseda, pak jeho souseda, pak souseda toho souseda atd. dokud jsi tak hluboko, že nemáš kam jít. Pak se teprve vynoř o úroveň výš a zkus prozkoumat jiného souseda.
|
||||
- **Shortest path algorithms / algoritmy pro nejkratší cestu**\
|
||||
Hledají nejkratší cestu mezi dvěma uzly. Používají nějakou heuristiku $f$ pro výběr dalšího uzlu k prozkoumání.
|
||||
- **Dijkstra’s algorithm / Dijkstrův algoritmus**\
|
||||
Podobný BFS, ale snaží se najít nejkratší cestu, ne nutně prozkoumat celý graf. Hranám přiřazuje cenu a vybírá ty s nejnižší cenou -- $f$ je nejnižší vzdálenost od počátečního uzlu.
|
||||
|
||||
### A\* algoritmus
|
||||
|
||||
Podobný Dijkstrovu algoritmu, ale navíc se snaží odhadnout, který směr je nejlepší. Používá heuristiku $h$ pro výběr dalšího uzlu k prozkoumání. Kombinuje Dijsktrův algoritmus s greedy best-first hledáním. [astar](#astar)
|
||||
|
||||
**A\* algoritmus [astar](#astar)**
|
||||
|
||||

|
||||
|
||||
```csharp
|
||||
record Node
|
||||
{
|
||||
Vector3 Position;
|
||||
List<Node> Neighbors = new();
|
||||
|
||||
// NB: We keep both scores because the heuristic is not guaranteed to be consistent.
|
||||
float GScore = float.Infinity; // Distance from start
|
||||
float FScore = float.Infinity; // Distance from start + heuristic
|
||||
Node? CameFrom = null;
|
||||
}
|
||||
|
||||
// NB: Assumes all nodes are initialized as above.
|
||||
List<Node> AStar(Node start, Node goal) {
|
||||
var toVisit = new PriorityQueue<Node, float>();
|
||||
start.GScore = 0;
|
||||
start.FScore = 0;
|
||||
toVisit.Enqueue(start, 0);
|
||||
|
||||
Node current = start;
|
||||
while (current != goal) {
|
||||
var (current, gCurrent) = toVisit.Dequeue();
|
||||
|
||||
foreach (var neighbor in current.Neighbors) {
|
||||
var gNeighbor = gCurrent + Distance(current, neighbor);
|
||||
if (gNeighbor < neighbor.GScore) {
|
||||
neighbor.GScore = gNeighbor;
|
||||
}
|
||||
|
||||
var fNeighbor = neighbor.GScore + Heuristic(neighbor, goal);
|
||||
if (fNeighbor < neighbor.FScore) {
|
||||
neighbor.FScore = fNeighbor;
|
||||
neighbor.CameFrom = current;
|
||||
toVisit.Enqueue(neighbor, fNeighbor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
float Heuristic(Node a, Node b) {
|
||||
// Example: Euclidean distance
|
||||
return Vector3.Distance(a.Position, b.Position);
|
||||
}
|
||||
```
|
||||
|
||||
Nejkratší cestu lze pak zrekonstruovat takto:
|
||||
|
||||
```csharp
|
||||
List<Node> ReconstructPath(Node goal) {
|
||||
var path = new List<Node> { goal };
|
||||
var current = goal;
|
||||
while (current.CameFrom is not null) {
|
||||
current = current.CameFrom
|
||||
path.Add(current);
|
||||
}
|
||||
path.Reverse();
|
||||
return path;
|
||||
}
|
||||
```
|
||||
|
||||
- **Datové struktury pro A\***
|
||||
A\* vyžaduje priority queue, která umí rychle vybírat prvek s nejnižší prioritou. Nejjednodušší je implementovat ji pomocí binární haldy. Pokud je však prohledávání na velmi velkém grafu (millions of nodes), lze pro urychlení použít například Bucketed Priority Queue (PBQ). Ta rozdělí uzly do bucketů podle jejich priority - buckety jsou seřazené, ale jejich obsah ne. Pro velký počet uzlů může být PBQ rychlejší díky menšímu počtu operací s pamětí.
|
||||
|
||||
- **Volba heuristiky**
|
||||
|
||||
- Čím přesnější bude odhad vzdálenosti k cíli, tím rychlejší A\* bude.
|
||||
- Pokud heuristika **podceňuje** vzdálenost k cíli, bude algoritmus pomalejší.
|
||||
- Pokud heuristika **přeceňuje** vzdálenost k cíli, algoritmus nemusí najít nejkratší cestu.
|
||||
- Heuristika je _admissible_ pokud nepřeceňuje.
|
||||
|
||||
- **Heuristika -- Euklidovská vzdálenost**\
|
||||
Poskytuje poměrně přesný nebo podceněný odhad vzdálenosti k cíli. Funguje dobře v exteriérech, ale v interiérech dává kvůli stěnám a dalším překážkám silně podhodnocené odhady. [pa217](#pa217)
|
||||
|
||||

|
||||
|
||||
- **Clusterová (shluková) heuristika**
|
||||
|
||||
- Shlukuje uzly blízko sebe (např. v rámci místnosti).
|
||||
- V rámci clusteru aplikuje Euklidovskou vzdálenost.
|
||||
- Pro vzdálenosti mezi clustery si udržuje look-up table (LUT).
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
- **D** algoritmus*\
|
||||
Varianta A*, která se umí vyrovnat s dynamickými změnami v grafu.
|
||||
- **Iterative Deepening A** (IDA*)*\
|
||||
Depth-first search s heuristikou. Iterative deepening znamená, že se postupně zvyšuje maximální hloubka prohledávání. [ida-star](#ida-star)
|
||||
- **Simplified Memory Bounded A** (SMA*)*\
|
||||
A\* co má nižší paměťové nároky.
|
||||
|
||||
### Reprezentace herního světa
|
||||
|
||||
Agenti nevidí herní svět stejně jako hráči, vidí ho spíš jako graf s uzly a hranami.
|
||||
|
||||
- **Division scheme**\
|
||||
Popisuje, jak je level rozdělen na uzly a hrany. Má vlastnosti:
|
||||
|
||||
- _Kvantizace_: metoda převodu pozice na uzel.
|
||||
- _Lokalizace_: metoda převodu uzlu na pozici.
|
||||
- _Generace_: metoda vytvoření uzlů a hran. Může být manuální (třeba Dirichletovy domény) nebo automatická (třeba Visibility points).
|
||||
- _Validita_: všechny uzly, mezi kterými je cesta, musí být vzájemně dosažitelné ve hře.
|
||||
|
||||
- **Tile-based / dlaždicové**\
|
||||
Některé hry, např real-time strategie (RTS), mají svět rozdělen do čtvercových / hexagonálních dlaždic. Díky tomu je jednoduché je převést na graf, neboť co dlaždice to uzel.
|
||||
|
||||
**Sid Meier’s Civilization V [civ5](#civ5)**
|
||||
|
||||

|
||||
|
||||
- **Dirichletova doména / Voronoiův diagram**\
|
||||
Level designer určí _charakteristické body_. Vytvořené regiony jsou složeny z bodů nejbližších danému charakteristickému bodu.
|
||||
|
||||
**20 points and their Voronoi cells by [Balu Ertl](https://commons.wikimedia.org/w/index.php?curid=38534275)**
|
||||
|
||||

|
||||
|
||||
- **Points of visibility**\
|
||||
Je automatická metoda generování charakteristických bodů (typicky pro generování Voronoiova diagramu). Generuje je v místech, kde se geometrie levelu mění z konvexní na konkávní a naopak (např. v rozích místností). Posouvá je o šířku hráče.
|
||||
|
||||
V praxi může generovat příliš mnoho bodů, ale může sloužit jako užitečný základ pro manuální úpravy.
|
||||
|
||||
**Points of visibility [ai-for-games](#ai-for-games)**
|
||||
|
||||

|
||||
|
||||
- **Navmesh / navigation mesh / navigační sítě**\
|
||||
Populární technika, kdy level designer popíše podlahové polygony. Agenti mohou chodit kamkoliv v rámci těchto polygonů a přecházet mezi těmi, které jsou spojené. Využívá geometrii už přítomnou v levelu nebo svoji vlastní.
|
||||
|
||||
**Navigation System in Unity [navmesh](#navmesh)**
|
||||
|
||||

|
||||
|
||||
**Polygonal mesh graph [ai-for-games](#ai-for-games)**
|
||||
|
||||

|
||||
|
||||
### Hierarchické hledání cest
|
||||
|
||||
> Nejdřív najde cestu mezi domy, pak teprve cestu od vchodových dveří k ledničce.
|
||||
|
||||
Nejprve hledá cestu na vysoké úrovni (mezi clustery), pak v rámci clusteru.
|
||||
|
||||
**❗ IMPORTANT**\
|
||||
Výhodou je, že zrychluje hledání cest.
|
||||
|
||||
Nevýhodou je, že vzdálenost mezi clustery se blbě měří, protože hráč do něj mohl vstoupit z různých míst. V praxi se používá třeba:
|
||||
|
||||
- nejkratší vzdálenost,
|
||||
- nejdelší vzdálenost,
|
||||
- průměrná minimální vzdálenost.
|
||||
|
||||
## Rozhodování
|
||||
|
||||
Agenti obvykle musí činit rozhodnutí ohledně toho, co budou dělat dál: zaútočit, ukrýt se, prchat, atd.
|
||||
|
||||
### Decision trees / rozhodovací stromy
|
||||
|
||||
Rozhodnutí jsou reprezentována jako strom. Vniřní uzly jsou podmínky, listy jsou akce, hrany reprezentují možnosti. Rozhodovací proces začíná u kořene a postupuje dolů stromem, dokud nenarazí na list -- ta akce se následně provede.
|
||||
|
||||
**Průchod rozhodovacím stromem [ai-for-games](#ai-for-games)**
|
||||
|
||||

|
||||
|
||||
### State machines / stavové automaty
|
||||
|
||||
Reprezentuje aktuální chování agenta pomocí stavů ve stavovém automatu. Každý stav zahrnuje nějaké akce. Přechody mezi stavy jsou spojeny s podmínkami a akcemi.
|
||||
|
||||
**State machine [ai-for-games](#ai-for-games)**
|
||||
|
||||

|
||||
|
||||
- **Hierarchické stavové automaty**\
|
||||
Stavy mohou obsahovat celé další stavové automaty. To umožňuje rozdělit chování agenta na části.
|
||||
|
||||
**Hierarchical state machine [ai-for-games](#ai-for-games)**
|
||||
|
||||

|
||||
|
||||
- **Stavový automat s rozhodovacími stromy v přechodech**\
|
||||
V přechodech mezi stavy jsou decision trees. Listy jsou další stavy.
|
||||
|
||||
**State machine with decision tree transitions [ai-for-games](#ai-for-games)**
|
||||
|
||||

|
||||
|
||||
### Behavior trees / stromy chování
|
||||
|
||||
- Návrhový vzor používáný v herním vývoji.
|
||||
- Je orientovaný na _úkoly_ (tasks) spíš než na _stav_ (state).
|
||||
- Kombinuje množství jiných technik.
|
||||
- Dá se vyrobit modulárně a znovupoužitelně.
|
||||
- Často pro něj existují i custom editory s GUI.
|
||||
|
||||
**Behavior tree [ai-for-games](#ai-for-games)**
|
||||
|
||||

|
||||
|
||||
**Parallel behavior tree [pa217](#pa217)**
|
||||
|
||||

|
||||
|
||||
- **Listy**
|
||||
- _Conditions_ (podmínky): vyhodnocují nějakou podmínku vůči postavě, hráči nebo hře. Mohou uspět nebo selhat.
|
||||
- _Actions_ (akce): mění stav hry, pouští animace, interagují s hráčem. Obvykle uspějí, ale mohou selhat (např. pokud jsou přerušeny).
|
||||
|
||||
- **Vnitřní uzly**
|
||||
- _Sequences_ (sekvence) $\to$: vykonávají své potomky po řadě, dokud _první_ **neselže**. Uspěje jen pokud uspějí všichni. Je to takový `AND`.
|
||||
- _Selectors_ (selektory) $?$: vykonávají své potomky po řadě, dokud _první_ není **úspěšný**. Selže, pokud neuspěje žádný. Je to takový `OR`.
|
||||
- _Parallel sequence/selector_ $\rightrightarrows$ / $???$: pouští všechny potomky najednou. Vyhodnocení zůstavá stejné.
|
||||
|
||||
- **Decorator / dekorátor**\
|
||||
Obaluje nějaký uzel a mění jeho chování (např. inverze výsledku, opakování).
|
||||
- **Filtery**\
|
||||
Rozhodují, jestli akci provedou nebo ne, případně až po nějakém čase či s nějakou pravděpodobností. Např. nemusí být žádoucí, aby se agent pořád dokola snažil otevřít dveře.
|
||||
|
||||
### Cílem orientované chování
|
||||
|
||||
Charakter má své cíle a snaží se jich dosáhnout za pomoci mnoha různých akcí.
|
||||
|
||||
- Množina cílů, každý cíl má různou prioritu.
|
||||
- Množina akcí závyslích na stavu světa (např. podle oběktů v okolí).
|
||||
- Akce mohou být atomické (např. sněz jídlo) nebo složené (např. jdi do supermarketu, kup jídlo, vrať se domů, sněz jídlo).
|
||||
- Provedené akce ovlivňují cíle (např. když sníme jídlo, změní se priorita cíle "sníst jídlo" na 0).
|
||||
- Vybrání nejlepší akce není tak jednoduché.
|
||||
- Nejjednodušší je vybrat akci s nejvyšší prioritou. To ale může mít nevyžádané vedlejší efekty (např. mám žízeň, vypiju vodu, počůrám se, protože jsem měl i potřebu jít na záchod).
|
||||
- Můžeme určit celkovou nespokojenost na základě všech potřeb a vybrat akci, která ji nejvíce sníží. (Počůrání by zvýšilo nespokojenost, proto se charakter rozhodne jít první na záchod.)
|
||||
- Výběr akce by měl zohledňovat i délky jednotlivých akcí a jak se v průběhu času mění priority cílů.
|
||||
- Jednou akcí můžu znemožnit jinou. Proto je potřeba plánovat akce dopředu.
|
||||
|
||||
## Strategie a taktika
|
||||
|
||||
Řeší rozhodování při nedostatku informací, koordinaci více agentů, plánování, atd.
|
||||
|
||||
### Waypoints / navigační body
|
||||
|
||||
Waypoint je pozice v levelu, která je něčím zajímavá.
|
||||
|
||||
- **Pathfinding nodes**\
|
||||
Místa kudy se dá projít.
|
||||
- **Tactical locations / rally points**\
|
||||
Místa kde se skrýt před útokem, místa ke snipení, místa pro ambush, atd. Do scény je může přidat přímo level designer nebo se mohou generovat automaticky.
|
||||
|
||||
**Tactical locations [ai-for-games](#ai-for-games)**
|
||||
|
||||

|
||||
|
||||
- **Context sensitive locations / závislost na kontextu**\
|
||||
Tactical locations mohou záviset na kontextu, třeba pozici protihráčů a jejich chování. Závislost na kontextu je implementována tak, že hodnota waypointu je předpočítána pro několik různých situací, či dodatečnou prací (např. ray castem) za běhu hry.
|
||||
- **Cover points**\
|
||||
Místa, kde se agent může schovat před nepřítelem. Kvalita je závyslá na množství a směru krytí a aktuální pozici nepřítele.
|
||||
- **Visibility points**\
|
||||
Místa s dobrým výhledem na důležité body v levelu. Visibility point může být zároveň i cover point, ale ne vždy.
|
||||
- **Shadow points**\
|
||||
Místa ve stínu.
|
||||
|
||||
### Taktická analýza
|
||||
|
||||
Vyskytuje se primárně ve real-time strategických (RTS) hrách.
|
||||
|
||||
- **Influence maps**
|
||||
|
||||
- Reprezentují aktuální vojenské působení agentů v dané oblasti.
|
||||
- Může být např. dán počtem jednotek a budov a jejich silou.
|
||||
- Upadá se vzdáleností od jednotek.
|
||||
- Používají se k určení toho, které oblasti jsou bezpečné a kterým je lepší se vyhnout, nebo kde jsou nepřátelské hranice nejslabší.
|
||||
- Pokud strana nemá všechny informace, můžeme vytvořit dvě influence mapy - každou pro jednoho hráče dle jemu dostupných informací.
|
||||
|
||||
**Influence map by [gamedev.net](https://www.gamedev.net/tutorials/programming/artificial-intelligence/the-core-mechanics-of-influence-mapping-r2799/)**
|
||||
|
||||

|
||||
|
||||
- **Terrain analyses**\
|
||||
Podobné waypointům ale pro vnější prostředí. Popisují, jak težké je daným terénem projít, jaká je na něm viditelnost, cover, možnost útect, potenciál ke snipení, atd.
|
||||
- **Frag-map**\
|
||||
Mapa, která obsahuje hodnoty zabití - pokud agent dostane hit, hodnota klesne, pokud zasáhne nepřítele hodnota stoupne. Dá se předpočátat offline při testování a poté adaptovat za běhu hry.
|
||||
- **Multi-layer analyses**\
|
||||
Informace v taktických analýzách lze rozdělit do tří kategorií:
|
||||
|
||||
- _Statické_: např. pozice budov, terén, atd. Dají se předpočítat.
|
||||
- _Vyvíjející se / evolving_: např. vojenský vliv, zdroje. Počítají se průběžně, ale analýzu lze přerušit.
|
||||
- _Dynamické_: např. urgentní nebezpečí, dynamické stíny. Počítají se ad hoc za běhu.
|
||||
|
||||
**Umístění radaru**
|
||||
|
||||
Zajímá nás:
|
||||
|
||||
- Bezpečnost lokace. _Nechceme, aby ho hned zničili._
|
||||
- Viditelnost lokace. _Čím viditelnější, tím lépší. Je to radar; chce vidět._
|
||||
- Vzdálenost od jiných radarů. _Nemá smysl je stavět blízko sebe._
|
||||
|
||||
Možné řešení:
|
||||
|
||||
```math
|
||||
\begin{aligned}
|
||||
|
||||
\text{Vhodnost} &= \text{Bezpečnost} \cdot \text{Viditelnost} \cdot \text{Vzdálenost}
|
||||
|
||||
\end{aligned}
|
||||
```
|
||||
|
||||
## Deskové hry
|
||||
|
||||
Typicky turn-based hry pro dva hráče, často s perfektní informací.
|
||||
|
||||
- **Perfect information**\
|
||||
Od začátku hry jsou známe všechny možnosti a jejich následky.
|
||||
- **Imperfect information**\
|
||||
Některé informace jsou skryté nebo náhodné, např. karty v ruce, hod kostkou.
|
||||
- **Zero-sum games**\
|
||||
Hra, kde výhra jednoho hráče je prohrou druhého (např. šachy).
|
||||
- **Non-zero-sum games**\
|
||||
Výhra jednoho hráče nemusí být prohra druhého, stejně tak prohra jednoho hráče nemusí být výhra druhého (např. kooperativní hry, prisoner’s dilemma).
|
||||
|
||||
### AI turn-based algoritmy
|
||||
|
||||
Algoritmy pro hledání nejlepšího tahu v tahových zero-sum deskových hrách pro dva hráče s perfektní informací.
|
||||
|
||||
- **Game tree**\
|
||||
Hru lze reprezentovat jako strom, kde uzly jsou stavy hry a hrany jednotlivé tahy. Listy jsou koncové stavy hry a mají hodnotu (výhru, prohru, remízu). Prohledáváním stromu lze najít nejlepší tah.
|
||||
|
||||
- Branching factor: dán počtem možných tahů v daném stavu.
|
||||
- Depth: počet tahů do konce hry.
|
||||
- Transposition: do některých stavů se dá dostat více cestami.
|
||||
|
||||
#### Minimax algoritmus
|
||||
|
||||
Projdi strom a vyber nejlepší možný tah pro nás s ohledem na to, že soupeř bude volit nejlepší tah pro sebe.
|
||||
|
||||
- Vybíráme nejlepší pozici pro nás - výběr maximální hodnoty.
|
||||
- Oponent vybírá nejhorší pozici pro nás - výběr minimální hodnoty.
|
||||
- Výběr se opakuje až do listu stromu - koncový stav s danou hodnotou. V případě, že nejsme schopní z časových důvodů prohledat celý strom, můžeme použít heuristiku pro ohodnocení nody (třeba počet a ohodnocení bílích figurek - černých figurek).
|
||||
- **Alpha-beta pruning**\
|
||||
Stromy pro hry jsou obvykle příliš velké na to, aby se daly prohledat celé (tic-tac-toe 9! stavů, šachy > 10^40 stavů). Zároveň ale nepotřebujeme prohledávat části, u kterých víme, že se určitě nestanou. Např. pokud najdeme v maxovi větev s hodnotou 5, nemusíme prohledávat podstrom mina, o kterém víme, že vybere menší hodnotu než 3. Této optimalizaci se říká _alpha-beta pruning_.
|
||||
|
||||
Minmax i alpha-beta pruning se chápe nejlíp s vizualizací. Můžete kouknout například na [Algorithms Explained – minimax and alpha-beta pruning](https://youtu.be/l-hh51ncgDI?feature=shared).
|
||||
|
||||
#### Monte Carlo prohledávání
|
||||
|
||||
- **Monte Carlo**\
|
||||
Město známé pro svá casina.
|
||||
- **Monte Carlo metoda**\
|
||||
Algoritmy a techniky spoléhající na náhodou, mega velké množiny vzorků a statistickou analýzu. [monte-carlo](#monte-carlo)
|
||||
|
||||
- **Monte Carlo tree search (MCTS)**\
|
||||
Heuristický algoritmus pro prohledávání stromových grafů. V kontextu deskových her se používá pro hledání nejlepšího tahu.[mcts](#mcts)
|
||||
|
||||
1. _Selection_: vyber uzel reprezentující stav hry, ze kterého ještě hra neskončila.
|
||||
2. _Expansion_: vytvoř možné volby ze zvoleného tahu.
|
||||
3. _Simulation_: vyber volbu náhodně a odsimuluj hru až do konce.
|
||||
4. _Backpropagation_: aktualizuj statistiky v uzlech na cestě od kořene k listu.
|
||||
|
||||
**Step of Monte Carlo tree search by [Rmoss92](https://commons.wikimedia.org/w/index.php?curid=88889583)**
|
||||
|
||||

|
||||
|
||||
- **Tree boundary**\
|
||||
Metoda (policy), kdy v uzlech nad _MCTS tree boundary_ jsou akce voleny inteligentně. Pod touto hranicí jsou akce voleny náhodně.
|
||||
- **Upper confidence bound (UCT)**\
|
||||
Metrika pro volbu nejlepšího uzlu.
|
||||
|
||||
```math
|
||||
\text{UCT} = \overline{X_j} + C \sqrt{\frac{\ln n}{n_j}}
|
||||
```
|
||||
|
||||
kde:
|
||||
|
||||
- $\overline{X_j}$ je střední hodnota odměny z akce v uzlu $j$. Může být třeba počet výher / počet her.
|
||||
- $C$ je _exploration parameter_, který určuje, jak moc se má algoritmus zaměřovat na prozkoumávání nových uzlů.
|
||||
- $n$ je počet her, ve kterých byl zvolen rodičovský uzel.
|
||||
- $n_j$ je počet her, ve kterých byl zvolen uzel $j$.
|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[pa217, 1]]] PA217 AI for Games
|
||||
- [[[ai-for-games, 2]]] Ian Millington, John Funge: Artificial Intelligence for Games
|
||||
- [[[steering, 3]]] [Steering Behaviors](https://slsdo.github.io/steering-behaviors/)
|
||||
- [[[navmesh, 4]]] [Navigation System in Unity](https://docs.unity3d.com/Manual/nav-NavigationSystem.html)
|
||||
- [[[astar, 5]]] [Introduction to the A\* Algorithm](https://www.redblobgames.com/pathfinding/a-star/introduction.html)
|
||||
- [[[civ5, 6]]] [Sid Meier’s Civilization V](https://store.steampowered.com/app/8930/Sid_Meiers_Civilization_V/)
|
||||
- [[[monte-carlo, 7]]] [Wikipedia: Monte Carlo method](https://en.wikipedia.org/wiki/Monte_Carlo_method)
|
||||
- [[[mcts, 8]]] [Wikipedia: Monte Carlo tree search](https://en.wikipedia.org/wiki/Monte_Carlo_tree_search)
|
||||
- [[[ida-star, 9]]] [Wikipedia: Iterative deepening A\*](https://en.wikipedia.org/wiki/Iterative_deepening_A*)
|
337
src/content/docs/szmgr/VPH07_gpu_rendering.md
Normal file
337
src/content/docs/szmgr/VPH07_gpu_rendering.md
Normal file
@ -0,0 +1,337 @@
|
||||
---
|
||||
title: "Renderování s využitím GPU (2023)"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
**⚠️ WARNING**\
|
||||
Tato otázka zatím nebyla aktualizována. Nová varze obsahuje pár termínů navíc!
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
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_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
- **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.
|
||||
|
||||
**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](../modelovani-a-projekce/).
|
||||
|
||||
**Coordinate Systems [coordinate-systems](#coordinate-systems)**
|
||||
|
||||

|
||||
|
||||
- **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: [sw-coordinates](#sw-coordinates)
|
||||
|
||||
| Editor |
|
||||
| ------------ |
|
||||
| Handedness |
|
||||
| $X$ |
|
||||
| $Y$ |
|
||||
| $Z$ |
|
||||
| _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 ($M$). 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 ($V$) 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 ($P$). Ta nám umožňuje objekt nejen posunout ale i otočit a změnit jeho měřítko. [coordinate-systems](#coordinate-systems)
|
||||
|
||||
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í $w$).
|
||||
|
||||
V OpenGL je to kostka $x \in (-1.0, 1.0), y \in (-1.0, 1.0), z \in (-1.0, 1.0)$.
|
||||
|
||||
- **Window / viewport space**\
|
||||
Má velikost danou rozlišením okna a `glDepthRange`. Ve _výchozím nastavení_ je to $x \in (0, width), y \in (0, height), z \in (0, 1)$.
|
||||
|
||||
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 $(0, 0)$. [viewport](#viewport)
|
||||
|
||||
- **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 $Z$ použitím projekční matice ($P$). [coordinate-systems](#coordinate-systems) V OpenGL tedy platí:
|
||||
|
||||
| Space |
|
||||
| ---------------------- | ------- | ------ | -------------------------- | -------- |
|
||||
| Handedness | $X$ | $Y$ | $Z$ | _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_ |
|
||||
|
||||
**💡 TIP**\
|
||||
Fun-fact: ve Vulkanu je NDC $x \in (-1.0, 1.0), y \in (-1.0, 1.0), z \in (\textcolor{red}{0.0}, 1.0)$. A navíc je **right-handed**, takže souřadnice $(-1.0, -1.0, 0.0)$ je vlevo **nahoře**, kdežto v OpenGL je vlevo **dole**. [vulkan-coords](#vulkan-coords)
|
||||
|
||||
## Pipeline (typy shaderů)
|
||||
|
||||
Při zvolání `glDraw*` se používá OpenGL pipeline, která se skládá z několika fází: [pipeline](#pipeline)
|
||||
|
||||
**Diagram of the Rendering Pipeline [pipeline](#pipeline)**
|
||||
|
||||

|
||||
|
||||
- **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ě: [post-process](#post-process)
|
||||
|
||||
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:
|
||||
|
||||
```math
|
||||
(x_{ndc}, y_{ndc}, z_{ndc}) = \left( \frac{x_{clip}}{w_{clip}}, \frac{y_{clip}}{w_{clip}}, \frac{z_{clip}}{w_{clip}} \right)
|
||||
```
|
||||
|
||||
4. převede je do window / viewport space:
|
||||
|
||||
```cpp
|
||||
void glViewport(GLint x, GLint y, GLsizei width, GLsizei height);
|
||||
void glDepthRange(GLdouble nearVal, GLdouble farVal);
|
||||
void glDepthRangef(GLfloat nearVal, GLfloat farVal);
|
||||
```
|
||||
|
||||
```math
|
||||
\begin{pmatrix}
|
||||
x_{\textit{viewport}} \\
|
||||
y_{\textit{viewport}} \\
|
||||
z_{\textit{viewport}}
|
||||
\end{pmatrix}
|
||||
=
|
||||
\begin{pmatrix}
|
||||
\frac{\textit{width}}{2} \cdot x_{ndc} + x + \frac{\textit{width}}{2} \\
|
||||
\frac{\textit{height}}{2} \cdot y_{ndc} + y + \frac{\textit{height}}{2} \\
|
||||
\frac{\textit{farVal} - \textit{nearVal}}{2} \cdot z_{ndc} + \frac{\textit{farVal} + \textit{nearVal}}{2}
|
||||
\end{pmatrix}
|
||||
```
|
||||
|
||||
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](../pokrocila-pocitacova-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í.
|
||||
|
||||
**The Shadow Mapping Depth Comparison [shadow-maps](#shadow-maps)**
|
||||
|
||||

|
||||
|
||||
- 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
|
||||
|
||||
- **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. [pa010-2021](#pa010-2021)
|
||||
|
||||

|
||||
|
||||
- **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. [pa010-2021](#pa010-2021)
|
||||
|
||||
```math
|
||||
w_\text{penumbra} = \frac{p_z^s - z_\text{avg}}{z_\text{avg}} w_\text{light}
|
||||
```
|
||||
|
||||

|
||||
|
||||
## 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. [pv227](#pv227)
|
||||
|
||||
Tuto techniku použijeme např. když máme ve scéně fakt hodně světel.
|
||||
|
||||

|
||||
|
||||
<dl><dt><strong>❗ IMPORTANT</strong></dt><dd>
|
||||
|
||||
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.
|
||||
</dd></dl>
|
||||
|
||||
<dl><dt><strong>⚠️ WARNING</strong></dt><dd>
|
||||
|
||||
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.
|
||||
</dd></dl>
|
||||
|
||||
## 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ů.
|
||||
|
||||
**Aliasing [anti-aliasing](#anti-aliasing)**
|
||||
|
||||

|
||||
|
||||
- **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.
|
||||
|
||||
**MSAA [anti-aliasing](#anti-aliasing)**
|
||||
|
||||

|
||||
|
||||
### 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.
|
||||
|
||||
**[NVidia HBAO+](https://www.nvidia.com/en-gb/geforce/technologies/hbao-plus/technology/)**
|
||||
|
||||

|
||||
|
||||
- **Screen-Space Ambient Occlusion (SSAO)**\
|
||||
Dívá se na okolí daného pixelu (v G-bufferu) a odhaduje tak jeho okluzi.
|
||||
|
||||
**SSAO [ssao](#ssao)**
|
||||
|
||||

|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[pipeline,1]]] [Rendering Pipeline Overview](https://www.khronos.org/opengl/wiki/Rendering_Pipeline_Overview)
|
||||
- [[[post-process,2]]] [Vertex Post-Processing](https://www.khronos.org/opengl/wiki/Vertex_Post-Processing)
|
||||
- [[[coordinate-systems,3]]] [LearnOpenGL: Coordinate Systems](https://learnopengl.com/Getting-started/Coordinate-Systems)
|
||||
- [[[sw-coordinates,4]]] [Verge3D Wiki: Coordinate Systems](https://www.soft8soft.com/wiki/index.php/Coordinate_Systems)
|
||||
- [[[viewport,5]]] [`glViewport`](https://registry.khronos.org/OpenGL-Refpages/gl4/html/glViewport.xhtml)
|
||||
- [[[depth-range,6]]] [`glDepthRange`](https://registry.khronos.org/OpenGL-Refpages/gl4/html/glDepthRange.xhtml)
|
||||
- [[[vulkan-coords,7]]] [Vulkan’s coordinate system](http://anki3d.org/vulkan-coordinate-system/)
|
||||
- [[[pv227,8]]] [PV227 GPU Rendering (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PV227/)
|
||||
- [[[anti-aliasing,9]]] [LearnOpenGL: Anti-Aliasing](https://learnopengl.com/Advanced-OpenGL/Anti-Aliasing)
|
||||
- [[[ambient-occlusion,10]]] [Wikipedia: Ambient occlusion](https://en.wikipedia.org/wiki/Ambient_occlusion)
|
||||
- [[[ssao,11]]] [LearnOpenGL: SSAO](https://learnopengl.com/Advanced-Lighting/SSAO)
|
||||
- [[[shadow-maps,12]]] [The Cg Tutorial: Shadow Mapping](https://developer.download.nvidia.com/CgTutorial/cg_tutorial_chapter09.html)
|
||||
- [[[pa010-2021,13]]] Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021)
|
||||
|
||||
## Další zdroje
|
||||
|
||||
- [Is OpenGL coordinate system left-handed or right-handed?](https://stackoverflow.com/questions/4124041/is-opengl-coordinate-system-left-handed-or-right-handed)
|
||||
- [Cascaded Shadow Maps](https://learn.microsoft.com/en-us/windows/win32/dxtecharts/cascaded-shadow-maps)
|
||||
- [Common Techniques to Improve Shadow Depth Maps](https://learn.microsoft.com/en-us/windows/win32/dxtecharts/common-techniques-to-improve-shadow-depth-maps)
|
190
src/content/docs/szmgr/VPH08_modelovani_3d_postav.md
Normal file
190
src/content/docs/szmgr/VPH08_modelovani_3d_postav.md
Normal file
@ -0,0 +1,190 @@
|
||||
---
|
||||
title: "Modelování 3D postav (2023)"
|
||||
description: "TODO"
|
||||
---
|
||||
|
||||
**⚠️ WARNING**\
|
||||
Tato otázka zatím nebyla aktualizována. Nová varze obsahuje pár věcí navíc!
|
||||
|
||||
<dl><dt><strong>📌 NOTE</strong></dt><dd>
|
||||
|
||||
Avatar, postava, model. Modelování mnohoúhelníkových sítí (high-poly, low-poly), topologie a modifikace těchto sítí, tvorba textur (maps baking). Kostra modelu a potažení kostry (rigging, skinning).
|
||||
|
||||
_VV035, VV036_
|
||||
|
||||
</dd></dl>
|
||||
|
||||
- **Model**\
|
||||
Model je komplikované slovo s mnoha významy:
|
||||
|
||||
> **model**, noun
|
||||
>
|
||||
> 1. a usually miniature representation of something\
|
||||
> **also**: a pattern of something to be made
|
||||
> 2. **a**: a type or design of product (such as a car)\
|
||||
> **b**: a type or design of clothing
|
||||
> 3. a system of postulates, data, and inferences presented as a mathematical description of an entity or state of affairs\
|
||||
> **also**: a computer simulation based on such a system
|
||||
> 4. archetype
|
||||
> 5. an example for imitation or emulation
|
||||
> 6. one who is employed to display clothes or other merchandise
|
||||
> 7. a person or thing that serves as a pattern for an artist\
|
||||
> **especially**: one who poses for an artist
|
||||
> 8. version
|
||||
> 9. a description or analogy used to help visualize something (such as an atom) that cannot be directly observed
|
||||
> 10. structural design
|
||||
> 11. an organism whose appearance a mimic imitates
|
||||
> 12. animal model
|
||||
> 13. (dialectal british): copy, image
|
||||
> 14. (obsolete): a set of plans for a building
|
||||
>
|
||||
> — Mirriam-Webster
|
||||
|
||||
Nicméně v kontextu modelování 3D postav je model soubor (např. ve formátu `.fbx`, `.obj` či `.blend`) obsahující mesh. Nejblíže má tím pádem významu č. 1.
|
||||
|
||||
- **Character / postava**\
|
||||
Fiktivní osoba či jiná bytost. Typicky má nějaký background -- příběh, rysy osobnosti, vzhled, dovednosti, apod. V herních kontextech rozlišuje player character (PC) a non-player character (NPC).
|
||||
|
||||
Vývojáři často zaměňují "postava" a "model".
|
||||
|
||||
- **Avatar**\
|
||||
Grafická reprezentace uživatele či uživatelovy postavy. [avatar](#avatar) Ve hrách je typicky implementován skrze 3D mesh (obsažený v modelu) či 2D sprite obohacený o animace, collidery, apod.
|
||||
|
||||
## Mnohoúhelníkové sítě
|
||||
|
||||
- **Polygon**\
|
||||
Mnohoúhelník.
|
||||
- **(Polygon) mesh**\
|
||||
Mnohoúhelníková síť.
|
||||
- **High-poly mesh**\
|
||||
Model s velkým množstvím polygonů. Typicky se jedná o model, který je určen např. pro pre-renderované cutscény a nikoliv pro hraní.
|
||||
|
||||
Bývájí výsledkem **sculptingu** v programech jako je ZBrush či Mudbox.
|
||||
|
||||
**Arachnid humanoid bust by [Alexander Tobler](https://yeaaa.artstation.com/projects/zRW1L)**
|
||||
|
||||

|
||||
|
||||
- **Low-poly mesh**\
|
||||
Model s malým množstvím polygonů. Typicky se jedná o model, který je vložen do hry a je tedy výhodné, aby bylo co možná nejjednodušší jen vykreslit.
|
||||
|
||||
**Triceratops by [Base Mesh Store](https://www.artstation.com/artwork/EVzXO4)**
|
||||
|
||||

|
||||
|
||||
- **Low-poly stylizace**\
|
||||
Stylizace, kdy je model záměrně vytvořen s nízkým množstvím polygonů, protože to vypadá cool. Je to taková _skoro_ 3D analogie pixelartu.
|
||||
|
||||
**Low Poly Worlds by [Pavel Novák](https://www.behance.net/gallery/89934319/Low-Poly-Worlds/modules/521713751)**
|
||||
|
||||

|
||||
|
||||
## Topologie a modifikace
|
||||
|
||||
**💡 TIP**\
|
||||
Pro základní topologické pojmy viz [3D modelování a datové struktury](../3d-modelovani-a-datove-struktury/).
|
||||
|
||||
- **Meshflow**\
|
||||
Logické uspořádání hran a polygonů v mnohoúhelníkové síti.
|
||||
|
||||
**📌 NOTE**\
|
||||
Nepovedlo se mi tenhle termín najít jinde než ve slidech pro VV035/VV036. Zdá se mi, že je to v zásadě synononymum pro _topologii_.
|
||||
|
||||
- **Quad topologie**\
|
||||
Při modelování (nejen postav) se snažíme, aby všechny polygony byly quady (čtyřúhelníky). Je to zejména proto, že subdivision na nich funguje lépe, a _3D artisti_ dokáží lépe odhadnout, co se s nimi při takových operacích stane.
|
||||
- **Organic modeling**\
|
||||
Při modelování postav většinou vycházíme z nějaké anatomie z reálného světa. Snažíme se vyjít z toho, jak jsou v reálném světě kosti, svaly, apod. umístěny. V důsledku toho je například důležité mít edge loops okolo ramen, úst, a boků. [vv036-2023](#vv036-2023)
|
||||
|
||||
Nejde jen o to vyrobit anatomicky věrný model, ale i o to, aby se model dobře rigoval a animoval. Správná topologie přispívá k tomu, aby se model plynule deformoval při animaci, aniž by se některé části modelu pohybovaly nerealisticky a rozbily _imerzi_.
|
||||
|
||||
**Flowing edge loops and good topology are crucial for rigging and animation [organic](#organic)**
|
||||
|
||||

|
||||
|
||||
- **Retopologie**\
|
||||
Postup, kdy začneme s high-poly modelem, který jsme nejspíš vysculptovali bez ohledu na topologii, a ručně / automaticky na něm postavíme nový low-poly model se správnou topologií. Tohle nám umožňuje se nejprve soustředit na to, co za model chceme, a pak teprve na jeho technické provedení. [vv036-2023](#vv036-2023)
|
||||
- **Box modeling**\
|
||||
Proces, kdy začneme od [default cube](https://www.youtube.com/watch?v=SDeVyxtdSUk), subdividneme ji a pokračujeme odtamtaď. [vv036-2023](#vv036-2023)
|
||||
- **Point to point modeling**\
|
||||
Začneme od jediného bodu / polygonu. Tahle metoda je užitečná, když očekáváme, že retopologie modelu bude náročná, jelikož nám dává větší kontrolu nad meshflow. [vv036-2023](#vv036-2023)
|
||||
|
||||
## Textury
|
||||
|
||||
Typický 3D model se skládá nejen z meshe, ale i z materiálů, které jsou v herních enginech typicky reprezentovány texturami (mapami).
|
||||
|
||||
**📌 NOTE**\
|
||||
Typy map souvisí s _physically based rendering_ (PBR), kterému se částečně věnuje otázka [Pokročilá počítačová grafika](../pokrocila-pocitacova-grafika/).
|
||||
|
||||
- **UV unwrapping**\
|
||||
Tvorba 2D reprezentace 3D modelu -- projekce jeho polygonů na 2D plochu. Toto mapování se posléze využívá při texturování. Proces zahrnuje označování _seams_ -- hran, podél kterých se bude model "rozřezávat". Nevhodná volba seams vede k deformaci textur.
|
||||
|
||||
**Result of unwrapping Suzanne [uv-unwrap](#uv-unwrap)**
|
||||
|
||||

|
||||
|
||||
- **Diffuse / albedo map**\
|
||||
Základní barva modelu.
|
||||
- **Detail map**\
|
||||
Detaily, které mají být na modelu vidět zblízka.
|
||||
- **Emissive / glow / incandescence / self-illumination map**\
|
||||
Jak moc model "svítí" ve tmě. Používané pro modely, na které není aplikováno osvětlení scény.
|
||||
- **Bump / displacement / height map**\
|
||||
Detaily na povrchu. Typicky se používá dohromady s teselací.
|
||||
- **Normal map**\
|
||||
Normála na povrchu každého pixelu. Má podobný efekt jako displacement mapa, ale není aplikovaná na vertexy.
|
||||
|
||||
**A normal mapped model, the mesh without the map, and the normal map alone (by [Eric Chadwick](https://ericchadwick.com/))**
|
||||
|
||||

|
||||
|
||||
- **Metallic / roughness map**\
|
||||
"Kovové" odlesky v daném místě modelu.
|
||||
- **Light map**\
|
||||
Zapečené statické osvětlení. Typicky se týká spíš celých scén než postav.
|
||||
- **Texture baking**\
|
||||
Proces přenosu detailů z (typicky high-poly) modelu na jiný (typicky low-poly) model. High-poly detaily jsou "zapečeny" do textur. Modelovací software typicky vrhá po modelu velké množství paprsků a výsledek ukládá do textur. [texture-baking](#texture-baking)
|
||||
|
||||
## Kostra modelu
|
||||
|
||||
- **Kostra / skeleton / rig**\
|
||||
Hierarchická struktura kostí (bones), jenž popisují, kde je možné model ohnout a animovat.
|
||||
|
||||
**Rig of Atlas from Portal 2 by Oliver Simmonet**
|
||||
|
||||

|
||||
|
||||
- **(Skeletal) rigging**\
|
||||
Proces tvorby kostry.
|
||||
|
||||
> Rigging is making our characters able to move. The process of rigging is we take that digital sculpture, and we start building the skeleton, the muscles, and we attach the skin to the character, and we also create a set of animation controls, which our animators use to push and pull the body around.
|
||||
>
|
||||
> — Josh Petty
|
||||
|
||||
- **Forward kinematics (FK)**\
|
||||
Animace se řetězí od parent kosti k child kosti. Pohneme-li rodičovskou kostí, pohnou se i její děcka. Klouby se hýbou po křivkách. [fk-ik](#fk-ik)
|
||||
- **Inverse kinematics (IK)**\
|
||||
Animujeme jen koncové kosti. Pohyb rodičovských kostí je dopočítán. Klouby se hýbou po přímkách. [fk-ik](#fk-ik)
|
||||
- **T-pose / reference pose**\
|
||||
Defaultní póza pro charakter při riggování.
|
||||
|
||||
**T-pose by [vkstudio](https://free3d.com/3d-model/male-body-base-mesh-in-3-poses-with-detailed-head-and-limbs-3060.html)**
|
||||
|
||||

|
||||
|
||||
- **Skinning**\
|
||||
Úprava kostry tak, aby se povrch modelu správně deformoval při animaci. [vv036-2023](#vv036-2023) Například v Blenderu se skinning dá provést automaticky nebo nastavením _envelopes_ -- objemů obsahujících ovlivněné vertexy -- a jejich vah.
|
||||
|
||||
## Zdroje
|
||||
|
||||
- [[[avatar,1]]] https://en.wikipedia.org/wiki/Avatar_(computing)
|
||||
- [[[vv036-2023,2]]] [VV036 3D Character Modeling (jaro 2023)](https://is.muni.cz/auth/el/fi/jaro2023/VV036/)
|
||||
- [[[quads,3]]] [Why are quads used in filmmaking and triangle in gaming?](https://computergraphics.stackexchange.com/questions/5465/why-are-quads-used-in-filmmaking-and-triangle-in-gaming)
|
||||
- [[[organic,4]]] [Tips and tricks for organic modelling](https://www.creativebloq.com/tips-and-tricks-organic-modelling-7123070)
|
||||
- [[[texture-baking,5]]] [Texture Baking](http://wiki.polycount.com/wiki/Texture_Baking)
|
||||
- [[[fk-ik,6]]] [FK and IK Explained - Which One to Use and When?](https://www.youtube.com/watch?v=0a9qIj7kwiA)
|
||||
- [[[envelopes,7]]] [Blender: Deform](https://docs.blender.org/manual/en/latest/animation/armatures/bones/properties/deform.html)
|
||||
- [[[uv-unwrap,8]]] [Blender: Unwrapping > Mapping Types](https://docs.blender.org/manual/en/2.79/editors/uv_image/uv/editing/unwrapping/mapping_types.html)
|
||||
|
||||
## Další zdroje
|
||||
|
||||
- [Moving and Manipulating Edge Poles](https://topologyguides.com/manipulating-edge-poles)
|
23
src/content/docs/szmgr/guidelines.md
Normal file
23
src/content/docs/szmgr/guidelines.md
Normal file
@ -0,0 +1,23 @@
|
||||
---
|
||||
title: Guidelines
|
||||
description: Guidelines for contributing notes
|
||||
---
|
||||
|
||||
Při psaní těchhle poznámek jsem se snažil (s proměnlivou mírou uspěšnosti) držet několika pravidel:
|
||||
|
||||
- **_Stopařův průvodce_ ne _Galaktická encyklopedie_**
|
||||
- Drž se formátu _heslo_ -> _stručný popis_.
|
||||
- Nepiš román.
|
||||
- Používej definition lists.
|
||||
- **Upřednosťnuj hesla ze zadání**\
|
||||
Nejprve popiš věci ze zadání a pak se teprve věnuj souvisejícím věcem.
|
||||
- **Zdůrazňuj překryvy**\
|
||||
Pokud se otázky někde překrývají zdůrazni to pomocí admonition. Nekopíruj obsah a neopakuj se.
|
||||
- **Zdroje**\
|
||||
Pokud je to možné, odkazuj na zdroje.
|
||||
- **Využívej možností Asciidocu**\
|
||||
Existují _example blocks_, _admonitions_, _code blocks_, atd. Využívej je, ať to není jenom nudný text.
|
||||
- **Obrázky**\
|
||||
Pokud se hodí, přidej obrázek. **Nevkládej ale jen screenshoty ze slidů.**
|
||||
- **Humor**\
|
||||
Pokud tě napadne vtipný ale srozumitelný způsob, jak něco napsat, použij ho.
|
89
src/content/docs/szmgr/index.md
Normal file
89
src/content/docs/szmgr/index.md
Normal file
@ -0,0 +1,89 @@
|
||||
---
|
||||
title: Magisterské státnice 2024
|
||||
description: "SZMGR"
|
||||
---
|
||||
|
||||
Poznámky k magisterským státnicím oboru _Vývoj počítačových her_ v červnu 2024. Otázky prošly mezi rokem 2023 a 2024 velkými změnami. Poznámky jsou z větší části aktualizované a přeorganizované podle státnic 2024, ale nejsou nutně kompletní, korektní ani nezaujaté, proto by vás mohly zajímat i následující zdroje:
|
||||
|
||||
- **Otázky**\
|
||||
[VIZI od 2018](https://www.fi.muni.cz/studies/fe-mgr/vizi2018.html)
|
||||
- **IV003 Algoritmy a datové struktury II**
|
||||
- [Jaro 2023](https://is.muni.cz/auth/el/fi/jaro2023/IV003/index.qwarp)
|
||||
- [Jaro 2021](https://is.muni.cz/auth/el/fi/jaro2021/IV003/index.qwarp)
|
||||
- **PA215 Game Design I**
|
||||
|
||||
- [Podzim 2022](https://is.muni.cz/auth/el/fi/podzim2022/PA215/index.qwarp)
|
||||
- [Podzim 2021](https://is.muni.cz/auth/el/fi/podzim2021/PA215/index.qwarp)
|
||||
- [Podzim 2019](https://is.muni.cz/auth/el/fi/podzim2019/PA215/um/)
|
||||
|
||||
**💡 TIP**\
|
||||
Odpovědi na některé podotázky jsou jen ve starších materiálech.
|
||||
|
||||
- **PA216 Game Design II**
|
||||
- [Jaro 2023](https://is.muni.cz/auth/el/fi/jaro2023/PA216/index.qwarp)
|
||||
- [Jaro 2020](https://is.muni.cz/auth/el/fi/jaro2020/PA216/index.qwarp)
|
||||
- **PV255 Game Development I**
|
||||
- [Podzim 2022](https://is.muni.cz/auth/el/fi/podzim2022/PV255/um/)
|
||||
- [2019 a starší](https://www.fi.muni.cz/~xchmeli1/PV255/materials.cgi)
|
||||
- **PA010 Intermediate Computer Graphics**
|
||||
- [Podzim 2020](https://is.muni.cz/auth/el/fi/podzim2020/PA010/)
|
||||
- **PA213 Advanced Computer Graphics**
|
||||
- [Jaro 2022](https://is.muni.cz/auth/el/fi/jaro2022/PA213/)
|
||||
- **VV035 3D Modeling**
|
||||
- [Podzim 2021](https://is.muni.cz/auth/el/fi/podzim2021/VV035/)
|
||||
- [Podzim 2020](https://is.muni.cz/auth/el/fi/podzim2020/VV035/)
|
||||
- [Materiály od @kiraacorsac](https://github.com/kiraacorsac/VV035-blender-study-materials)
|
||||
- **VV036 3D Character Modeling**
|
||||
- [Jaro 2023](https://is.muni.cz/auth/el/fi/jaro2023/VV036/)
|
||||
- [Tomáš Mádr: Tvorba herního charakteru](https://is.muni.cz/th/nsvk0/)
|
||||
- **PV227 GPU Rendering**
|
||||
- [Podzim 2022](https://is.muni.cz/auth/el/fi/podzim2022/PV227/)
|
||||
- **PA217 AI for Games**
|
||||
- [Jaro 2021](https://is.muni.cz/auth/el/fi/jaro2021/PA217/)
|
||||
- **PV021 Neural Networks**
|
||||
- [Podzim 2022](https://is.muni.cz/auth/el/fi/podzim2022/PV021/)
|
||||
- **IB000 Matematické základy informatiky**
|
||||
- [Podzim 2022](https://is.muni.cz/auth/el/fi/podzim2022/IB000/)
|
||||
- **IB002 Algoritmy a datové struktury I**
|
||||
- [Jaro 2020](https://is.muni.cz/auth/el/fi/jaro2020/IB002/)
|
||||
- **MA018 Numerical Methods**
|
||||
- [Podzim 2019](https://is.muni.cz/auth/el/fi/podzim2019/MA018/)
|
||||
- **PB130 Úvod do digitálního zpracování obrazu**
|
||||
- [Podzim 2022](https://is.muni.cz/auth/el/fi/podzim2022/PB130/)
|
||||
- **PV131 Digitální zpracování obrazu**
|
||||
- [Jaro 2023](https://is.muni.cz/auth/el/fi/jaro2023/PV131/)
|
||||
- **Státnicové poznámky ostatních**
|
||||
- [@xholubec, @megikej, @karelch, ...](https://hackmd.io/@fi-muni-viz-2022)
|
||||
- [Algoritmy a datové struktury](https://hackmd.io/7JoUfj1rQWO_0euDkWktQQ)
|
||||
- [Numerické metody](https://hackmd.io/@fi-muni-viz-2022/HkaIknlhF)
|
||||
- [Statistika](https://hackmd.io/_7a3hiIPR6Swq8rXUrijgw)
|
||||
- [3D modelování a datové struktury](https://hackmd.io/@fi-muni-viz-2022/H16Jenent)
|
||||
- [Křivky a povrchy](https://hackmd.io/@fi-muni-viz-2022/Hk94ehehF)
|
||||
- [Strojové učení](https://hackmd.io/Qh0d2P9iTbqli9ZcRMKK1g)
|
||||
- [Grafy a grafové algoritmy](https://hackmd.io/j26mWx8USFqA5Zcm9GFHCA)
|
||||
- [Modelování a projekce](https://hackmd.io/@fi-muni-viz-2022/Bkp5fnx2t)
|
||||
- [Zpracování rastrového obrazu](https://hackmd.io/@fi-muni-viz-2022/SywCznl2t)
|
||||
- [Analýza rastrového obrazu](https://hackmd.io/@fi-muni-viz-2022/ry_Q73l3K)
|
||||
- [Honza Polák](https://github.com/Darkyenus/FI-MUNI-VIZI/wiki/)
|
||||
- GDSTAT (Adam Šufliarsky, Jan Breburda)
|
||||
- [Pokročilá počítačová grafika](https://hackmd.io/@lulz/ry4djbfYc)
|
||||
- [Grafické a fyzikální principy](https://hackmd.io/@lulz/rJjkOSfK9)
|
||||
- [Herní design I](https://hackmd.io/@lulz/SJoinimt5)
|
||||
- [Herní design II](https://hackmd.io/@lulz/ByeK7HBd5)
|
||||
- [Vývoj her](https://hackmd.io/@lulz/BJlt7BB_5)
|
||||
- [Umělá inteligence v počítačových hrách](https://hackmd.io/@lulz/HybtXHHu9)
|
||||
- [Renderování s využitím GPU](https://hackmd.io/@lulz/B1IjhIGtq)
|
||||
- [Modelování 3D postav](https://hackmd.io/@lulz/SJvttrmK5)
|
||||
- **Další moje relevantní poznámky**
|
||||
- [PA010 Intermediate Computer Graphics](/pa010/)
|
||||
- [MV013 Statistics for Computer Science](/mv013/)
|
||||
- [IV003 Algoritmy a datové struktury II](/iv003/)
|
||||
- [PA217 AI for Games](/pa217/)
|
||||
- [PV021 Neural Networks](/pv021/)
|
||||
- [Bakalářské státnice 2020](/szb/)
|
||||
- **Meta**
|
||||
- [Guidelines pro psaní poznámek](./guidelines/)
|
||||
|
||||
---
|
||||
|
||||
**_NEPROPADEJTE PANICE_**
|
Loading…
Reference in New Issue
Block a user