From 5a259fe945426a4575d7a0b76a3bc0cf48728246 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20=C5=A0t=C4=9Bp=C3=A1nek?= Date: Sun, 20 Jul 2025 09:44:19 +0200 Subject: [PATCH 01/44] Change the file extension of every Asciidoc file in szmgr to preserve git history --- ...{PGV01_zaklady_vizualizace.ad => PGV01_zaklady_vizualizace.md} | 0 .../{PGV02_metody_vizualizace.ad => PGV02_metody_vizualizace.md} | 0 ...ocitatcove_grafiky.ad => PGV03_zaklady_pocitatcove_grafiky.md} | 0 ...04_geometricke_algoritmy.ad => PGV04_geometricke_algoritmy.md} | 0 ...eleni_prostoru_a_sceny.ad => PGV05_deleni_prostoru_a_sceny.md} | 0 ...ani_objemovych_dat.ad => PGV06_vykreslovani_objemovych_dat.md} | 0 szmgr/{PGV07_modely_osvetleni.ad => PGV07_modely_osvetleni.md} | 0 ...{PGV08_real_time_rendering.ad => PGV08_real_time_rendering.md} | 0 ...GV09_minimalizace_energie.ad => PGV09_minimalizace_energie.md} | 0 ...obrazu_pomoci_PDE.ad => PGV10_zpracovani_obrazu_pomoci_PDE.md} | 0 ..._zpracovani_obrazu_intro.ad => PGV_zpracovani_obrazu_intro.md} | 0 szmgr/{SZP01_algoritmy.ad => SZP01_algoritmy.md} | 0 szmgr/{SZP02_numericke_metody.ad => SZP02_numericke_metody.md} | 0 szmgr/{SZP03_statistika.ad => SZP03_statistika.md} | 0 szmgr/{SZP04_3d_modelovani.ad => SZP04_3d_modelovani.md} | 0 szmgr/{SZP05_krivky_a_povrchy.ad => SZP05_krivky_a_povrchy.md} | 0 szmgr/{SZP06_strojove_uceni.ad => SZP06_strojove_uceni.md} | 0 szmgr/{SZP07_grafy.ad => SZP07_grafy.md} | 0 ...08_modelovani_a_projekce.ad => SZP08_modelovani_a_projekce.md} | 0 szmgr/{SZP09_zpracovani_obrazu.ad => SZP09_zpracovani_obrazu.md} | 0 szmgr/{SZP10_analyza_obrazu.ad => SZP10_analyza_obrazu.md} | 0 ..._ve_vyvoji_her.ad => VPH01_graficke_principy_ve_vyvoji_her.md} | 0 szmgr/{VPH01_pokrocila_grafika.ad => VPH01_pokrocila_grafika.md} | 0 ...ve_vyvoji_her.ad => VPH02_fyzikalni_principy_ve_vyvoji_her.md} | 0 ...zikalni_principy.ad => VPH02_graficke_a_fyzikalni_principy.md} | 0 szmgr/{VPH03_herni_design_i.ad => VPH03_herni_design_i.md} | 0 szmgr/{VPH04_herni_design_ii.ad => VPH04_herni_design_ii.md} | 0 szmgr/{VPH05_vyvoj_her.ad => VPH05_vyvoj_her.md} | 0 szmgr/{VPH06_ai_ve_hrach.ad => VPH06_ai_ve_hrach.md} | 0 szmgr/{VPH07_gpu_rendering.ad => VPH07_gpu_rendering.md} | 0 ...PH08_modelovani_3d_postav.ad => VPH08_modelovani_3d_postav.md} | 0 szmgr/{guidelines.ad => guidelines.md} | 0 szmgr/{index.ad => index.md} | 0 33 files changed, 0 insertions(+), 0 deletions(-) rename szmgr/{PGV01_zaklady_vizualizace.ad => PGV01_zaklady_vizualizace.md} (100%) rename szmgr/{PGV02_metody_vizualizace.ad => PGV02_metody_vizualizace.md} (100%) rename szmgr/{PGV03_zaklady_pocitatcove_grafiky.ad => PGV03_zaklady_pocitatcove_grafiky.md} (100%) rename szmgr/{PGV04_geometricke_algoritmy.ad => PGV04_geometricke_algoritmy.md} (100%) rename szmgr/{PGV05_deleni_prostoru_a_sceny.ad => PGV05_deleni_prostoru_a_sceny.md} (100%) rename szmgr/{PGV06_vykreslovani_objemovych_dat.ad => PGV06_vykreslovani_objemovych_dat.md} (100%) rename szmgr/{PGV07_modely_osvetleni.ad => PGV07_modely_osvetleni.md} (100%) rename szmgr/{PGV08_real_time_rendering.ad => PGV08_real_time_rendering.md} (100%) rename szmgr/{PGV09_minimalizace_energie.ad => PGV09_minimalizace_energie.md} (100%) rename szmgr/{PGV10_zpracovani_obrazu_pomoci_PDE.ad => PGV10_zpracovani_obrazu_pomoci_PDE.md} (100%) rename szmgr/{PGV_zpracovani_obrazu_intro.ad => PGV_zpracovani_obrazu_intro.md} (100%) rename szmgr/{SZP01_algoritmy.ad => SZP01_algoritmy.md} (100%) rename szmgr/{SZP02_numericke_metody.ad => SZP02_numericke_metody.md} (100%) rename szmgr/{SZP03_statistika.ad => SZP03_statistika.md} (100%) rename szmgr/{SZP04_3d_modelovani.ad => SZP04_3d_modelovani.md} (100%) rename szmgr/{SZP05_krivky_a_povrchy.ad => SZP05_krivky_a_povrchy.md} (100%) rename szmgr/{SZP06_strojove_uceni.ad => SZP06_strojove_uceni.md} (100%) rename szmgr/{SZP07_grafy.ad => SZP07_grafy.md} (100%) rename szmgr/{SZP08_modelovani_a_projekce.ad => SZP08_modelovani_a_projekce.md} (100%) rename szmgr/{SZP09_zpracovani_obrazu.ad => SZP09_zpracovani_obrazu.md} (100%) rename szmgr/{SZP10_analyza_obrazu.ad => SZP10_analyza_obrazu.md} (100%) rename szmgr/{VPH01_graficke_principy_ve_vyvoji_her.ad => VPH01_graficke_principy_ve_vyvoji_her.md} (100%) rename szmgr/{VPH01_pokrocila_grafika.ad => VPH01_pokrocila_grafika.md} (100%) rename szmgr/{VPH02_fyzikalni_principy_ve_vyvoji_her.ad => VPH02_fyzikalni_principy_ve_vyvoji_her.md} (100%) rename szmgr/{VPH02_graficke_a_fyzikalni_principy.ad => VPH02_graficke_a_fyzikalni_principy.md} (100%) rename szmgr/{VPH03_herni_design_i.ad => VPH03_herni_design_i.md} (100%) rename szmgr/{VPH04_herni_design_ii.ad => VPH04_herni_design_ii.md} (100%) rename szmgr/{VPH05_vyvoj_her.ad => VPH05_vyvoj_her.md} (100%) rename szmgr/{VPH06_ai_ve_hrach.ad => VPH06_ai_ve_hrach.md} (100%) rename szmgr/{VPH07_gpu_rendering.ad => VPH07_gpu_rendering.md} (100%) rename szmgr/{VPH08_modelovani_3d_postav.ad => VPH08_modelovani_3d_postav.md} (100%) rename szmgr/{guidelines.ad => guidelines.md} (100%) rename szmgr/{index.ad => index.md} (100%) diff --git a/szmgr/PGV01_zaklady_vizualizace.ad b/szmgr/PGV01_zaklady_vizualizace.md similarity index 100% rename from szmgr/PGV01_zaklady_vizualizace.ad rename to szmgr/PGV01_zaklady_vizualizace.md diff --git a/szmgr/PGV02_metody_vizualizace.ad b/szmgr/PGV02_metody_vizualizace.md similarity index 100% rename from szmgr/PGV02_metody_vizualizace.ad rename to szmgr/PGV02_metody_vizualizace.md diff --git a/szmgr/PGV03_zaklady_pocitatcove_grafiky.ad b/szmgr/PGV03_zaklady_pocitatcove_grafiky.md similarity index 100% rename from szmgr/PGV03_zaklady_pocitatcove_grafiky.ad rename to szmgr/PGV03_zaklady_pocitatcove_grafiky.md diff --git a/szmgr/PGV04_geometricke_algoritmy.ad b/szmgr/PGV04_geometricke_algoritmy.md similarity index 100% rename from szmgr/PGV04_geometricke_algoritmy.ad rename to szmgr/PGV04_geometricke_algoritmy.md diff --git a/szmgr/PGV05_deleni_prostoru_a_sceny.ad b/szmgr/PGV05_deleni_prostoru_a_sceny.md similarity index 100% rename from szmgr/PGV05_deleni_prostoru_a_sceny.ad rename to szmgr/PGV05_deleni_prostoru_a_sceny.md diff --git a/szmgr/PGV06_vykreslovani_objemovych_dat.ad b/szmgr/PGV06_vykreslovani_objemovych_dat.md similarity index 100% rename from szmgr/PGV06_vykreslovani_objemovych_dat.ad rename to szmgr/PGV06_vykreslovani_objemovych_dat.md diff --git a/szmgr/PGV07_modely_osvetleni.ad b/szmgr/PGV07_modely_osvetleni.md similarity index 100% rename from szmgr/PGV07_modely_osvetleni.ad rename to szmgr/PGV07_modely_osvetleni.md diff --git a/szmgr/PGV08_real_time_rendering.ad b/szmgr/PGV08_real_time_rendering.md similarity index 100% rename from szmgr/PGV08_real_time_rendering.ad rename to szmgr/PGV08_real_time_rendering.md diff --git a/szmgr/PGV09_minimalizace_energie.ad b/szmgr/PGV09_minimalizace_energie.md similarity index 100% rename from szmgr/PGV09_minimalizace_energie.ad rename to szmgr/PGV09_minimalizace_energie.md diff --git a/szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.ad b/szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md similarity index 100% rename from szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.ad rename to szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md diff --git a/szmgr/PGV_zpracovani_obrazu_intro.ad b/szmgr/PGV_zpracovani_obrazu_intro.md similarity index 100% rename from szmgr/PGV_zpracovani_obrazu_intro.ad rename to szmgr/PGV_zpracovani_obrazu_intro.md diff --git a/szmgr/SZP01_algoritmy.ad b/szmgr/SZP01_algoritmy.md similarity index 100% rename from szmgr/SZP01_algoritmy.ad rename to szmgr/SZP01_algoritmy.md diff --git a/szmgr/SZP02_numericke_metody.ad b/szmgr/SZP02_numericke_metody.md similarity index 100% rename from szmgr/SZP02_numericke_metody.ad rename to szmgr/SZP02_numericke_metody.md diff --git a/szmgr/SZP03_statistika.ad b/szmgr/SZP03_statistika.md similarity index 100% rename from szmgr/SZP03_statistika.ad rename to szmgr/SZP03_statistika.md diff --git a/szmgr/SZP04_3d_modelovani.ad b/szmgr/SZP04_3d_modelovani.md similarity index 100% rename from szmgr/SZP04_3d_modelovani.ad rename to szmgr/SZP04_3d_modelovani.md diff --git a/szmgr/SZP05_krivky_a_povrchy.ad b/szmgr/SZP05_krivky_a_povrchy.md similarity index 100% rename from szmgr/SZP05_krivky_a_povrchy.ad rename to szmgr/SZP05_krivky_a_povrchy.md diff --git a/szmgr/SZP06_strojove_uceni.ad b/szmgr/SZP06_strojove_uceni.md similarity index 100% rename from szmgr/SZP06_strojove_uceni.ad rename to szmgr/SZP06_strojove_uceni.md diff --git a/szmgr/SZP07_grafy.ad b/szmgr/SZP07_grafy.md similarity index 100% rename from szmgr/SZP07_grafy.ad rename to szmgr/SZP07_grafy.md diff --git a/szmgr/SZP08_modelovani_a_projekce.ad b/szmgr/SZP08_modelovani_a_projekce.md similarity index 100% rename from szmgr/SZP08_modelovani_a_projekce.ad rename to szmgr/SZP08_modelovani_a_projekce.md diff --git a/szmgr/SZP09_zpracovani_obrazu.ad b/szmgr/SZP09_zpracovani_obrazu.md similarity index 100% rename from szmgr/SZP09_zpracovani_obrazu.ad rename to szmgr/SZP09_zpracovani_obrazu.md diff --git a/szmgr/SZP10_analyza_obrazu.ad b/szmgr/SZP10_analyza_obrazu.md similarity index 100% rename from szmgr/SZP10_analyza_obrazu.ad rename to szmgr/SZP10_analyza_obrazu.md diff --git a/szmgr/VPH01_graficke_principy_ve_vyvoji_her.ad b/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md similarity index 100% rename from szmgr/VPH01_graficke_principy_ve_vyvoji_her.ad rename to szmgr/VPH01_graficke_principy_ve_vyvoji_her.md diff --git a/szmgr/VPH01_pokrocila_grafika.ad b/szmgr/VPH01_pokrocila_grafika.md similarity index 100% rename from szmgr/VPH01_pokrocila_grafika.ad rename to szmgr/VPH01_pokrocila_grafika.md diff --git a/szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.ad b/szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.md similarity index 100% rename from szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.ad rename to szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.md diff --git a/szmgr/VPH02_graficke_a_fyzikalni_principy.ad b/szmgr/VPH02_graficke_a_fyzikalni_principy.md similarity index 100% rename from szmgr/VPH02_graficke_a_fyzikalni_principy.ad rename to szmgr/VPH02_graficke_a_fyzikalni_principy.md diff --git a/szmgr/VPH03_herni_design_i.ad b/szmgr/VPH03_herni_design_i.md similarity index 100% rename from szmgr/VPH03_herni_design_i.ad rename to szmgr/VPH03_herni_design_i.md diff --git a/szmgr/VPH04_herni_design_ii.ad b/szmgr/VPH04_herni_design_ii.md similarity index 100% rename from szmgr/VPH04_herni_design_ii.ad rename to szmgr/VPH04_herni_design_ii.md diff --git a/szmgr/VPH05_vyvoj_her.ad b/szmgr/VPH05_vyvoj_her.md similarity index 100% rename from szmgr/VPH05_vyvoj_her.ad rename to szmgr/VPH05_vyvoj_her.md diff --git a/szmgr/VPH06_ai_ve_hrach.ad b/szmgr/VPH06_ai_ve_hrach.md similarity index 100% rename from szmgr/VPH06_ai_ve_hrach.ad rename to szmgr/VPH06_ai_ve_hrach.md diff --git a/szmgr/VPH07_gpu_rendering.ad b/szmgr/VPH07_gpu_rendering.md similarity index 100% rename from szmgr/VPH07_gpu_rendering.ad rename to szmgr/VPH07_gpu_rendering.md diff --git a/szmgr/VPH08_modelovani_3d_postav.ad b/szmgr/VPH08_modelovani_3d_postav.md similarity index 100% rename from szmgr/VPH08_modelovani_3d_postav.ad rename to szmgr/VPH08_modelovani_3d_postav.md diff --git a/szmgr/guidelines.ad b/szmgr/guidelines.md similarity index 100% rename from szmgr/guidelines.ad rename to szmgr/guidelines.md diff --git a/szmgr/index.ad b/szmgr/index.md similarity index 100% rename from szmgr/index.ad rename to szmgr/index.md From 14be274d5715cdb6082a3fb2190e888d99331587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Fri, 6 Jun 2025 22:32:10 +0200 Subject: [PATCH 02/44] Setup the docs framework I did various changes and updates, using the question 8 (modelovani a projekce) as my lab rat. It's a pretty good case, containing images, plenty of math, footnotes, everything. I now feel it looks pretty good, I'll try to import more content. --- index.md | 1 + szmgr.md | 6 + szmgr/SZP08_modelovani_a_projekce.md | 811 +++++++++++++-------------- 3 files changed, 394 insertions(+), 424 deletions(-) create mode 100644 szmgr.md diff --git a/index.md b/index.md index a97d99c..694c028 100644 --- a/index.md +++ b/index.md @@ -2,6 +2,7 @@ layout: layouts/standalone.tsx styles: [ main ] title: FI Notes +description: Notes (mostly in Czech) from the Faculty of Informatics of Masaryk University in Brno. --- Notes (mostly in Czech) from the [Faculty of Informatics of Masaryk University](https://www.fi.muni.cz/) in Brno. diff --git a/szmgr.md b/szmgr.md new file mode 100644 index 0000000..0940489 --- /dev/null +++ b/szmgr.md @@ -0,0 +1,6 @@ +--- +title: MGR State exam +description: A reference page in my new Starlight docs site. +--- + +# SZMGR \ No newline at end of file diff --git a/szmgr/SZP08_modelovani_a_projekce.md b/szmgr/SZP08_modelovani_a_projekce.md index ce9cf4e..efb9dba 100644 --- a/szmgr/SZP08_modelovani_a_projekce.md +++ b/szmgr/SZP08_modelovani_a_projekce.md @@ -1,118 +1,112 @@ -= Modelování a projekce -:url: ./modelovani-a-projekce/ -:page-group: szp -:page-order: SZP08 - -[NOTE] -==== -Homogenní souřadnice, modelovací, pohledová a projekční matice, perspektivní a ortografická projekce. Základní afinní transformace. - -_PV189, PV112_ -==== - -== Souřadnicové systémy - -Right-hand rule:: -Mnemotechnická pomůcka pro určení orientace os v kartézské soustavě souřadnic. Taky se používá pro určení směru vektorového součinu. -+ -image::./img/szp08_right_hand_rule.svg[Right-hand rule] -+ -TIP: Osa X je dána ukazováčkem, osa Y prostředníčkem, osa Z palcem. Pokud Y míří nahoru, pak ano, člověk si u toho může vykroutit ruku, ale alespoň si to zapamatuje. - -Kartézská soustava souřadnic:: -Right-handed systém definován třemi kolmými osami. Ve 2D jsou to stem:[x] a stem:[y]. Ve 3D jsou to stem:[x], stem:[y] a stem:[z]. Jsou na sebe v zájemně kolmé. Počátek je v bodě, kde se protínají všechny osy, označovaném jako stem:[0]. - -Homogenní souřadnice:: -Hack, kdy reprezentujeme souřadnici v 3D prostoru pomocí 4 čísel, abychom mohli zapsat translaci pomocí matice. Využívá se v projektivní geometrii, pro projekci 3D scén na 2D plochu. -+ -Převod z kartézských na homogenní souřadnice: stem:[(x, y, z) \to (x, y, z, 1)]. -+ -Převod z homogenních na kartézské souřadnice: stem:[(x, y, z, w) \to (\frac{x}{w}, \frac{y}{w}, \frac{z}{w})]. -+ -Body, kde stem:[w = 0] jsou body v nekonečnu. Využívá se pro popis pohybu k nekonečnu, který se v kartézských souřadnicích nedá popsat. - -== MVP matice - -IMPORTANT: Pro implementaci v OpenGL viz link:../renderovani-s-vyuzitim-gpu/[Renderování s využitím GPU]. - -WARNING: Při zápisu matic bacha na to, jestli jsou row-major nebo column-major. Třeba v OpenGL to znamená, že se všechny matice píší v transponované podobě, jelikož OpenGL je column-major a v takovém pořádí jsou i parametery `mat2`, `mat3` a `mat4` V GLSL. - -Modelová matice stem:[M]:: -Převádí souřadnice z prostoru objektu (local space) do prostoru světa (world space). Využívá se pro rotaci (stem:[R]), škálování (stem:[S]) a translaci (stem:[T]) objektu. -+ -[stem] -++++ -M = T \cdot R \cdot S -++++ - -Pohledová matice / view matrix stem:[V]:: -Převádí souřadnice z prostoru světa (world space) do prostoru před kamerou (camera space). _Otáčí světem, aby kamera byla jeho středem._ <> -+ -[stem] -++++ -V = \begin{bmatrix} - \color{red}{R_x} & \color{red}{R_y} & \color{red}{R_z} & 0 \\ - \color{green}{U_x} & \color{green}{U_y} & \color{green}{U_z} & 0 \\ - \color{blue}{D_x} & \color{blue}{D_y} & \color{blue}{D_z} & 0 \\ - 0 & 0 & 0 & 1 -\end{bmatrix} -\cdot -\begin{bmatrix} - 1 & 0 & 0 & -\color{purple}{P_x} \\ - 0 & 1 & 0 & -\color{purple}{P_y} \\ - 0 & 0 & 1 & -\color{purple}{P_z} \\ - 0 & 0 & 0 & 1 -\end{bmatrix} -++++ -+ -kde: -+ -* stem:[\color{red}{R}] je vektor, který ukazuje doprava od kamery. -* stem:[\color{green}{U}] je vektor, který ukazuje nahoru od kamery. -* stem:[\color{blue}{D}] je vektor, který ukazuje dopředu od kamery. -* stem:[\color{purple}{P}] je pozice kamery. -+ -NOTE: Všimni si, že levá matice je transponovaná a poziční vektor v pravé matici je negovaný. Je to proto, že otáčíme a posouváme celým světem tak, aby kamera byla v počátku, musíme proto provést inverzní operace vůči těm, které chceme provést s kamerou. <> +--- +title: 8. Modelování a projekce +description: A guide in my new Starlight docs site. +--- + +> [!NOTE] +> Homogenní souřadnice, modelovací, pohledová a projekční matice, perspektivní a ortografická projekce. Základní afinní transformace. +> +> _PV189, PV112_ + +## Souřadnicové systémy + +- **Right-hand rule** + Mnemotechnická pomůcka pro určení orientace os v kartézské soustavě souřadnic. Taky se používá pro určení směru vektorového součinu. + + ![Right-hand rule](./img/szp08_right_hand_rule.svg) + + > [!TIP] + > Osa X je dána ukazováčkem, osa Y prostředníčkem, osa Z palcem. Pokud Y míří nahoru, pak ano, člověk si u toho může vykroutit ruku, ale alespoň si to zapamatuje. + +- **Kartézská soustava souřadnic** + Right-handed systém definován třemi kolmými osami. Ve 2D jsou to $x$ a $y$. Ve 3D jsou to $x$, $y$ a $z$. Jsou na sebe v zájemně kolmé. Počátek je v bodě, kde se protínají všechny osy, označovaném jako $0$. +- **Homogenní souřadnice** + Hack, kdy reprezentujeme souřadnici v 3D prostoru pomocí 4 čísel, abychom mohli zapsat translaci pomocí matice. Využívá se v projektivní geometrii, pro projekci 3D scén na 2D plochu. + + Převod z kartézských na homogenní souřadnice: $(x, y, z) \to (x, y, z, 1)$. + + Převod z homogenních na kartézské souřadnice: $(x, y, z, w) \to (\frac{x}{w}, \frac{y}{w}, \frac{z}{w})$. + + Body, kde $w = 0$ jsou body v nekonečnu. Využívá se pro popis pohybu k nekonečnu, který se v kartézských souřadnicích nedá popsat. + +## MVP matice + +> [!IMPORTANT] +> Pro implementaci v OpenGL viz [Renderování s využitím GPU](../renderovani-s-vyuzitim-gpu/). + +> [!WARNING] +> Při zápisu matic bacha na to, jestli jsou row-major nebo column-major. Třeba v OpenGL to znamená, že se všechny matice píší v transponované podobě, jelikož OpenGL je column-major a v takovém pořádí jsou i parametery `mat2`, `mat3` a `mat4` V GLSL. + +- **Modelovací matice $M$** + Převádí souřadnice z prostoru objektu (local space) do prostoru světa (world space). Využívá se pro rotaci ($R$), škálování ($S$) a translaci ($T$) objektu. -Frustum:: -Část 3D tělesa (nejčastěji pyramidy nebo jehlanu) mezi dvěma rovnoběžnými rovinami. + ```math + M = T \cdot R \cdot S + ``` -Projekční matice / projection matrix stem:[P]:: -Převádí souřadnice z prostoru před kamerou (camera space) do clip space. -+ -Používá se zejména ortografická projekce (stem:[P_\text{ortho}]) a perspektivní projekce (stem:[P_\text{persp}]). +- **Pohledová matice / view matrix $V$**\ + Převádí souřadnice z prostoru světa (world space) do prostoru před kamerou (camera space). Otáčí světem, aby kamera byla jeho středem.[^camera] -MVP matice:: -Pro převod modelu z jeho lokálního prostoru do clip space použijeme: -+ -[stem] -++++ -\vec{v}_\text{clip} = P \cdot V \cdot M \cdot \vec{v}_\text{local} -++++ + ```math + V = \begin{bmatrix} + \color{red}{R_x} & \color{red}{R_y} & \color{red}{R_z} & 0 \\ + \color{green}{U_x} & \color{green}{U_y} & \color{green}{U_z} & 0 \\ + \color{blue}{D_x} & \color{blue}{D_y} & \color{blue}{D_z} & 0 \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + \cdot + \begin{bmatrix} + 1 & 0 & 0 & -\color{purple}{P_x} \\ + 0 & 1 & 0 & -\color{purple}{P_y} \\ + 0 & 0 & 1 & -\color{purple}{P_z} \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + ``` -== Projekce + kde: -=== Ortografická projekce + - $\color{red}{R}$ je vektor, který ukazuje doprava od kamery. + - $\color{green}{U}$ je vektor, který ukazuje nahoru od kamery. + - $\color{blue}{D}$ je vektor, který ukazuje dopředu od kamery. + - $\color{purple}{P}$ je pozice kamery. -Používáme především k vykreslení 2D scén. Osu Z můžeme využít, abychom jeden sprite schovali za jiný. Nicméně objekty dál od kamery jsou stejně velké jako ty blízko kamery. <> + > [!NOTE] + > Všimni si, že levá matice je transponovaná a poziční vektor v pravé matici je negovaný. Je to proto, že otáčíme a posouváme celým světem tak, aby kamera byla v počátku, musíme proto provést inverzní operace vůči těm, které chceme provést s kamerou. [^camera] -image::./img/szp08_orthographic_projection.png[width=500] +- **Frustum** + Část 3D tělesa (nejčastěji pyramidy nebo jehlanu) mezi dvěma rovnoběžnými rovinami. Doslovný překlad je _"komolý jehlan"_ +- **Projekční matice / projection matrix $P$** + Převádí souřadnice z prostoru před kamerou (camera space) do clip space. + + Používá se zejména ortografická projekce ($P_\text{ortho}$) a perspektivní projekce ($P_\text{persp}$). + +- **MVP matice** + Pro převod modelu z jeho lokálního prostoru do clip space použijeme: + + ```math + \vec{v}_\text{clip} = P \cdot V \cdot M \cdot \vec{v}_\text{local} + ``` + +## Projekce + +### Ortografická projekce + +Používáme především k vykreslení 2D scén. Osu Z můžeme využít, abychom jeden sprite schovali za jiný. Nicméně objekty dál od kamery jsou stejně velké jako ty blízko kamery. [camera](#camera) + +![width=500](./img/szp08_orthographic_projection.png) Je dána 6 parametry: --- -* stem:[\text{left}] - levá hranice (X), -* stem:[\text{right}] - pravá hranice (X), -* stem:[\text{bottom}] - spodní hranice (Y), -* stem:[\text{top}] - horní hranice (Y), -* stem:[\text{near}] - blízká hranice (Z), -* stem:[\text{far}] - daleká hranice (Z). --- +- $\text{left}$ - levá hranice (X), +- $\text{right}$ - pravá hranice (X), +- $\text{bottom}$ - spodní hranice (Y), +- $\text{top}$ - horní hranice (Y), +- $\text{near}$ - blízká hranice (Z), +- $\text{far}$ - daleká hranice (Z). -Společně definují boxík, kde je stem:[(\text{left}, \text{bottom}, -\text{near})] levý spodní roh a stem:[(\text{right}, \text{top}, -\text{far})] pravý horní roh. Úkolem matice stem:[P_\text{ortho}] je nasoukat tento boxík do krychle stem:[(-1, -1, -1) \to (1, 1, 1)] (a navíc flipnou Z, protože OpenGL mění handedness). +Společně definují boxík, kde je $(\text{left}, \text{bottom}, -\text{near})$ levý spodní roh a $(\text{right}, \text{top}, -\text{far})$ pravý horní roh. Úkolem matice $P_\text{ortho}$ je nasoukat tento boxík do krychle $(-1, -1, -1) \to (1, 1, 1)$ (a navíc flipnou Z, protože OpenGL mění handedness). -[stem] -++++ +```math \begin{aligned} P_\text{ortho} &= C \cdot S \cdot T \\ @@ -149,149 +143,140 @@ P_\text{ortho} &= C \cdot S \cdot T \\ \end{bmatrix} \end{aligned} -++++ +``` kde: --- -* stem:[C] obrací osu Z, kvůli přechodu z right-handed do left-handed (týká se OpenGL <>), -* stem:[S] definuje velikost kvádru, který se vleze do clip space, -* stem:[T] posouvá počátek doprostřed kvádru. --- +- $C$ obrací osu Z, kvůli přechodu z right-handed do left-handed (týká se OpenGL [^ortho]), +- $S$ definuje velikost kvádru, který se vleze do clip space, +- $T$ posouvá počátek doprostřed kvádru. -=== Perspektivní projekce +### Perspektivní projekce -Zmenšuje objekty, které jsou dále od kamery. <> +Zmenšuje objekty, které jsou dále od kamery. [^camera] -image::./img/szp08_perspective_projection.png[width=500] +![width=500](./img/szp08_perspective_projection.png) Je definována 4 parametry: --- -* stem:[\text{FOV}_y] - field of view (úhel zorného pole) v ose Y, -* stem:[\text{aspect}] - poměr šířky a výšky okna, -* stem:[\text{near}] - blízká hranice, -* stem:[\text{far}] - daleká hranice. --- - -V matici stem:[P_\text{persp}] se vyskytují následující mezihodnoty: - --- -* stem:[\text{top} = \text{near} \cdot \tan \left( \frac{\text{FOV}_y}{2} \right)], -* stem:[\text{bottom} = -\text{top}], -* stem:[\text{right} = \text{top} \cdot \text{aspect}], -* stem:[\text{left} = -\text{right}]. --- - -Translace frustumu:: -Posouváme špičku frustumu do počátku souřadného systému. <> -+ -[stem] -++++ -T = -\begin{bmatrix} - 1 & 0 & 0 & -\frac{\text{left} + \text{right}}{2} \\ - 0 & 1 & 0 & -\frac{\text{bottom} + \text{top}}{2} \\ - 0 & 0 & 1 & 0 \\ - 0 & 0 & 0 & 1 \\ -\end{bmatrix} -++++ -+ -NOTE: Všimni si, že. Pokud používáme 4-parametrickou verzi, tak je to matice identity a tím pádem není potřeba. - -Perspective divide:: -Objekty blíže k rovině stem:[\text{near}] budou větší než objekty dále. Rovina stem:[\text{near}] reprezentuje plochu obrazovky, na kterou jsou všechny body promítány. -+ -.Perspective divide <> -image::./img/szp08_perspective_divide.png[width=500] -+ -V obrázku výše je bod stem:[(x, y, z)] promítnut na rovinu stem:[\text{near}] jako stem:[(x', y', near)]. Vznikají tak dva trojúhelníky, které jsou si sobě podobné a proto mají stejné poměry stran. Platí tedy stem:[\frac{y'}{\text{near}} = \frac{y}{z}]. Pak stem:[y' = \frac{y \cdot \text{near}}{z}]. Chceme tedy, aby platilo: -+ -[stem] -++++ -\begin{aligned} - x' = \frac{x \cdot \text{near}}{z} \\ - y' = \frac{y \cdot \text{near}}{z} -\end{aligned} -++++ -+ -Což můžeme vyjádřit v homogenních souřadnicích vyjadřít dělením stem:[w] jako: -+ -[stem] -++++ -D = \begin{bmatrix} - \text{near} & 0 & 0 & 0 \\ - 0 & \text{near} & 0 & 0 \\ - 0 & 0 & 1 & 0 \\ - 0 & 0 & \color{red}{-1} & \color{red}{0} \\ -\end{bmatrix} -++++ - -Velikost okna:: -Šířka a výška okna dána pomocí stem:[\text{left}, \text{right}, \text{bottom}, \text{top}] se musí vlézt do intervalu stem:[(-1.0, 1.0)], proto je potřeba provést škálování: -+ -[stem] -++++ -S = \begin{bmatrix} - \frac{2}{\text{right} - \text{left}} & 0 & 0 & 0 \\ - 0 & \frac{2}{\text{top} - \text{bottom}} & 0 & 0 \\ - 0 & 0 & 1 & 0 \\ - 0 & 0 & 0 & 1 \\ -\end{bmatrix} -++++ - -Přemapování hloubky:: -Chceme zachovat tu schopnost souřadnice stem:[z] nám říct, že něco je před něčím jiným. Potřebujeme proto přemapovat interval stem:[(-\text{near}, -\text{far})] na stem:[(-1.0, 1.0)]. Jelikož desetinná čísla mají tendenci vytvářet artefakty, chceme aby toto mapování bylo nelineární tak, aby bylo přesnější blíže stem:[\text{near}]. Použijeme stem:[\frac{c_1}{-z} + c_2], kde stem:[c_1] a stem:[c_2] jsou konstanty zvoleny pomocí: -+ -NOTE: Interval stem:[(-\text{near}, -\text{far})] obsahuje negace, neboť kamera se dívá do -Z osy, ale tyto hodnoty zadáváme jako kladná čísla. -+ -NOTE: stem:[-z] v rovnici výše je zodpovědné za přepnutí mezi right-handed a left-handed systémem souřadnic v OpenGL. -+ -.Depth mapping <> -image::./img/szp08_depth_mapping.png[width=500] -+ -[stem] -++++ -\begin{aligned} - -1.0 &= \frac{c_1}{-(-\text{near})} + c_2 \\ - 1.0 &= \frac{c_1}{-(-\text{far})} + c_2 -\end{aligned} -++++ -+ -Tedy: -+ -[stem] -++++ -\begin{aligned} - c_1 &= \frac{2 \cdot \text{far} \cdot \text{near}}{\text{near} - \text{far}} \\ - c_2 &= \frac{\text{far} + \text{near}}{\text{far} - \text{near}} -\end{aligned} -++++ -+ -Pokud stem:[\frac{c_1}{-z} + c_2] přepíšeme jako stem:[\frac{(c_1 + c_2 \cdot (-z))}{-z} = \frac{(-c_2 \cdot z + c_1)}{-z}], můžeme opět použít homogenní souřadnice a dělení stem:[w] a získáme: -+ -[stem] -++++ -M_\text{depth} = \begin{bmatrix} - 1 & 0 & 0 & 0 \\ - 0 & 1 & 0 & 0 \\ - 0 & 0 & -c_2 & c_1 \\ - 0 & 0 & -1 & 0 \\ -\end{bmatrix} -= \begin{bmatrix} - 1 & 0 & 0 & 0 \\ - 0 & 1 & 0 & 0 \\ - 0 & 0 & -\frac{\text{far} + \text{near}}{\text{far} - \text{near}} & \frac{2 \cdot \text{far} \cdot \text{near}}{\text{near} - \text{far}} \\ - 0 & 0 & -1 & 0 \\ -\end{bmatrix} -++++ +- $\text{FOV}_y$ - field of view (úhel zorného pole) v ose Y, +- $\text{aspect}$ - poměr šířky a výšky okna, +- $\text{near}$ - blízká hranice, +- $\text{far}$ - daleká hranice. + +V matici $P_\text{persp}$ se vyskytují následující mezihodnoty: + +- $\text{top} = \text{near} \cdot \tan \left( \frac{\text{FOV}_y}{2} \right)$, +- $\text{bottom} = -\text{top}$, +- $\text{right} = \text{top} \cdot \text{aspect}$, +- $\text{left} = -\text{right}$. + +- **Translace frustumu** + Posouváme špičku frustumu do počátku souřadného systému. [^perspective] + + ```math + T = + \begin{bmatrix} + 1 & 0 & 0 & -\frac{\text{left} + \text{right}}{2} \\ + 0 & 1 & 0 & -\frac{\text{bottom} + \text{top}}{2} \\ + 0 & 0 & 1 & 0 \\ + 0 & 0 & 0 & 1 \\ + \end{bmatrix} + ``` + + > [!NOTE] + > Všimni si, že. Pokud používáme 4-parametrickou verzi, tak je to matice identity a tím pádem není potřeba. + +- **Perspective divide** + Objekty blíže k rovině $\text{near}$ budou větší než objekty dále. Rovina $\text{near}$ reprezentuje plochu obrazovky, na kterou jsou všechny body promítány. + + **Perspective divide** [^perspective] + + ![width=500](./img/szp08_perspective_divide.png) + + V obrázku výše je bod $(x, y, z)$ promítnut na rovinu $\text{near}$ jako $(x', y', near)$. Vznikají tak dva trojúhelníky, které jsou si sobě podobné a proto mají stejné poměry stran. Platí tedy $\frac{y'}{\text{near}} = \frac{y}{z}$. Pak $y' = \frac{y \cdot \text{near}}{z}$. Chceme tedy, aby platilo: + + ```math + \begin{aligned} + x' = \frac{x \cdot \text{near}}{z} \\ + y' = \frac{y \cdot \text{near}}{z} + \end{aligned} + ``` + + Což můžeme vyjádřit v homogenních souřadnicích vyjadřít dělením $w$ jako: + + ```math + D = \begin{bmatrix} + \text{near} & 0 & 0 & 0 \\ + 0 & \text{near} & 0 & 0 \\ + 0 & 0 & 1 & 0 \\ + 0 & 0 & \color{red}{-1} & \color{red}{0} \\ + \end{bmatrix} + ``` + +- **Velikost okna** + Šířka a výška okna dána pomocí $\text{left}, \text{right}, \text{bottom}, \text{top}$ se musí vlézt do intervalu $(-1.0, 1.0)$, proto je potřeba provést škálování: + + ```math + S = \begin{bmatrix} + \frac{2}{\text{right} - \text{left}} & 0 & 0 & 0 \\ + 0 & \frac{2}{\text{top} - \text{bottom}} & 0 & 0 \\ + 0 & 0 & 1 & 0 \\ + 0 & 0 & 0 & 1 \\ + \end{bmatrix} + ``` + +- **Přemapování hloubky** + Chceme zachovat tu schopnost souřadnice $z$ nám říct, že něco je před něčím jiným. Potřebujeme proto přemapovat interval $(-\text{near}, -\text{far})$ na $(-1.0, 1.0)$. Jelikož desetinná čísla mají tendenci vytvářet artefakty, chceme aby toto mapování bylo nelineární tak, aby bylo přesnější blíže $\text{near}$. Použijeme $\frac{c_1}{-z} + c_2$, kde $c_1$ a $c_2$ jsou konstanty zvoleny pomocí: + + > [!NOTE] + > Interval $(-\text{near}, -\text{far})$ obsahuje negace, neboť kamera se dívá do -Z osy, ale tyto hodnoty zadáváme jako kladná čísla. + + > [!NOTE] + > $-z$ v rovnici výše je zodpovědné za přepnutí mezi right-handed a left-handed systémem souřadnic v OpenGL. + + **Depth mapping [^perspective]** + + ![width=500](./img/szp08_depth_mapping.png) + + ```math + \begin{aligned} + -1.0 &= \frac{c_1}{-(-\text{near})} + c_2 \\ + 1.0 &= \frac{c_1}{-(-\text{far})} + c_2 + \end{aligned} + ``` + + Tedy: + + ```math + \begin{aligned} + c_1 &= \frac{2 \cdot \text{far} \cdot \text{near}}{\text{near} - \text{far}} \\ + c_2 &= \frac{\text{far} + \text{near}}{\text{far} - \text{near}} + \end{aligned} + ``` + + Pokud $\frac{c_1}{-z} + c_2$ přepíšeme jako $\frac{(c_1 + c_2 \cdot (-z))}{-z} = \frac{(-c_2 \cdot z + c_1)}{-z}$, můžeme opět použít homogenní souřadnice a dělení $w$ a získáme: + + ```math + M_\text{depth} = \begin{bmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 \\ + 0 & 0 & -c_2 & c_1 \\ + 0 & 0 & -1 & 0 \\ + \end{bmatrix} + = \begin{bmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 \\ + 0 & 0 & -\frac{\text{far} + \text{near}}{\text{far} - \text{near}} & \frac{2 \cdot \text{far} \cdot \text{near}}{\text{near} - \text{far}} \\ + 0 & 0 & -1 & 0 \\ + \end{bmatrix} + ``` --- Výsledná matice je: -[stem] -++++ +```math P_\text{persp} = M_\text{depth} \cdot S \cdot D \cdot T = \begin{bmatrix} @@ -300,25 +285,24 @@ P_\text{persp} = M_\text{depth} \cdot S \cdot D \cdot T = & 0 & \textcolor{purple}{-\text{near} \cdot \frac{\text{right} + \text{left}}{\text{right} - \text{left}}} \\ - 0 + 0 & \textcolor{blue}{\frac{2 \cdot \text{near}}{\text{top} - \text{bottom}}} & 0 & \textcolor{#F56FA1}{-\text{near} \cdot \frac{\text{top} + \text{bottom}}{\text{top} - \text{bottom}}} \\ % Nika: použij cyklamenovou farbu - 0 + 0 & 0 & -\frac{\text{far} + \text{near}}{\text{far} - \text{near}} & \frac{2 \cdot \text{far} \cdot \text{near}}{\text{near} - \text{far}} \\ 0 & 0 & -1 & 0 \\ \end{bmatrix} -++++ +``` -Tahle matice funguje pro obecné frustum dané parametry stem:[\text{left}, \text{right}, \text{bottom}, \text{top}, \text{near}, \text{far}]. Pokud dosadíme původní parametry za mezihodnoty: +Tahle matice funguje pro obecné frustum dané parametry $\text{left}, \text{right}, \text{bottom}, \text{top}, \text{near}, \text{far}$. Pokud dosadíme původní parametry za mezihodnoty: -[stem] -++++ +```math \begin{aligned} \textcolor{green}{\frac{2 \cdot \text{near}}{\text{right} - \text{left}}} @@ -341,208 +325,187 @@ Tahle matice funguje pro obecné frustum dané parametry stem:[\text{left}, \tex = \textcolor{#F56FA1}{0} \end{aligned} -++++ +``` -dostaneme matici, na kterou se trochu lépe kouká: <> +dostaneme matici, na kterou se trochu lépe kouká: [^gluperspective] -[stem] -++++ +```math P_\text{persp} = \begin{bmatrix} \textcolor{green}{\frac{\cot \left( \frac{\text{FOV}_y}{2} \right)}{\text{aspect}}} & 0 & 0 & \textcolor{purple}{0} \\ - 0 & \textcolor{blue}{\cot \left( \frac{\text{FOV}_y}{2} \right)} & 0 & \textcolor{#F56FA1}{0} \\ - 0 & 0 & -\frac{\text{far} + \text{near}}{\text{far} - \text{near}} & \frac{2 \cdot \text{far} \cdot \text{near}}{\text{near} - \text{far}} \\ - - 0 & 0 & -1 & 0 \\ -\end{bmatrix} -++++ - -== Základní afinní transformace - -==== -Opakování z link:../../szb/linearni-algebra-ii/[Lineární algebry II]: - -Afinní prostor stem:[\mathcal{A}]:: -Trojice stem:[(A, V, \oplus)], kde stem:[A] je množina bodů, stem:[V] je vektorový prostor (zaměření) a stem:[\oplus] je binární funkce stem:[\oplus : A \times V \to A]. -Standardní afinní prostor stem:[\mathcal{A}_n]:: -Je afinní prostor stem:[(\mathbb{R}^n, \mathbb{R}^n, +)]. - -Afinní kombinace bodů:: -Výrazy tvaru stem:[t_0 \cdot a_0 + t_1 \cdot a_1 + ... + t_n \cdot a_n], kde stem:[t_i \in \mathbb{R}, a_i \in \mathcal{A}] a stem:[\sum_{i=0}^n t_i = 1]. - -Afinní zobrazení:: -Zobrazení stem:[f : \mathcal{A} \to \mathcal{A}], které zachovává afinní kombinace bodů. -+ -Složení nějakého lineárního zobrazení a translace. -==== - -Translace stem:[T]:: -Pro posun v 2D prostoru podél osy stem:[(x, y)]: -+ -[stem] -++++ -T = \begin{bmatrix} - 1 & 0 & x \\ - 0 & 1 & y \\ - 0 & 0 & 1 -\end{bmatrix} -++++ -+ -Pro posun ve 3D prostoru podél osy stem:[(x, y, z)]: -+ -[stem] -++++ -T = \begin{bmatrix} - 1 & 0 & 0 & x \\ - 0 & 1 & 0 & y \\ - 0 & 0 & 1 & z \\ - 0 & 0 & 0 & 1 -\end{bmatrix} -++++ - -Rotace stem:[R]:: -Pro rotaci v 2D prostoru o úhel stem:[\theta]: -+ -[stem] -++++ -R = \begin{bmatrix} - \cos \theta & -\sin \theta & 0 \\ - \sin \theta & \cos \theta & 0 \\ - 0 & 0 & 1 \\ -\end{bmatrix} -++++ -+ -Pro rotaci ve 3D prostoru o úhel stem:[\theta]: -+ -* Kolem osy stem:[X]: -+ -[stem] -++++ -R = \begin{bmatrix} - 1 & 0 & 0 & 0 \\ - 0 & \cos \theta & -\sin \theta & 0 \\ - 0 & \sin \theta & \cos \theta & 0 \\ - 0 & 0 & 0 & 1 -\end{bmatrix} -++++ -+ -* Kolem osy stem:[Y]: -+ -[stem] -++++ -R = \begin{bmatrix} - \cos \theta & 0 & \sin \theta & 0 \\ - 0 & 1 & 0 & 0 \\ - -\sin \theta & 0 & \cos \theta & 0 \\ - 0 & 0 & 0 & 1 -\end{bmatrix} -++++ -+ -* Kolem osy stem:[Z]: -+ -[stem] -++++ -R = \begin{bmatrix} - \cos \theta & -\sin \theta & 0 & 0 \\ - \sin \theta & \cos \theta & 0 & 0 \\ - 0 & 0 & 1 & 0 \\ - 0 & 0 & 0 & 1 -\end{bmatrix} -++++ - -Škálování / scale stem:[S]:: -Pro škálování v 2D prostoru: -+ -[stem] -++++ -S = \begin{bmatrix} - x & 0 & 0 \\ - 0 & y & 0 \\ - 0 & 0 & 1 \\ -\end{bmatrix} -++++ -+ -Pro škálování ve 3D prostoru: -+ -[stem] -++++ -S = \begin{bmatrix} - x & 0 & 0 & 0 \\ - 0 & y & 0 & 0 \\ - 0 & 0 & z & 0 \\ - 0 & 0 & 0 & 1 -\end{bmatrix} -++++ - -Zkosení / shear (asi taky stem:[S]):: -Pro zkosení v 2D prostoru vektorem stem:[(x, y)]: -+ -[stem] -++++ -S = \begin{bmatrix} - 1 & x & 0 \\ - y & 1 & 0 \\ - 0 & 0 & 1 \\ -\end{bmatrix} -++++ -+ -Pro zkosení ve 3D prostoru podél plochy stem:[YZ]: -+ -[stem] -++++ -S = \begin{bmatrix} - 1 & Y & Z & 0 \\ - 0 & 1 & 0 & 0 \\ - 0 & 0 & 1 & 0 \\ - 0 & 0 & 0 & 1 -\end{bmatrix} -++++ -+ -Podél plochy stem:[XZ]: -+ -[stem] -++++ -S = \begin{bmatrix} - 1 & 0 & 0 & 0 \\ - X & 1 & Z & 0 \\ - 0 & 0 & 1 & 0 \\ - 0 & 0 & 0 & 1 -\end{bmatrix} -++++ -+ -Podél plochy stem:[XY]: -+ -[stem] -++++ -S = \begin{bmatrix} - 1 & 0 & 0 & 0 \\ - 0 & 1 & 0 & 0 \\ - X & Y & 1 & 0 \\ - 0 & 0 & 0 & 1 + 0 & 0 & -1 & 0 \\ \end{bmatrix} -++++ - -[bibliography] -== Zdroje +``` + +## Základní afinní transformace + +Opakování z [Lineární algebry II](../../szb/linearni-algebra-ii/): + +- **Afinní prostor $\mathcal{A}$**\ + Trojice $(A, V, \oplus)$, kde $A$ je množina bodů, $V$ je vektorový prostor (zaměření) a $\oplus$ je binární funkce $\oplus : A \times V \to A$. +- **Standardní afinní prostor $\mathcal{A}_n$**\ + Je afinní prostor $(\mathbb{R}^n, \mathbb{R}^n, +)$. +- **Afinní kombinace bodů**\ + Výrazy tvaru $t_0 \cdot a_0 + t_1 \cdot a_1 + ... + t_n \cdot a_n$, kde $t_i \in \mathbb{R}, a_i \in \mathcal{A}$ a $\sum_{i=0}^n t_i = 1$. +- **Afinní zobrazení**\ + Zobrazení $f : \mathcal{A} \to \mathcal{A}$, které zachovává afinní kombinace bodů. + + Složení nějakého lineárního zobrazení a translace. + +- **Translace $T$**\ + Pro posun v 2D prostoru podél osy $(x, y)$: + + ```math + T = \begin{bmatrix} + 1 & 0 & x \\ + 0 & 1 & y \\ + 0 & 0 & 1 + \end{bmatrix} + ``` + + Pro posun ve 3D prostoru podél osy $(x, y, z)$: + + ```math + T = \begin{bmatrix} + 1 & 0 & 0 & x \\ + 0 & 1 & 0 & y \\ + 0 & 0 & 1 & z \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + ``` + +- **Rotace $R$**\ + Pro rotaci v 2D prostoru o úhel $\theta$: + + ```math + R = \begin{bmatrix} + \cos \theta & -\sin \theta & 0 \\ + \sin \theta & \cos \theta & 0 \\ + 0 & 0 & 1 \\ + \end{bmatrix} + ``` + + Pro rotaci ve 3D prostoru o úhel $\theta$: + + - Kolem osy $X$: + + ```math + R = \begin{bmatrix} + 1 & 0 & 0 & 0 \\ + 0 & \cos \theta & -\sin \theta & 0 \\ + 0 & \sin \theta & \cos \theta & 0 \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + ``` + + - Kolem osy $Y$: + + ```math + R = \begin{bmatrix} + \cos \theta & 0 & \sin \theta & 0 \\ + 0 & 1 & 0 & 0 \\ + -\sin \theta & 0 & \cos \theta & 0 \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + ``` + + - Kolem osy $Z$: + + ```math + R = \begin{bmatrix} + \cos \theta & -\sin \theta & 0 & 0 \\ + \sin \theta & \cos \theta & 0 & 0 \\ + 0 & 0 & 1 & 0 \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + ``` + +- **Škálování / scale $S$** + Pro škálování v 2D prostoru: + + ```math + S = \begin{bmatrix} + x & 0 & 0 \\ + 0 & y & 0 \\ + 0 & 0 & 1 \\ + \end{bmatrix} + ``` + + Pro škálování ve 3D prostoru: + + ```math + S = \begin{bmatrix} + x & 0 & 0 & 0 \\ + 0 & y & 0 & 0 \\ + 0 & 0 & z & 0 \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + ``` + +- **Zkosení / shear (asi taky $S$)** + Pro zkosení v 2D prostoru vektorem $(x, y)$: + + ```math + S = \begin{bmatrix} + 1 & x & 0 \\ + y & 1 & 0 \\ + 0 & 0 & 1 \\ + \end{bmatrix} + ``` + + Pro zkosení ve 3D prostoru podél plochy $YZ$: + + ```math + S = \begin{bmatrix} + 1 & Y & Z & 0 \\ + 0 & 1 & 0 & 0 \\ + 0 & 0 & 1 & 0 \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + ``` + + Podél plochy $XZ$: + + ```math + S = \begin{bmatrix} + 1 & 0 & 0 & 0 \\ + X & 1 & Z & 0 \\ + 0 & 0 & 1 & 0 \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + ``` + + Podél plochy $XY$: + + ```math + S = \begin{bmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 \\ + X & Y & 1 & 0 \\ + 0 & 0 & 0 & 1 + \end{bmatrix} + ``` + +## Další zdroje + +- [`glm::ortho`](https://github.com/g-truc/glm/blob/5c46b9c07008ae65cb81ab79cd677ecc1934b903/glm/ext/matrix_clip_space.inl#L55) +- [`glm::perspective`](https://github.com/g-truc/glm/blob/5c46b9c07008ae65cb81ab79cd677ecc1934b903/glm/ext/matrix_clip_space.inl#L249) +- [`glm::lookAt`](https://github.com/g-truc/glm/blob/5c46b9c07008ae65cb81ab79cd677ecc1934b903/glm/ext/matrix_transform.inl#L153) -* [[[camera,1]]] link:https://learnopengl.com/Getting-started/Camera[LearnOpenGL: Camera] -* [[[lookat,2]]] link:https://github.com/g-truc/glm/blob/5c46b9c07008ae65cb81ab79cd677ecc1934b903/glm/ext/matrix_transform.inl#L153[`glm::lookAt`] -* [[[ortho,3]]] link:http://learnwebgl.brown37.net/08_projections/projections_ortho.html[LearnWebGL: Orthographic Projection] -* [[[perspective,4]]] link:http://learnwebgl.brown37.net/08_projections/projections_perspective.html[LearnWebGL: Perspective Projection] -* [[[gluperspective,5]]] link:https://registry.khronos.org/OpenGL-Refpages/gl2.1/xhtml/gluPerspective.xml[`gluPerspective`] - -== Další zdroje +--- -* link:https://github.com/g-truc/glm/blob/5c46b9c07008ae65cb81ab79cd677ecc1934b903/glm/ext/matrix_clip_space.inl#L55[`glm::ortho`] -* link:https://github.com/g-truc/glm/blob/5c46b9c07008ae65cb81ab79cd677ecc1934b903/glm/ext/matrix_clip_space.inl#L249[`glm::perspective`] +[^camera]: [LearnOpenGL: Camera](https://learnopengl.com/Getting-started/Camera) +[^ortho]: [LearnWebGL: Orthographic Projection](http://learnwebgl.brown37.net/08_projections/projections_ortho.html) +[^perspective]: [LearnWebGL: Perspective Projection](http://learnwebgl.brown37.net/08_projections/projections_perspective.html) +[^gluperspective]: [`gluPerspective`](https://registry.khronos.org/OpenGL-Refpages/gl2.1/xhtml/gluPerspective.xml) From 5c20e0aa57fbd6adf065fbbd7e6c02db412787e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Fri, 6 Jun 2025 23:12:45 +0200 Subject: [PATCH 03/44] Transpiled SZMGR content to markdown The tool is called "downdoc" --- szmgr.md | 6 - szmgr/PGV01_zaklady_vizualizace.md | 150 +- szmgr/PGV02_metody_vizualizace.md | 172 +- szmgr/PGV03_zaklady_pocitatcove_grafiky.md | 311 ++-- szmgr/PGV04_geometricke_algoritmy.md | 207 +-- szmgr/PGV05_deleni_prostoru_a_sceny.md | 139 +- szmgr/PGV06_vykreslovani_objemovych_dat.md | 374 ++-- szmgr/PGV07_modely_osvetleni.md | 360 ++-- szmgr/PGV08_real_time_rendering.md | 318 ++-- szmgr/PGV09_minimalizace_energie.md | 353 ++-- szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md | 304 ++-- szmgr/PGV_zpracovani_obrazu_intro.md | 63 +- szmgr/SZP01_algoritmy.md | 975 ++++++----- szmgr/SZP02_numericke_metody.md | 616 ++++--- szmgr/SZP03_statistika.md | 1125 +++++-------- szmgr/SZP04_3d_modelovani.md | 962 +++++------ szmgr/SZP05_krivky_a_povrchy.md | 1064 +++++------- szmgr/SZP06_strojove_uceni.md | 817 ++++----- szmgr/SZP07_grafy.md | 1023 ++++++----- szmgr/SZP08_modelovani_a_projekce.md | 2 +- szmgr/SZP09_zpracovani_obrazu.md | 1499 ++++++++--------- szmgr/SZP10_analyza_obrazu.md | 1071 ++++++------ .../VPH01_graficke_principy_ve_vyvoji_her.md | 526 +++--- szmgr/VPH01_pokrocila_grafika.md | 686 ++++---- .../VPH02_fyzikalni_principy_ve_vyvoji_her.md | 147 +- szmgr/VPH02_graficke_a_fyzikalni_principy.md | 638 ++++--- szmgr/VPH03_herni_design_i.md | 505 +++--- szmgr/VPH04_herni_design_ii.md | 487 +++--- szmgr/VPH05_vyvoj_her.md | 648 ++++--- szmgr/VPH06_ai_ve_hrach.md | 823 +++++---- szmgr/VPH07_gpu_rendering.md | 660 ++++---- szmgr/VPH08_modelovani_3d_postav.md | 285 ++-- szmgr/guidelines.md | 43 +- szmgr/index.md | 182 +- 34 files changed, 8172 insertions(+), 9369 deletions(-) delete mode 100644 szmgr.md diff --git a/szmgr.md b/szmgr.md deleted file mode 100644 index 0940489..0000000 --- a/szmgr.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -title: MGR State exam -description: A reference page in my new Starlight docs site. ---- - -# SZMGR \ No newline at end of file diff --git a/szmgr/PGV01_zaklady_vizualizace.md b/szmgr/PGV01_zaklady_vizualizace.md index deda57a..21b1c89 100644 --- a/szmgr/PGV01_zaklady_vizualizace.md +++ b/szmgr/PGV01_zaklady_vizualizace.md @@ -1,125 +1,133 @@ -= Základy vizualizace -:url: ./zaklady_vizualizace/ -:page-group: pgv -:page-order: PGV01 +--- +title: "Základy vizualizace" +description: "TODO" +--- + +
📌 NOTE
-[NOTE] -==== 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_ -==== + +
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 +## 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 (Effectiveness) Efektivita je vysoká, pokud je 1. Správně a rychle interpretována 2. Rychle vyrenderována -stem:[M_{eff} = \frac{1}{1 + \text{interpret} + \text{render}}], kde stem:[0 \leq M_{eff} \leq 1]. +$M_{eff} = \frac{1}{1 + \text{interpret} + \text{render}}$, kde $0 \leq M_{eff} \leq 1$. -Pokud je stem:[M_{eff} \sim 1], pak je čas na interpretaci a renderování krátký. +Pokud je $M_{eff} \sim 1$, pak je čas na interpretaci a renderování krátký. -=== Expresivita (Expressiveness) +### Expresivita (Expressiveness) -stem:[M_{exp} = \frac{\text{displayed information}}{\text{information to be expressed}}], kde stem:[0 \leq M_{exp} \leq 1]. +$M_{exp} = \frac{\text{displayed information}}{\text{information to be expressed}}$, kde $0 \leq M_{exp} \leq 1$. -- Pokud je stem:[M_{exp} = 1], pak je expresivita ideální. -- Pokud je stem:[M_{exp} < 1], pak zobrazujeme méně informací, než jsme zamýšleli. -- Pokud je stem:[M_{exp} > 1], pak zobrazujeme více informací, než bychom měli. +- 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é Vizuální proměnné se snaží maximalizovat efektivitu a expresivitu vizualizace. Základní vizuální proměnné definuje Bertin a jsou to: -image::./img/pgv01_visual_variables.png[width=600] +![width=600](./img/pgv01_visual_variables.png) + +### Pozice -=== Pozice -Best case: Každý bod má jednoznačnou pozici. + +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 +### Velikost + Bývá problematické rozlišit velikost, pokud je rozdíl malý. -=== Tvar +### Tvar + Může být použit pro kategorické proměnné. Tvar zahrnují i písmena, typy čar, atd. -=== Jas (value) +### Jas (value) + Podobně, jako u velikosti je obtížné rozlišit jas, pokud je rozdíl malý. -=== Barva (hue) +### Barva (hue) + Lze použít pro kategorické i numerické proměnné. -*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é. -image::./img/pgv01_color_palettes.png[width=500] +![width=500](./img/pgv01_color_palettes.png) 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". -image::./img/pgv01_rainbow.png[width=400] +![width=400](./img/pgv01_rainbow.png) -*Kategorické proměnné:* +**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 +### Orientace + +### Textura -=== Textura +### Pohyb -=== 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 +## Základní vizualizační techniky prostorových dat + +
💡 TIP
-[TIP] -==== 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í. -==== -=== 0D (neprostorová) data +
+ +### 0D (neprostorová) data Množina hodnot, které nemají žádnou prostorovou interpretaci. -*Numerické proměnné:* +**Numerické proměnné:** -- *Histogram* (seskupíme hodnoty do intervalů a zobrazíme počet hodnot v každém intervalu) +- **Histogram** (seskupíme hodnoty do intervalů a zobrazíme počet hodnot v každém intervalu) -*Kategorické proměnné:* +**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) +- **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 +### 1D prostorová data Sekvence jednodimenzionálních dat s jednou proměnnou. -- *Graf* -- *Barevný pruh* +- **Graf** +- **Barevný pruh** -image::./img/pgv01_1D.png[width=500] +![width=500](./img/pgv01_1D.png) -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). +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 +### 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ů) +- **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ů) -image::./img/pgv01_2D.png[width=700] +![width=700](./img/pgv01_2D.png) Pro více proměnných: @@ -128,55 +136,55 @@ Pro více proměnných: 2D data je často třeba zjednodušit, např. pomocí agregace, nebo pomocí vizualizace hustoty (histogram). -=== 3D prostorová data +### 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 +## 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. +Pokud nejsou datové body na mřížce, použijeme tzv. **Resampling** (převzorkování) - interpolace hodnot mezi body. -=== Slicing +### 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. -image::./img/pgv01_clip_planes.png[width=500] +![width=500](./img/pgv01_clip_planes.png) -=== Isosurface +### Isosurface Vytvoříme povrch, kde hodnota je konstantní. Na vytvoření isosurface můžeme použít algoritmy jako Marching Cubes. -=== Direct volume rendering +### 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 link:../PGV06_vykreslovani_objemovych_dat[PGV06]. +Detailní fungování je popsané v otázce [PGV06](../PGV06_vykreslovani_objemovych_dat). -== Geovizualizace +## Geovizualizace Mohou zobrazovat nejen body, ale i čáry a plochy. -=== Choropletové mapy +### 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). -image::./img/pgv01_choropleth.png[width=300] +![width=300](./img/pgv01_choropleth.png) -=== Kartogramy +### 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. +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. -image::./img/pgv01_cartogram.png[width=700] \ No newline at end of file +![width=700](./img/pgv01_cartogram.png) diff --git a/szmgr/PGV02_metody_vizualizace.md b/szmgr/PGV02_metody_vizualizace.md index 7c5380e..1a1f115 100644 --- a/szmgr/PGV02_metody_vizualizace.md +++ b/szmgr/PGV02_metody_vizualizace.md @@ -1,153 +1,137 @@ -= Metody vizualizace -:url: ./metody_vizualizace/ -:page-group: pgv -:page-order: PGV02 +--- +title: "Metody vizualizace" +description: "TODO" +--- + +
📌 NOTE
-[NOTE] -==== 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_ -==== -== Vizualizace multidimenzionálních dat +
+ +## 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 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. -image::./img/pgv02_scatterplot_matrix.png[width=500] +![width=500](./img/pgv02_scatterplot_matrix.png) -=== Paralelní souřadnice +### 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. -image::./img/pgv02_parallel_ordering.png[width=600] +![width=600](./img/pgv02_parallel_ordering.png) -=== Skládání dimenzí +### 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. -image::./img/vpg02_dim_stacking.png[width=600] - +![width=600](./img/vpg02_dim_stacking.png) -== Vizualizace hierarchických struktur +## 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 +### 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é. -image::./img/pgv02_treemap.png[width=600] +![width=600](./img/pgv02_treemap.png) -=== Sunburst +### 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. -image::./img/pgv02_sunburst.png[width=400] +![width=400](./img/pgv02_sunburst.png) -=== Další techniky +### 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 +## 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. -[TIP] -==== -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 link:https://annas-archive.org/md5/0bf49e061a8b82167d0e05a5d2b50476[Anna's Archive]) -==== +
💡 TIP
-=== Techniky pro prostor obrazovky (Pixely) +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)) -Výběr pixelů:: -Vybíráme jednotlivé body obrazovky (obdélník, laso, ...) +
-Zkreslení:: -Mapování pixelů na jiné pixely (zoom, lupa, ...) stem:[(x', y') = f(x, y)]. Zkreslení mohou způsobit kolizi pixelů, nebo naopak díry, které musíme vyřešit interpolací. +### Techniky pro prostor obrazovky (Pixely) -Rybí oko::: -Zvětšení jednoho místa na obrazovce, v podstatě "odstrkujeme pixely" od vybraného bodu stem:[(c_x, c_y)] logaritmicky podle vzdálenosti od tohoto bodu a síly zkreslení stem:[d]. +- **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$. -image::./img/pgv02_fisheye.png[width=300] +![width=300](./img/pgv02_fisheye.png) -=== Techniky pro prostor hodnot +### 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. stem:[(d_0', d_1', \dots, d_n') = (j_0(d_0), j_1(d_1), \dots, j_n(d_n))] +- **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))$ -image::./img/pgv02_data_space.png[width=600] +![width=600](./img/pgv02_data_space.png) -=== Techniky pro datové struktury (Organizace dat) +### 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í +- **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). -Změna kódování:: -Úprava barevné škály, barev, ... +### Techniky pro prostor atributů -=== Techniky pro objekt (3D povrch) +- **Filtrování**\ + Skrývání některých atributů, nebo jejich zvýraznění +- **Změna kódování**\ + Úprava barevné škály, barev, ... -Navigace:: -Otáčení, kamera, ... +### Techniky pro objekt (3D povrch) -Perspective walls:: -Vizualizační metoda pro navigaci ve velkém množství dat. +- **Navigace**\ + Otáčení, kamera, ... +- **Perspective walls**\ + Vizualizační metoda pro navigaci ve velkém množství dat. diff --git a/szmgr/PGV03_zaklady_pocitatcove_grafiky.md b/szmgr/PGV03_zaklady_pocitatcove_grafiky.md index 4253109..f492e36 100644 --- a/szmgr/PGV03_zaklady_pocitatcove_grafiky.md +++ b/szmgr/PGV03_zaklady_pocitatcove_grafiky.md @@ -1,100 +1,99 @@ -= Základy počítačové grafiky -:url: ./zaklady_pocitatcove_grafiky/ -:page-group: pgv -:page-order: PGV03 +--- +title: "Základy počítačové grafiky" +description: "TODO" +--- + +
📌 NOTE
-[NOTE] -==== 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_ -==== -== OpenGL blokový diagram +
+ +## OpenGL blokový diagram -image::./img/pgv03_block_diagram.png[width=600] +![width=600](./img/pgv03_block_diagram.png) -Blokový diagram je abstraktní, high-level popis fungování OpenGL <>. +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 link:../modelovani-a-projekce[model space do camera space], 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 +- **_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 +## GLSL - vertex a fragment shader -image::./img/pgv03_with_shaders.png[width=600] +![width=600](./img/pgv03_with_shaders.png) Čá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, ... +- **_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 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_ + - `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_ + - `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_ + - `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č_ + - `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_ + - `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č_ + - `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_ + - 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_ - -image::./img/pgv03_creating_program.gif[width=350] - -== Základní typy vstupních a výstupních proměnných + - `glUseProgram` + - Předáme identifikátor programu + - _Spustíme program na počítači_ -=== Podle způsobu předávání dat +![width=350](./img/pgv03_creating_program.gif) -- **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 +## Základní typy vstupních a výstupních proměnných -- **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 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 +### Podle datového typu - `float`, `double`, `int`, `uint`, `bool` - skalární typy - `vec2`, `vec3`, `vec4` - vektorové typy @@ -102,9 +101,7 @@ image::./img/pgv03_creating_program.gif[width=350] - `mat2`, `mat3`, `mat4` - matice - `sampler1D`, `sampler2D`, `sampler3D`, `samplerCube` - textury - struktury, pole, ... - -Přístup k jednotlivým složkám vektoru:: - +- **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` @@ -114,21 +111,19 @@ Můžeme použít také tzv. swizzling, kdy můžeme vytvořit nový vektor z ex `v.xy`, `v.zw`, `v.xxyy`, `v.zzzz`, ... -Struktury:: +- **Struktury** -[source,glsl] ----- +```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í: -[source,glsl] ----- +```glsl struct Light { vec3 position; vec3 color; @@ -138,39 +133,39 @@ struct Light { layout(binding = 0, std140) uniform Lights { Light lights[10]; }; ----- +``` -Pole:: +- **Pole** -[source,glsl] ----- +```glsl float data[10]; ----- +``` -== Druhy grafických primitiv +## 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` +- **_Body_** - `GL_POINTS` +- **_Čáry_** - `GL_LINES`, `GL_LINE_STRIP`, `GL_LINE_LOOP` +- **_Trojúhelníky_** - `GL_TRIANGLES`, `GL_TRIANGLE_STRIP`, `GL_TRIANGLE_FAN` -image::./img/pgv03_primitives.png[width=500] +![width=500](./img/pgv03_primitives.png) Typ primitivu nastavíme funkcí `glDrawArrays` nebo `glDrawElements` až při renderu. +## Vertex Buffer Objects a Vertex Array Objects -== Vertex Buffer Objects a Vertex Array Objects +![width=700](./img/pgv03_vao_vbo.jpg) -image::./img/pgv03_vao_vbo.jpg[width=700] +### Vertex Buffer Object (VBO) -=== 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) +### 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:: +- **Příklad 1** Naše data vypadají takto: @@ -191,25 +186,22 @@ Pak chceme napojit naši strukturu na VBO takto: - 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) - +* 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:: +- **Příklad 2** Naše data vypadají takto: @@ -237,55 +229,48 @@ Pak chceme napojit naši strukturu na VBO takto: - 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 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 +## 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). +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. +- **Bod**\ + Při rasterizaci bodu vykreslíme čtverec o hraně `gl_PointSize` zaokrouhlený na celé pixely. -image::./img/pgv03_rast_point.png[width=300] +![width=300](./img/pgv03_rast_point.png) -Úsečka:: -Při rasterizaci úsečky použijeme Bresenhamův algoritmus <>. Poslední bod úsečky zůstane nevykreslený (half-open) kvůli návaznosti na další úsečky. +- **Ú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. -[source,cpp] ----- +```cpp // From the solution of PB009 void Application::bresenham(glm::vec2 start, glm::vec2 end, Raster& raster, Color color) { @@ -333,38 +318,37 @@ void Application::bresenham(glm::vec2 start, glm::vec2 end, Raster& raster, Colo } } } ----- +``` -Trojúhelník:: +- **Trojúhelník** -Při rasterizaci trojúhelníku můžeme použít Pinedaův algoritmus <>. 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. +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: stem:[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. +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. -image::./img/pgv03_rast_triangle.png[width=300] +![width=300](./img/pgv03_rast_triangle.png) -== Framebuffer +## Framebuffer -image::./img/pgv03_framebuffer.jpg[width=700] +![width=700](./img/pgv03_framebuffer.jpg) 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 +## 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 +- **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í +### 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í +### Filtrování - `GL_NEAREST` - nejbližší texel, zachovává pixelizaci - `GL_LINEAR` - lineární interpolace mezi texely, vyhlazuje pixelizaci @@ -374,9 +358,9 @@ Pokud nepracujeme s pixel-artovou grafikou je ideální použít `GL_LINEAR_MIPM 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. -image::./img/pgv03_mipmaps.jpg[width=500] +![width=500](./img/pgv03_mipmaps.jpg) -=== Syntéza +### 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, ... @@ -386,17 +370,16 @@ Výhodami syntetizovaných textur je: - dobrá návaznost na hranách geometrie, pokud syntetizujeme 3D texturu - parametrizovatelnost -[NOTE] -==== -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 <> a <>. -==== +
📌 NOTE
+ +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). +
-[bibliography] -== Zdroje +## 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 \ No newline at end of file +- [[[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 diff --git a/szmgr/PGV04_geometricke_algoritmy.md b/szmgr/PGV04_geometricke_algoritmy.md index 9f5ee36..df53fc3 100644 --- a/szmgr/PGV04_geometricke_algoritmy.md +++ b/szmgr/PGV04_geometricke_algoritmy.md @@ -1,31 +1,33 @@ -= Geometrické algoritmy -:url: ./geometricke_algoritmy/ -:page-group: pgv -:page-order: PGV04 +--- +title: "Geometrické algoritmy" +description: "TODO" +--- + +
📌 NOTE
-[NOTE] -==== 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_ -==== -[TIP] -==== -Většina algoritmů je výborně popsaná na webu předmětu link:https://is.muni.cz/auth/do/sci/UMS/el/geometricke-alg/index.html[MA017 Geometrické algoritmy] včetně interaktivních animací a ukázek. -==== +
+ +
💡 TIP
+ +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. -== Konvexní obaly +
+ +## Konvexní obaly Konvexní obal je nejmenší konvexní mnohoúhelník, který obsahuje všechny body z dané množiny bodů. -=== Naivní algoritmus +### Naivní algoritmus -Pokud hledáme konvexní obal, pak můžeme postupně vyzkoušet všechny dvojice bodů stem:[(p, q)] a pro každou ověřit, že vlevo od ní (pomocí link:../zaklady_pocitacove_grafiky[edge funkce]) neleží žádný bod. Úsečky, pro které toto platí jsou poté součástí konvexního obalu. +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 stem:[O(n^3)], kde n je počet bodů. +Tento algoritmus je velice hloupý a má složitost $O(n^3)$, kde n je počet bodů. -=== Sweep Line +### 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. @@ -34,13 +36,13 @@ Seřadíme si všechny body podle vzrůstající souřadnice X. Poté řešíme 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í link:../zaklady_pocitacove_grafiky[edge funkce]. +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] +image::./img/pgv04_hull_upperlower_invalid.png[width=400] -Tento algoritmus má složitost stem:[O(n \log n)], kde n je počet bodů. +Tento algoritmus má složitost $O(n \log n)$, kde n je počet bodů. -=== Gift wrapping +### 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. @@ -50,60 +52,60 @@ Vybereme bod s nejmenší souřadnicí X a přidáme ho do konvexního obalu. Po 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 stem:[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 stem:[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ž stem:[O(\log n)]). +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 +### 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) +- **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 +### 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_ <>. +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 stem:[(x, y, z)] - * Nejvzdálenější bod od tohoto bodu - * Nejvzdálenější bod od této hrany + - 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) + - 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. -image::./img/pgv04_hull_3d.png[width=500] +![width=500](./img/pgv04_hull_3d.png) -Tento algoritmus má složitost stem:[O(n \log n)], kde n je počet bodů. +Tento algoritmus má složitost $O(n \log n)$, kde n je počet bodů. -== Voroného diagramy +## 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žší. -image::./img/pgv04_voronoi.png[width=300] +![width=300](./img/pgv04_voronoi.png) -=== Naivní algoritmus +### 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 stem:[O(n \log n)] (kvůli hledání průniku) a celková složitost je stem:[O(n^2 \log n)]. +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 +### Inkrementální algoritmus -Tento algoritmus je založen na postupném přidávání bodů (Doporučuji kouknout na link:https://www.youtube.com/watch?v=By_VJMXKVXk[toto video]). Vybereme počáteční bod a postupně přidáváme body. Pro každý bod uděláme následující: +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 stem:[O(n^2)]. +Tento algoritmus má složitost $O(n^2)$. -=== Divide and conquer +### 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. -image::./img/pgv04_voronoi_divide.png[width=400] +![width=400](./img/pgv04_voronoi_divide.png) Separating chain vytvoříme následovně: @@ -113,54 +115,54 @@ Separating chain vytvoříme následovně: 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 stem:[O(n \log n)]. +Tento algoritmus má složitost $O(n \log n)$. -=== Sweep Line +### 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. -image::./img/pgv04_voronoi_sweep.png[width=400] +![width=400](./img/pgv04_voronoi_sweep.png) 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 +- **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 link:https://is.muni.cz/auth/do/sci/UMS/el/geometricke-alg/pages/09-diagramy.html[Geometrických algoritmů]. Tento algoritmus má složitost stem:[O(n \log n)]. +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 +### 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ů. -image::./img/pgv04_voronoi_delaunay.png[width=300] +![width=300](./img/pgv04_voronoi_delaunay.png) -== Delaunayova triangulace +## 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. -image::./img/pgv04_halfedges.png[width=400] +![width=400](./img/pgv04_halfedges.png) -=== Lokální výměna +### 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). -image::./img/pgv04_delaunay_edgeflip.png[width=500] +![width=500](./img/pgv04_delaunay_edgeflip.png) -Tento algoritmus má složitost stem:[O(n^2)]. +Tento algoritmus má složitost $O(n^2)$. -=== Inkrementální konstrukce +### 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í: @@ -170,38 +172,38 @@ Další možností je inkrementální konstrukce. Iniciálně zvolíme jednu hra Delaunayova vzdálenost se vypočítá, jako -image::./img/pgv04_delaunay_distance.png[width=400] +![width=400](./img/pgv04_delaunay_distance.png) -Tento algoritmus má složitost stem:[O(n^2)]. +Tento algoritmus má složitost $O(n^2)$. -=== Inkrementální inserce +### 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). -image::./img/pgv04_delaunay_insert.png[width=400] +![width=400](./img/pgv04_delaunay_insert.png) -=== Další algoritmy +### Další algoritmy -- *Divide and conquer* -- *Walking method* +- **Divide and conquer** +- **Walking method** -== Dualita +## 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). -image::./img/pgv04_duality.png[width=500] +![width=500](./img/pgv04_duality.png) -== Triangulace +## 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 +### 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. -image::./img/pgv04_triangulation_convex.png[width=200] +![width=200](./img/pgv04_triangulation_convex.png) -=== Triangulace monotónního mnohoúhelníka +### 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ě: @@ -209,73 +211,72 @@ Monotónní mnohoúhelník je takový mnohoúhelník, který v dané ose (např. 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. + - 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. -image::./img/pgv04_triangulation_monotonous.png[width=400] +![width=400](./img/pgv04_triangulation_monotonous.png) -=== Triangulace obecného mnohoúhelníka +### 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ů: -image::./img/pgv04_triangulation_types.png[width=400] +![width=400](./img/pgv04_triangulation_types.png) 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ě. -image::./img/pgv04_triangulation_helper.png[width=300] +![width=300](./img/pgv04_triangulation_helper.png) 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). -image::./img/pgv04_triangulation_split.png[width=300] +![width=300](./img/pgv04_triangulation_split.png) 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. -image::./img/pgv04_triangulation_merge.png[width=300] +![width=300](./img/pgv04_triangulation_merge.png) Po dokončení tohoto algoritmu bychom měli mít samé monotónní trojúhelníky, které dokážeme "dotriangulovat". -== Prostorové vyhledávání +## Prostorové vyhledávání -=== k-D stromy +### 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. +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. -image::./img/pgv04_kd_build.png[width=600] +![width=600](./img/pgv04_kd_build.png) -Složitost postavení k-D stromu je stem:[O(n \log n)]. +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 +- 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 -image::./img/pgv04_kd_search.png[width=600] +![width=600](./img/pgv04_kd_search.png) -Složitost vyhledávání v k-D stromě je stem:[O(n^{1-\frac{1}{d}} + k)], kde stem:[d] je dimenze a stem:[k] je počet prvků v dané oblasti. +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 +### Range Trees Tyto jsou značně méně probírány, proto jen obecně myšlenka: -Vytvoříme binární vyhledávácí strom stem:[T] pro vrcholy podle souřadnice X. Pro každý vrchol stem:[v] vytvoříme asociovaný vyhledávací strom stem:[T_{ass}(v)] obsahující pouze vrcholy z podstromnu tohoto bodu stem:[T(v)]. stem:[T_{ass}] je binární vyhledávací strom podle souřadnice Y. +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. -image::./img/pgv04_tass.png[width=500] +![width=500](./img/pgv04_tass.png) 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ěť: stem:[O(n \log^{d-1} n)] -- Konstrukce: stem:[O(n \log^{d-1} n)] -- Vyhledávání: stem:[O(\log^{d} n + k)] +- Paměť: $O(n \log^{d-1} n)$ +- Konstrukce: $O(n \log^{d-1} n)$ +- Vyhledávání: $O(\log^{d} n + k)$ -[bibliography] -== Zdroje +## Zdroje -* [[[so_hull_3d,1]]] https://stackoverflow.com/a/74968910/22953817 \ No newline at end of file +- [[[so_hull_3d,1]]] https://stackoverflow.com/a/74968910/22953817 diff --git a/szmgr/PGV05_deleni_prostoru_a_sceny.md b/szmgr/PGV05_deleni_prostoru_a_sceny.md index c52f44e..95aead3 100644 --- a/szmgr/PGV05_deleni_prostoru_a_sceny.md +++ b/szmgr/PGV05_deleni_prostoru_a_sceny.md @@ -1,14 +1,15 @@ -= Techniky dělení prostoru a scény -:url: ./deleni_prostoru_a_sceny/ -:page-group: pgv -:page-order: PGV05 +--- +title: "Techniky dělení prostoru a scény" +description: "TODO" +--- + +
📌 NOTE
-[NOTE] -==== 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_ -==== + +
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šší. @@ -16,116 +17,115 @@ Hierarchické reprezentace zjednodušují výpočet, pokud jsou dva objekty dale Existují dva základní přístupy k tomuto problému: -== Prostorové dělení scény (Spatial decomposition of the scene) +## 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á. -image::./img/pgv05_space_sub.png[width=600] +![width=600](./img/pgv05_space_sub.png) -=== Uniformní dělení prostoru +### 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. +- **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. -Prostorová složitost:: -Pro 3D scénu s rozlišením stem:[n] v každé dimenzi potřebujeme stem:[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, 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í. -image::./img/pgv05_octree.png[width=600] +![width=600](./img/pgv05_octree.png) -Složitost vytvoření Octree/Quadtree je stem:[O(n \log n)]. Složitost vyhledávání je stem:[O(\log n)] (jako v libovolném stromu). Složitost detekce kolizí je v nejhorším případě stem:[O(n)]. +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 +### k-D stromy -(Převzato z 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. +(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. -image::./img/pgv04_kd_build.png[width=600] +![width=600](./img/pgv04_kd_build.png) -Složitost postavení k-D stromu je stem:[O(n \log n)]. +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 +- 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 -image::./img/pgv04_kd_search.png[width=600] +![width=600](./img/pgv04_kd_search.png) -Složitost vyhledávání v k-D stromě je stem:[O(n^{1-\frac{1}{d}} + k)], kde stem:[d] je dimenze a stem:[k] je počet prvků v dané oblasti. +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 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. -image::./img/pgv05_bsp.png[width=600] +![width=600](./img/pgv05_bsp.png) 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ž stem:[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ž stem:[O(n^3)]). +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) -== 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 -image::./img/pgv05_b_volumes.png[width=600] +- 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 + +![width=600](./img/pgv05_b_volumes.png) -=== Sphere Bounding Volume +### Sphere Bounding Volume -- Velice jednoduchý a rychlý test kolizí (stem:[(c_1 - c_2) \cdot (c_1 - c_2) \leq (r_1 + r_2)^2]). +- 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 stem:[\frac{B-C}{2}] - * Pro každý bod v objektu upravíme kouli tak, aby obsahovala i tento bod + - 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 -image::./img/pgv05_sphere.png[width=400] +![width=400](./img/pgv05_sphere.png) -=== Axis-Aligned Bounding Box (AABB) +### 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) +### 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ňů. -image::./img/pgv05_kdop.png[width=600] +![width=600](./img/pgv05_kdop.png) -=== Oriented Bounding Box (OBB) +### 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ší (stem:[O(n \log n)] pro jeden objekt, stem:[O(n \log^2 n)] pro celý strom). +- 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 +### Konvexní obaly - Nejmenší konvexní mnohostěn, který obaluje daný objekt. -- Pro vytvoření využijeme algoritmus QuickHull (složitost stem:[O(n \log n)]). +- Pro vytvoření využijeme algoritmus QuickHull (složitost $O(n \log n)$). - -=== Hierarchie objemových ohraničení +### 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. -image::./img/pgv05_volume_hierarchy.png[width=400] +![width=400](./img/pgv05_volume_hierarchy.png) 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). @@ -135,31 +135,26 @@ Snažíme se konstruovat hierarchie tak, aby: - testování kolizí bylo co nejrychlejší - bylo třeba je co nejméně aktualizovat - -== Detekce kolizí +## 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 link:https://www.youtube.com/watch?v=EB6NY5sGd08[SethBlingovo video]. - -image::./img/pgv05_sat.png[width=400] +- **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ší. +![width=400](./img/pgv05_sat.png) -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. +- **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. -image::./img/pgv05_swept_sphere.png[width=400] +![width=400](./img/pgv05_swept_sphere.png) -== Vykreslování +## 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 - -[bibliography] -== Zdroje - -* [[[pgv04,1]]] ../geometricke_algoritmy/ \ No newline at end of file +- [[[pgv04,1]]] ../geometricke_algoritmy/ diff --git a/szmgr/PGV06_vykreslovani_objemovych_dat.md b/szmgr/PGV06_vykreslovani_objemovych_dat.md index c02b8a4..2f7a0e5 100644 --- a/szmgr/PGV06_vykreslovani_objemovych_dat.md +++ b/szmgr/PGV06_vykreslovani_objemovych_dat.md @@ -1,214 +1,206 @@ -= Vykreslování objemových dat -:url: ./vykreslovani_objemovych_dat/ -:page-group: pgv -:page-order: PGV06 +--- +title: "Vykreslování objemových dat" +description: "TODO" +--- + +
📌 NOTE
-[NOTE] -==== Rekonstrukce povrchu - kontury, objem, bodový mrak. Algoritmus pochodujících kostek. Přímé vykreslování objemových dat. _PB009, PA010, PA213_ -==== -[TIP] -==== +
+ +
💡 TIP
+ Většina obsahu převzata z původní otázky VPH01 Pokročilá počítačová grafika -==== -== Bodový mrak (point cloud) +
+ +## 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. +- 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ů +### 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 stem:[n = \arg \min_{|n| = 1} \sum_{i=1}^k ((p_i - p) \cdot n)^2 ]. <> -+ -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í. -+ -image::./img/pgv06_splatting.png[width=400] -+ -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ů. -+ -image::./img/pgv06_splatting2.png[width=600] - -=== 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ů. <> -+ -image::./img/vph01_delaunay.svg[width=300] -+ -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. -+ -<> 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. <> -+ -.Příklady meshe pro různé hodnoty Alpha -image::./img/pgv06_alpha_shapes.png[width=600] - -Aproximace implicitní funkcí:: -Uvažujme implicitní funkci stem:[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. -+ -image::./img/pgv06_implicit.png[width=400] - -== 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 link:https://commons.wikimedia.org/wiki/File:MarchingCubesEdit.svg[Ryoshoru] (16. varianta je, pokud všechny body leží uvnitř) -image::./img/vph01_marching_cubes.svg[width=500rem] -+ -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. <> -+ -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). <> - -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ší. -+ -image::./img/pgv06_surface_nets.png[width=500] - -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. <> -+ -image::./img/pgv06_dual_contouring.png[width=500] - - -=== 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ů. <> +- 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í. + + ![width=400](./img/pgv06_splatting.png) + + 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ů. + + ![width=600](./img/pgv06_splatting2.png) + +### 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) + + ![width=300](./img/vph01_delaunay.svg) + + 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** + + ![width=600](./img/pgv06_alpha_shapes.png) + +- **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. + + ![width=400](./img/pgv06_implicit.png) + +## 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ř)** + + ![width=500rem](./img/vph01_marching_cubes.svg) + + 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ší. + + ![width=500](./img/pgv06_surface_nets.png) + +- **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) + + ![width=500](./img/pgv06_dual_contouring.png) + +### 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 <> -image::./img/vph01_direct_volume_rendering.jpg[width=500rem] - -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: <> -+ --- -* stem:[\kappa] je funkce absorpce, -* stem:[q] je emise. --- - -Optická hloubka / optical depth:: -Bezrozměrná veličina stem:[\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 stem:[s_1] a stem:[s_2] na paprsku je dána jako: -+ -[stem] -++++ -\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 stem:[s_1] a stem:[s_2] na paprsku je dána jako: -+ -[stem] -++++ -\theta(s_1, s_2) = e^{-\tau(s_1, s_2)} -++++ - -Volume rendering integral:: -Intenzitu světla stem:[I] v místě paprsku stem:[s] počítáme pomocí: <> -+ -[stem] -++++ -\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: -+ --- -* stem:[s_0] je místo, kde se paprsek dostal dovnitř nějakého světlo-vyzařujícího objemu, -* stem:[I(s_0)] je boundary light, tedy světlo na hranici objemu, -* stem:[q(s')] je emise v bodě stem:[s']. --- -+ -image::./img/vph01_emission_absorption_model.png[width=500] - -Back-to-front:: -Přístup k počítání stem:[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í stem:[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 stem:[T], která mapuje hodnoty voxelů na barvu a průhlednost. Klasifikuje voxely. <> - -[bibliography] -== Zdroje - -* [[[pa010-2020,1]]] Sochor: PA010 Intermediate Computer Graphics (podzim 2020) -* [[[pa213, 2]]] PA213 Advanced Computer Graphics -* [[[marching-cubes,3]]] link:https://dl.acm.org/doi/10.1145/37402.37422[Marching cubes: A high resolution 3D surface construction algorithm] -* [[[marching-tetrahedra,4]]] link:https://en.wikipedia.org/wiki/Marching_tetrahedra[Wikipedia: Marching tetrahedra] -* [[[dual-contouring,5]]] link:https://www.boristhebrave.com/2018/04/15/dual-contouring-tutorial/[Dual Contouring Tutorial] -* [[[delaunay-triangulation,6]]] link:https://en.wikipedia.org/wiki/Delaunay_triangulation[Wikipedia: Delaunay triangulation] -* [[[gpugems,7]]] link:https://developer.nvidia.com/gpugems/gpugems/part-vi-beyond-triangles/chapter-39-volume-rendering-techniques[GPU Gems: Volume Rendering Techniques] \ No newline at end of file +**The Process of Volume Rendering [gpugems](#gpugems)** + +![width=500rem](./img/vph01_direct_volume_rendering.jpg) + +- **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'$. + + ![width=500](./img/vph01_emission_absorption_model.png) + +- **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) diff --git a/szmgr/PGV07_modely_osvetleni.md b/szmgr/PGV07_modely_osvetleni.md index 75ad96a..049289b 100644 --- a/szmgr/PGV07_modely_osvetleni.md +++ b/szmgr/PGV07_modely_osvetleni.md @@ -1,90 +1,85 @@ -= Lokální a globální modely osvětlení -:url: ./modely_osvetleni/ -:page-group: pgv -:page-order: PGV07 +--- +title: "Lokální a globální modely osvětlení" +description: "TODO" +--- + +
📌 NOTE
-[NOTE] -==== 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_ -==== -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. +
+ +- **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ů. -Globální osvětlení (global illumination):: -Řeší nejen přímé osvětlení, ale i odrazy, lomy, průhlednost, stíny, atd. + Patří sem Blinn-Phong, pomineme-li jeho ambientní složku. -Ambient illumination:: -Aproximace globálního osvětlení pomocí konstantní ambientní barvy. +- **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 -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í. <> +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) -image::./img/pgv07_phong_overview.png[width=600] +![width=600](./img/pgv07_phong_overview.png) -=== Ambientní osvětlení +### 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. -image:./img/pgv07_phong_ambient1.png[width=300] -image:./img/pgv07_phong_ambient2.png[width=200] +![width=300](./img/pgv07_phong_ambient1.png) +![width=200](./img/pgv07_phong_ambient2.png) -=== Difuzní osvětlení +### Difuzní osvětlení -Difuzní osvětlení je závislé na úhlu stem:[\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). +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). -image::./img/pgv07_phong_diffuse1.png[width=600] -image:./img/pgv07_phong_diffuse2.png[width=500] -image:./img/pgv07_phong_diffuse3.png[width=300] +![width=600](./img/pgv07_phong_diffuse1.png) +![width=500](./img/pgv07_phong_diffuse2.png) +![width=300](./img/pgv07_phong_diffuse3.png) -=== Spekulární osvětlení +### Spekulární osvětlení -Spekulární osvětlení vytváří odlesky na povrchu objektu. Je závislé na úhlu stem:[\beta] mezi vektorem ke světlu a vektorem ke kameře. +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. -image::./img/pgv07_phong_specular1.png[width=600] -image:./img/pgv07_phong_specular2.png[width=500] -image:./img/pgv07_phong_specular3.png[width=300] +![width=600](./img/pgv07_phong_specular1.png) +![width=500](./img/pgv07_phong_specular2.png) +![width=300](./img/pgv07_phong_specular3.png) -=== Všechno dohromady +### 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. -stem:[C=A+\sum_{i=1}^{n} (D_i + S_i)] +$C=A+\sum_{i=1}^{n} (D_i + S_i)$ A pokud dosadíme i konkrétní vzorce dostaneme následující rovnici: -image::./img/pgv07_phong_equation.png[width=600] +![width=600](./img/pgv07_phong_equation.png) Uvedené podmínky jsou v rovnici pro odstranění odlesků na zadní straně objektu. - -== Bidirectional Reflectance Distribution Function (BRDF) +## Bidirectional Reflectance Distribution Function (BRDF) Funkce popisující poměr mezi dopajícím a odraženým světlem na povrchu objektu. -[stem] -++++ +```math f(\vec{l}, \vec{v}) = \frac{\partial L_o(\vec{v})}{\partial E_i(\vec{l})} -++++ +``` -_Povrch je nasvícen ze směru stem:[\vec{l}] s ozářením stem:[\partial E(\vec{l})]. stem:[\partial(L_o(\vec{v}))] je odražená zář ve směru stem:[\vec{v}]._ +_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}$._ -[TIP] --- -Udává pravděpodobnost, že světlo dopadající na povrch ze směru stem:[\vec{l}] bude odraženo ve směru stem:[\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ů) -== 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: @@ -95,178 +90,163 @@ Obecný postup: 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. -image::./img/pgv07_raytracing.png[width=500] +![width=500](./img/pgv07_raytracing.png) 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 stem:[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. -+ -stem:[frac{\sin \alpha'}{\sin \alpha} = \frac{n_1}{n_2}] -+ -image::./img/pgv07_snell.png[width=300] +- **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}$ + + ![width=300](./img/pgv07_snell.png) + +## Radiosity (metoda osvětlení) -== 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). -stem:[KB = E] +$KB = E$ -Vytvoříme matici stem:[K], kde stem:[K_{ij}] je množství světla, které se přelilo z segmentu stem:[i] do segmentu stem:[j] (form faktor stem:[K_{ij} = F_{ij}]). Zároveň máme vektor stem:[E], který určuje emitované světlo v každém segmentu. Výsledný vektor stem:[B] je vektor světla v každém segmentu. +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í. -image::./img/pgv07_radiosity.png[width=500] - +![width=500](./img/pgv07_radiosity.png) -== Fotonové mapy +## 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). -image::./img/pgv07_photonmap.png[width=600] - +![width=600](./img/pgv07_photonmap.png) -== Participující média +## 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) - -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. <> 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: -+ -[stem] -++++ -F_\text{Schlick}(F_0, L, N) = F_0 + (1 - F_0) \cdot (1 - L \cdot N)^5 -++++ -+ -kde: -+ --- -* stem:[F_0] je Fresnelův odraz při úhlu 0 (dá se dohledat pro daný materiál), -* stem:[L] je vektor směru světla, -* stem:[N] je vektor normály povrchu. --- -+ -.Z určitého úhlu se povrchy, které normálně světlo odráží špatně, jeví jako zrcadla (link:https://commons.wikimedia.org/w/index.php?curid=2138545[tanakawho]) -image::./img/vph01_fresnel.jpg[width=300] - -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: -+ -[stem] -++++ -\frac{\sin \alpha_1}{\sin \alpha_2} = \frac{v_1}{v_2} = \frac{n_2}{n_1} -++++ -+ -kde: -+ -* stem:[\alpha_1] je úhel dopadu (angle of incidence), -* stem:[\alpha_2] je úhel lomu (angle of refraction), -* stem:[v_1] je rychlost šíření vlnění ve vnějším prostředí, -* stem:[v_2] je rychlost šíření vlnění v prostředí objektu, -* stem:[n_1] je index lomu vnějšího prostředí, -* stem:[n_2] je index lomu prostředí objektu. -+ -image::./img/vph01_snell.svg[width=500rem] - -Diffuse lighting:: -Když všechno (neabsorbované) světlo opustí objekt ze stejného místa, kam dopadlo. -+ -image::./img/vph01_diffuse.png[width=500rem] - -Subsurface scattering:: -Když neabsorbované světlo opustí objekt z jiného místa, než kam dopadlo. -+ -image::./img/vph01_subsurface_scattering.png[width=500rem] - -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). -+ -image::./img/vph01_microfacets.png[width=500rem] -+ -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ý (stem:[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 (stem:[\Phi]):: -"Energy per second." Bezva na popisování síly světel jako jsou žárovky, plošná světla, atd. -+ -[stem] -++++ -\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. -+ -[stem] -++++ -E = \frac{\partial \Phi}{\partial A} -++++ -+ -Jednotka: Watt per square meter (stem:[\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. -+ -[stem] -++++ -L = \frac{\partial^2 \Phi}{\partial A_\text{proj} \partial \omega} -++++ -+ -Jednotka: Watt per square meter per steradian (stem:[\frac{W}{m^2 \cdot sr}]) - - -== Image-based lighting (IBL) - -[NOTE] -==== -Tahle část otázky by si možná zasloužila rozšířit, ale bohužel tomu víc nerozumím :D -==== +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ů. -IBL využívá envitornmentálních textur (HDR CubeMap, ...) pro vyhodnocení světla z každého směru scény. +- **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: -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. + ```math + F_\text{Schlick}(F_0, L, N) = F_0 + (1 - F_0) \cdot (1 - L \cdot N)^5 + ``` -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. + 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))** + + ![width=300](./img/vph01_fresnel.jpg) + +- **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. + + ![width=500rem](./img/vph01_snell.svg) + +- **Diffuse lighting**\ + Když všechno (neabsorbované) světlo opustí objekt ze stejného místa, kam dopadlo. + + ![width=500rem](./img/vph01_diffuse.png) + +- **Subsurface scattering**\ + Když neabsorbované světlo opustí objekt z jiného místa, než kam dopadlo. + + ![width=500rem](./img/vph01_subsurface_scattering.png) -image::./img/pgv07_ibr.png[width=600] +- **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). + ![width=500rem](./img/vph01_microfacets.png) + 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) + +
📌 NOTE
+ +Tahle část otázky by si možná zasloužila rozšířit, ale bohužel tomu víc nerozumím :D + +
+ +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. +![width=600](./img/pgv07_ibr.png) -[bibliography] -== Zdroje +## Zdroje -* [[[pv227-2022, 1]]] link:https://is.muni.cz/auth/el/fi/podzim2022/PV227/[PV227 GPU Rendering (podzim 2022)] -* [[[pb009-io, 2]]] link:https://is.muni.cz/auth/el/fi/jaro2023/PB009/index.qwarp[Interaktivní osnova PB009 by xrosecky] \ No newline at end of file +- [[[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) diff --git a/szmgr/PGV08_real_time_rendering.md b/szmgr/PGV08_real_time_rendering.md index c20fd6e..dd1338c 100644 --- a/szmgr/PGV08_real_time_rendering.md +++ b/szmgr/PGV08_real_time_rendering.md @@ -1,51 +1,57 @@ -= Vykreslování v reálném čase -:url: ./real_time_rendering/ -:page-group: pgv -:page-order: PGV08 +--- +title: "Vykreslování v reálném čase" +description: "TODO" +--- + +
📌 NOTE
-[NOTE] -==== 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_ -==== -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. +
+ +- **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) -== 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 +### 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 +### 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á. +## Analýza viditelnosti -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á. +- **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é. -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. + 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 -=== 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. -image::./img/pgv08_portal_culling.png[width=700] +![width=700](./img/pgv08_portal_culling.png) -geometrie stem:[\pi_{i,j} = \pi_{j,i}] +geometrie $\pi_{i,j} = \pi_{j,i}$ Toto všechno je předpočítané. -**V každém snímku:** +**_V každém snímku:_** 1. Spočítáme, ve které místnosti se nachází kamera 2. Vyrenderujeme tuto místnost @@ -56,200 +62,188 @@ Toto všechno je předpočítané. 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í. -image::./img/pgv08_portal_culling_algorithm.png[width=800] +![width=800](./img/pgv08_portal_culling_algorithm.png) 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 +### 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. -image::./img/pgv08_hardware_oclusion_query.png[width=600] +![width=600](./img/pgv08_hardware_oclusion_query.png) 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). +- **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 +## 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) +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). +### Generování -Další metody výběru:: -Podle důležitosti, pohyb, focus, ... - -=== Přepínání +Typicky z detailnějšího modelu vytváříme méně detailní -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) +- 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ů) -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. +### Výběr -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! +- **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, ... -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ě). +### Přepínání -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á. -+ -image::./img/pgv08_geomorph.png[width=600] +- **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á. + ![width=600](./img/pgv08_geomorph.png) -== Vykreslování terénu +## 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ž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 +### 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. +- **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. -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 Mesh už je množina trojúhelníků, které prostě vykreslíme na GPU. -=== Heightmap +### 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) -image::./img/pgv08_heightmap.png[width=600] +![width=600](./img/pgv08_heightmap.png) Může nastat problém s nejednoznačností (_ambiguity_). Ta se většinou ignoruje. -image::./img/pgv08_ambiguity.png[width=300] +![width=300](./img/pgv08_ambiguity.png) Výslednou mesh můžeme vyrenderovat, jako triangle strips. -=== Voxely +### 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í +### 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. +- **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. -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. + ![width=600](./img/pgv08_triangle_bintree.png) -Triangle Bintree:: -Dělí trojúhelníky víc a víc, čím blíže jsou ke kameře. CPU musí upravovat mesh. -+ -image::./img/pgv08_triangle_bintree.png[width=600] +- **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. -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. -+ -image::./img/pgv08_clipmaps.png[width=600] + 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í. + ![width=600](./img/pgv08_clipmaps.png) +- **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ů +## 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. -+ -image:./img/vph01_hard_shadows.png[width=30%] -image:./img/vph01_hard_shadows_schema.png[width=69%] - -Soft shadows / "měkké" stíny:: -Rozlišují i částečně osvětlené oblasti. Týká se světel, která mají plochu. -+ -image:./img/vph01_soft_shadows.png[width=30%] -image:./img/vph01_soft_shadows_schema.png[width=69%] - -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. -+ -image::./img/vph01_shadow_maps.png[width=500rem] -+ -IMPORTANT: Shadow mapám se důkladně věnuje otázka link:../renderovani-s-vyuzitim-gpu/[Renderování s využitím 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ý. -+ -image::./img/vph01_shadow_volumes.png[width=500rem] -+ -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. - -[bibliography] -== Zdroje - -* [[[pa010-2021,1]]] Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021) \ No newline at end of file +- 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. + + ![width=30%](./img/vph01_hard_shadows.png) + ![width=69%](./img/vph01_hard_shadows_schema.png) + +- **Soft shadows / "měkké" stíny**\ + Rozlišují i částečně osvětlené oblasti. Týká se světel, která mají plochu. + + ![width=30%](./img/vph01_soft_shadows.png) + ![width=69%](./img/vph01_soft_shadows_schema.png) + +- **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. + + ![width=500rem](./img/vph01_shadow_maps.png) + + **❗ 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ý. + + ![width=500rem](./img/vph01_shadow_volumes.png) + + 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) diff --git a/szmgr/PGV09_minimalizace_energie.md b/szmgr/PGV09_minimalizace_energie.md index ce30763..0829e77 100644 --- a/szmgr/PGV09_minimalizace_energie.md +++ b/szmgr/PGV09_minimalizace_energie.md @@ -1,44 +1,37 @@ -= Zpracování obrazu pomocí minimalizace energie -:url: ./minimalizace_energie/ -:page-group: pgv -:page-order: PGV09 +--- +title: "Zpracování obrazu pomocí minimalizace energie" +description: "TODO" +--- + +
📌 NOTE
-[NOTE] -==== Variační filtrování. Aktivní křivky a plochy (geodetický model, Chan-Vese model). Minimalizace pomocí grafových řezů. Variační optický tok. _PA166_ -==== -include::./PGV_zpracovani_obrazu_intro.ad[] +
+ +## Variační filtrování -== 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 -[stem] -++++ +```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 stem:[\alpha]. Regularizer stem:[\Psi] určuje “metodu” vyhlazení: +``` -[cols="1,2"] -|=== -|**Tikhonov (linear)** -- identita -|stem:[\Psi(\lvert \nabla u \rvert^2) = \lvert \nabla u \rvert^2] +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í: -|**Charbonnier** -|stem:[\Psi(\lvert \nabla u \rvert^2) = 2 \lambda^2 \sqrt{1 + \lvert \nabla u \rvert^2 / \lambda^2} - 2 \lambda^2] - -|**Total Variation** -|stem:[\Psi(\lvert \nabla u \rvert^2) = 2\sqrt{\lvert \nabla u \rvert^2} = 2\lvert\nabla u\rvert] -|=== +| | | +| ----------------------------------- | ------------------------------------------------------------------------------------------------------------ | +| **_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) +### 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. @@ -46,255 +39,247 @@ Pokud je obraz 2D, bereme všechny pixely jako dlouhou 1D posloupnost a řeším 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í +### 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 stem:[u(x) \Rightarrow \mathbb{R}]. +- **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 stem:[E_f(u) = \int_{\Omega} ( (u - f)^2 + \alpha \Psi (| \nabla u |^2) ) dxdy] získáme předpis pro minimalizaci: +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: -[stem] -++++ +```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 link:../zpracovani_obrazu_pomoci_PDE[PGV10]): +``` -[cols="1,2"] -|=== -|**Variační metoda** -|stem:[\frac {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)): -|**Difuzní filtrování** -|stem:[\partial_t u = \text{div}(\Psi'(\lvert \nabla u \rvert^2) \nabla u)] -|=== +| | | +| ------------------------ | ------------------------------------------------------------------------------ | +| **_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* - * stem:[\Psi(\lvert \nabla u \rvert^2) = \lvert \nabla u \rvert^2] - * stem:[\Psi'(\lvert \nabla u \rvert^2) = 1] -- *Charbonnier regulariser* ~ *Charbonnier diffusivity* - * stem:[\Psi(\lvert \nabla u \rvert^2) = 2 \lambda^2 \sqrt{1 + \lvert \nabla u \rvert^2 / \lambda^2} - 2 \lambda^2] - * stem:[\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 stem:[\frac{1}{\lvert \nabla u \rvert}] - * stem:[\Psi(\lvert \nabla u \rvert^2) = 2\lvert\nabla u\rvert] - * stem:[\Psi'(\lvert \nabla u \rvert^2) = \frac{1}{\lvert \nabla u \rvert}] +- **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 -== 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 stem:[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: +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: -[stem] -++++ +```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: -Kde stem:[E_{int}] je *vnitřní energie*, kde stem:[\alpha] a stem:[\beta] jsou váhy pro délku (stem:[\alpha]) a křivost (stem:[\beta]) křivky: -+ -[stem] -++++ +- + +```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: + +- -A stem:[E_{ext}] je *vnější energie*, kde stem:[P] je potenciální funkce: -+ -[stem] -++++ +```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* - stem:[P(x, y) = -\lvert \nabla f(x, y) \rvert^2] -- *Hrany po rozmazání* - stem:[P(x, y) = -\lvert \nabla (G_{\sigma}(x, y) * f(x, y) )\rvert^2] -- *Linie* - stem:[P(x, y) = -f(x, y)] -- *Linie po rozmazání* - stem:[P(x, y) = -G_{\sigma}(x, y) * f(x, y)] --- +``` + +- **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: -[stem] -++++ +```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 stem:[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ě stem:[\frac{\partial p}{\partial t} = F_{int}(p) + F_{ext}(p)\\p(s, 0) = p_0(s)] +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:: +- **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 + - 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 + - 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 + - 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) -+ -image::./img/pgv09_fixing_active.png[width=400] - + + - 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) + + ![width=400](./img/pgv09_fixing_active.png) + - 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 -+ -stem:[$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í + + - 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 -+ -image::./img/pgv09_gvf.png[width=600] - - 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 -+ -image::./img/pgv09_gvf2.png[width=600] +- Kontury mají problém opsat “tvar rohlíku” a nic je nenutí dostávat se do úzkých prostor + + ![width=600](./img/pgv09_gvf.png) + +- 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 + ![width=600](./img/pgv09_gvf2.png) + +### 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_): + -[stem] -++++ + +```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 stem:[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: + -[stem] -++++ +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 -=== 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. -[stem] -++++ +```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; stem:[\Omega_1, \Omega_2]) od konstantního odhadu stem:[c_1, c_2] -- Parametry stem:[\mu, \lambda_1, \lambda_2] určují vyhlazení, variabilitu pozadí a popředí respectively -- Pro danou křivku C jsou optimální stem:[c_1, c_2] s průměrnou hodnotou +- **_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: -[stem] -++++ +```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ů +## 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. -image::./img/pgv09_graph_cuts.png[width=600] +![width=600](./img/pgv09_graph_cuts.png) -Riemannovy metrické systémy:: -Normálně, když počítáme délku mezi dvěma body, počítáme ji, jako stem:[d = \sqrt{u^T \cdot u}]. Můžeme ale přidat tzv. metrický tensor stem:[M], který může tuto délku upravit v závislosti na směru stem:[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* - stem:[M = I] (identita) -- *Geodetickou vzdálenost* - stem:[M = \text{diag}(g(\lvert \nabla I(\cdot) \rvert))] -- *Anizotropní vzdálenost* - stem:[M = g(\lvert \nabla I(\cdot) \rvert) \cdot E + (1 - g(\lvert \nabla I(\cdot) \rvert)) \cdot u \cdot u^T] (kde stem:[u = \frac{\nabla I}{\lvert \nabla I \rvert}] jednotkový vektor ve směru gradientu a stem:[E] je identita) --- +- **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: -[stem] -++++ +```math w_k^R = w_k^{\epsilon} \cdot \frac{\text{det} M}{(u_k^T \cdot M \cdot u_k)^{p}} -++++ +``` + +### Geodetická segmentace -=== 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 +- **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 -=== 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 stem:[c_1, c_2] pro popředí a pozadí. Nastavme tedy váhy: +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* - stem:[w_{si} = \lambda_2(f(i) - c_2)^2 \text{, } w_{it} = \lambda_1(f(i) - c_1)^2] -- *n-linky* - podle Riemannovy metriky +- **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 stem:[w_{si}, w_{it}] jsou závislé na stem:[c_1, c_2]. Typicky řešíme tak, že si tipneme, provedeme iteraci, aktualizujeme a jedem znovu +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 -== Variační optický tok -Pro sekvenci obrázků stem:[f(x,y,t)] chceme získat vektor posunutí stem:[(u(x,y,t),v(x,y,t))^T] každého místa obrázku. +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** - stem:[f(x+u, y+v, t+1)=f(x,y,t)] (posunutý pixel se rovná neposunutému) +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 - -[stem] -++++ + +```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) -stem:[f_x u+f_y v + f_t = 0] (stem:[\nabla f \cdot (u,v) + f_t = 0])** - +$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) -image:./img/pgv09_nonuniqueness.svg[width=500] - -Taky protože stem:[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 + +![width=500](./img/pgv09_nonuniqueness.svg) + +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) +### Lukas a Kanade (Lokální metoda) + Přidává 3. předpoklad: - Zachování jasu - Malé změny -- *Konstantnost toku v okolí stem:[B_\rho] každého bodu* +- **Konstantnost toku v okolí $B_\rho$ každého bodu** Chceme minimalizovat následující lokální energii (integrál přes okolí) -[stem] -++++ +```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 -[stem] -++++ +```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 @@ -313,12 +298,11 @@ v -\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í" -[stem] -++++ +```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) @@ -332,7 +316,7 @@ v -G_{\sigma} * (f_x f_t) \\ -G_{\sigma} * (f_y f_t) \end{pmatrix} -++++ +``` Snadno vyřešíme Cramerovým pravidlem @@ -346,28 +330,27 @@ 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) +### Horn-Schunck (Globální metoda) Pouze dva přepoklady: -- Zachování jasu - stem:[f_x u+f_y v + f_t = 0] -- Malé změny (Gradient vektorového pole je malý) - stem:[\int_{\Omega} ( \lvert \nabla u \rvert^2 + \lvert \nabla v \rvert^2) dx dy] je malé +- 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 -[stem] -++++ +```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í stem:[\alpha] +- 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é \ No newline at end of file +- Celkem pomalé a drahé diff --git a/szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md b/szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md index 084bc39..8506d5a 100644 --- a/szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md +++ b/szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md @@ -1,197 +1,185 @@ -= Zpracování obrazu pomocí PDE -:url: ./zpracovani_obrazu_pomoci_PDE/ -:page-group: pgv -:page-order: PGV10 +--- +title: "Zpracování obrazu pomocí PDE" +description: "TODO" +--- + +
📌 NOTE
-[NOTE] -==== 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_ -==== -include::./PGV_zpracovani_obrazu_intro.ad[] +
+ +- **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. -Divergence:: -Operace, která nám říká, jak moc vektorové pole míří ven z daného bodu. Pokud je stem:[\text{div} j > 0], pak se v daném bodě hodnota časem snižuje, pokud je stem:[\text{div} j < 0], pak se hodnota zvyšuje. -+ -stem:[\text{div} j = \nabla^T j = (\partial_x, \partial_y) \cdot (j_1, j_2) = \partial_x j_1 + \partial_y j_2]. + 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}$. -Laplacian stem:[\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: stem:[\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 -== Difuze -Imituje šíření tepla v 1D tyči / 2D ploše / ... Řídí se také rovnicí pro šíření tepla: stem:[u_t = \Delta u = u_{xx} + u_{yy}] (kde stem:[\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: +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). -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)*. +- 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: -image::./img/pgv10_diff_types.svg[width=400] +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)**. + +![width=400](./img/pgv10_diff_types.svg) + +### Lineární difuze -=== 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)$ +- **_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 stem:[u_{ij}^{k + 1}] pomocí aproximace Taylorova rozvoje: +Chceme vypočítat $u_{ij}^{k + 1}$ pomocí aproximace Taylorova rozvoje: -[stem] -++++ +```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 stem:[u_{ij}^{k + 1}]. (stem:[\Delta t] je časový krok, stem:[\Delta x] a stem:[\Delta y] jsou prostorové kroky) - -=== Nelineární izotropní difuze - -Zobecníme funkci pro difuzi kombinací Fick’s law a Mass preservation: stem:[\partial_t u = \text{div} (g \cdot \nabla u)], kde stem:[\div] je divergence. - -- *Lineární* - * stem:[g = 1] - * Rozmazání ve všech bodech stejně ve všech směrech -- *Nelineární izotropní* - * stem:[g =] skalární funkce - * Rozmazání stejně ve všech směrech, ale v každém bodě jinak -- *Nelineární anizotropní* - * stem:[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 stem:[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:: -stem:[g(\nabla u) = \frac{1}{1 + |\nabla u|^2 / \lambda^2}]. - -Charbonnier difuzivita:: -stem:[g(\nabla u) = \frac{1}{\sqrt{1 + |\nabla u|^2 / \lambda^2}}]. - -Exponenciální difuzivita:: -stem:[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ť stem:[g] je v tomto případě matice. - -Symetrická matice:: -Reprezentuje otočení, roztažení a otočení zpátky: -+ -[stem] -++++ -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á --- -+ -image::./img/pgv10_sym_matrix.png[width=500] +``` + +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á + + ![width=500](./img/pgv10_sym_matrix.png) 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: -+ -[stem] -++++ -v_1 \parallel \nabla u_\sigma, \lambda_1 = g(|\nabla u_\sigma|^2) \\ -v_2 \perp \nabla u_\sigma, \lambda_2 = 1 -++++ -+ -Kde funkce stem:[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: -+ -[stem] -++++ -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). -+ -image::./img/pgv10_structure_tensor.png[width=600] - - -== Level set metody +- **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). + + ![width=600](./img/pgv10_structure_tensor.png) + +## 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. +- **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 stem:[\frac{\partial C}{\partial t} = \beta n] (kde stem:[n] je normála a stem:[\beta] řídí rychlost evoluce). Pokud ho chceme definovat v rámci obalující funkce stem:[u], můžeme ho zapsat, jako stem:[\partial_t u = \beta |\nabla u|]. stem:[\beta] v této rovnici ovlivňuje směr a rychlost pohybu křivky, stem:[|\nabla u|] je velikost gradientu. +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*. +**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** - stem:[\beta = a] = dilatace / eroze -- **Pohyb řízený křivostí** - stem:[\beta = - \epsilon \kappa] = vyhlazování křivky -- **Pohyb ve vnějším vektorovém poli** - stem:[\beta = V(x, y, t) \cdot n], kde stem:[V] je vnější vektorové pole --- -+ -image::./img/pgv10_motion_types.png[width=500] +- **Typy pohybu**\ + Existují 3 základní typy pohybu křivky: -Pohyb ve vnějším vektorovém poli:: -stem:[\beta = V(x, y, t) \cdot n] popisuje pohyb ve vektorovém poli definovaném parametrem stem:[V]. Aproximujeme opět pomocí Taylorova rozvoje. + - **_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 řízený křivostí:: -Chceme, aby se křivka vyhlazovala, protože křivost je vlastně druhá derivace. stem:[\beta = - \epsilon \kappa] popisuje pohyb křivky ve směru opačném k její křivosti. stem:[\kappa] je křivost a stem:[\epsilon] je parametr, který řídí rychlost vyhlazování. + ![width=500](./img/pgv10_motion_types.png) -Pohyb ve směru normály:: -Chceme, aby se křivka rozšiřovala, nebo smršťovala. stem:[\beta = a] popisuje pohyb křivky ve směru normály. stem:[a] je parametr, který řídí rychlost pohybu. +- **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: stem:[u_t = -V \cdot \nabla u - a |\nabla u| + \epsilon \kappa |\nabla u|] a aproximovat pomocí Taylorova rozvoje. +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 -=== Fast marching algoritmus -FMA je specifický případ Level set metody s pouze jedním typem pohybu ve směru normály stem:[\partial_t u = a |\nabla u|]. +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 stem:[a]. +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 stem:[a = 1]. +- **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. -Geodesická vzdálenost:: -Chceme-li změřit vzdálenost od daného bodu uvnitř objektu, zvolíme stem:[a = 1] uvnitř objektu a stem:[a \rightarrow 0] venku. -+ -image::./img/pgv10_geodesic.png[width=400] + ![width=400](./img/pgv10_geodesic.png) -Segmentace:: -Můžeme jednoduše segmentovat obraz, pokud zvolíme stem:[a = g(|\nabla f|)] (kde stem:[f] je obraz a stem:[g] je nějaká funkce, například Perona-Malik). Potom stem:[g] jde k 0 při vysokém gradientu a k 1 při nízkém gradientu. +- **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 @@ -199,8 +187,8 @@ Samotný výpočet algoritmu je trošku složitější, uděláme si 3 množiny - 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í stem:[T_{new} = \tau(v_1, v_2) + v_1 T_1 + v_2 T_2], kde stem:[\tau] je časový krok, stem:[T_1, T_2] jsou hodnoty v Known a stem:[v_1, v_2] jsou souřadnice bodu X, které chceme minimalizovat (stem:[v_1 + v_2 = 1, v_1, v_2 \geq 0]). +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 link:https://xrosecky.notion.site/PA166-Image-analysis-II-b2875a07366c404dabbf20a8b75a6e2e?pvs=74[notionu], ale myslím, že je celkem zbytečný. +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 stem:[O(n \log n)], kde stem:[n] je počet pixelů v obrazu. \ No newline at end of file +Složitost je v řádu $O(n \log n)$, kde $n$ je počet pixelů v obrazu. diff --git a/szmgr/PGV_zpracovani_obrazu_intro.md b/szmgr/PGV_zpracovani_obrazu_intro.md index 6e8a186..ab7e477 100644 --- a/szmgr/PGV_zpracovani_obrazu_intro.md +++ b/szmgr/PGV_zpracovani_obrazu_intro.md @@ -1,34 +1,35 @@ -[TIP] -==== -Doporučuju kouknout na shrnutí v link:https://xrosecky.notion.site/PA166-Image-analysis-II-b2875a07366c404dabbf20a8b75a6e2e?pvs=74[zápiscích z předmětu PA166 od xrosecky] -==== +--- +title: Zpracování obrazu - intro +description: "TODO" +--- +
💡 TIP
-Gradient stem:[\nabla]:: +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) +
+ +* **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: stem:[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): -+ -[stem] -++++ -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): -+ -[stem] -++++ -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 \ No newline at end of file + + 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 diff --git a/szmgr/SZP01_algoritmy.md b/szmgr/SZP01_algoritmy.md index 5d9497b..0b21e37 100644 --- a/szmgr/SZP01_algoritmy.md +++ b/szmgr/SZP01_algoritmy.md @@ -1,497 +1,692 @@ -= Algoritmy a datové struktury -:url: ./algoritmy-a-datove-struktury/ -:page-group: szp -:page-order: SZP01 +--- +title: "Algoritmy a datové struktury" +description: "TODO" +--- + +
📌 NOTE
-[NOTE] -==== -Pokročilé techniky návrhu algoritmů: dynamické programování, hladové strategie, backtracking. Amortizovaná analýza. +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_ -==== +
-== Pokročilé techniky návrhu algoritmů +## Pokročilé techniky návrhu algoritmů -=== Dynamické programování +### Dynamické programování -[quote,Richard Bellman,Eye of the Hurricane: An Autobiography (1984, page 159)] -____ -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. -____ +> 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. --- +- 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ší_. --- +- 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ší_. + +
💡 TIP
-[TIP] -==== 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 stem:[l] zanořených cyklů, vyřeším nejvíc stem:[n^l] podproblémů. -==== +Pokud mám $l$ zanořených cyklů, vyřeším nejvíc $n^l$ podproblémů. + +
-==== Memoizace +#### 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 stem:[M] (asi memory), stem:[A] (asi array), nebo stem:[C] (asi cache). +**💡 TIP**\ +V pseudokódu se označuje jako $M$ (asi memory), $A$ (asi array), nebo $C$ (asi cache). -==== Bottom-up +#### 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ě. -[NOTE] -==== +
📌 NOTE
+ Zjednodušeně jde o to přetransformovat rekurzi na cykly. Pěkný vedlejším efektem je, že je jednodušší určit složitost algoritmu. -==== -==== Kuchařka --- +
+ +#### 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ý stem:[\text{OPT}] protože dává _optimální_ řešení). +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 stem:[n] intervalů (událostí, úkolů, atd.), které se mohou překrývat v čase, a mají určitou váhu stem:[w_i], vyber takovou množinu intervalů stem:[S], pro kterou je stem:[\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. +#### Problémy -Nechť stem:[p(j)] je index takové události stem:[i < j], že stem:[i] a stem:[j] jsou kompatibilní. +- **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í. -[stem] -++++ -\text{OPT}(j) = \begin{cases} + - **Řešení** -0 & \text{pokud } j = 0 \\ -\max \{ \text{OPT}(j-1), w_j + \text{OPT}(p(j)) \} & \text{pokud } j > 0 + Ř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. -\end{cases} -++++ --- -==== + Nechť $p(j)$ je index takové události $i < j$, že $i$ a $j$ jsou kompatibilní. -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 stem:[i \times j] a stem:[j \times k] je stem:[i \cdot j \cdot k]. Jaké pořadí zvolit, aby byl výsledný součin co nejlevnější? -+ -==== -Problém:: -+ --- -Máme matice stem:[A_1, A_2, ..., A_n], které chceme pronásobit. + ```math + \text{OPT}(j) = \begin{cases} -Potřebujeme najít index stem:[k] takový, že stem:[\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ý. + 0 & \text{pokud } j = 0 \\ + \max \{ \text{OPT}(j-1), w_j + \text{OPT}(p(j)) \} & \text{pokud } j > 0 --- + \end{cases} + ``` -Řešení:: -+ -[stem] -++++ -\text{OPT}(i, j) = \begin{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ší? -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 + - **Problém** -\end{cases} -++++ -==== + Máme matice $A_1, A_2, ..., A_n$, které chceme pronásobit. -Knapsack:: -Mějme batoh s nosností stem:[W] a stem:[n] věcí, které bychom do něj rádi naložili. Každá věc stem:[i] má hodnotu stem:[v_i] a váhu stem:[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í. + 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ý. -Procházíme věci postupně přes index stem:[i] a pro každou řešíme, jestli ji chceme v batohu o nosnosti stem:[w]: + - **Řešení** -[stem] -++++ -\text{OPT}(i, w) = \begin{cases} + ```math + \text{OPT}(i, j) = \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 + 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} -++++ --- -==== - -=== Hladové (greedy) strategie - -[quote] -____ -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!" -____ + \end{cases} + ``` -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. +- **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? --- -* 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. --- + - **Řešení** -==== Problémy + Vychází z myšlenky, že batoh, ve kterém už něco je, je _jakoby_ batoh s nižší nosností. -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. -==== + Procházíme věci postupně přes index $i$ a pro každou řešíme, jestli ji chceme v batohu o nosnosti $w$: -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. -==== + ```math + \text{OPT}(i, w) = \begin{cases} -=== Backtracking + 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 -_Inteligentní brute-force nad prostorem řešení._ + \end{cases} + ``` -Technika hledání řešení problému postupným sestavováním _kandidátního_ řešení. <> +### Hladové (greedy) strategie --- -* Čá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. --- +> 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!" -.Porovnání s dynamickým programováním -[%header, cols=2] -|=== -| 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_. +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. -| Má blíž k BFS -- staví "vrstvy". -| Má blíž k DFS -- zanoří se do jednoho řešení a pak se vrátí. +- 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. -| Typicky zabírá víc paměti kvůli memoizaci. -| Typicky trvá déle, protože hledá _všechna_ řešení. +#### Problémy -| Mívá cykly. -| Mívá rekurzi. -|=== +- **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. -==== Problémy +- **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í. -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. + - **Řešení**\ + Vybereme ty, které končí nejdřív. -Eight queens:: -Jak rozestavit osm šachových královen na šachovnic tak, aby se vzájemně neohrožovaly? +### Backtracking +_Inteligentní brute-force nad prostorem řešení._ -== Amortizovaná analýza +Technika hledání řešení problému postupným sestavováním _kandidátního_ řešení. [backtracking](#backtracking) -[quote, Online Etymology Dictionary] -____ -_amortize(v)_:: -* _amortisen_ -- "to alienate lands", "to deaden, destroy" -* _amortir_ (Old French) -- "deaden, kill, destroy; give up by right" -* _*admortire_ (Vulgar Latin) -- to extinquish -____ +- Čá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. -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í*, [.underline]#*ne samostatně*#. +**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. | -.Připomenutí -==== +#### Problémy -TIP: Viz bakalářská otázka link:../../szb/korektnost-a-slozitost-algoritmu/[Korektnost a složitost algoritmu]. +- **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? -Základními pojmy analýzy složitosti jsou: +## Amortizovaná analýza -Časová složitost:: -Funkce velikosti vstupu stem:[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 stem:[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 stem:[g], nebo *pomaleji*: -+ -[stem] -++++ -\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 stem:[g], nebo *rychleji*. -+ -[stem] -++++ -\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 stem:[g]. -+ -[stem] -++++ -\Theta(g) = \mathcal{O}(g) \cap \Omega(g) -++++ -==== - -=== Aggregate method (brute force) +> - **_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 -Analyzujeme celou sekvenci operací najednou. Nepoužíváme žádné chytristiky ani fígle. +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ě**. -.Zásobník (brute force) -==== -Věta:: -Pokud začneme s prázdným zásobníkem, pak libovolná posloupnost stem:[n] operací `Push`, `Pop` a `Multi-Pop` zabere stem:[\mathcal{O}(n)] času. +**Připomenutí** -Důkaz:: -* Každý prvek je ``Pop``nut nejvýše jednou pro každý jeho `Push`. -* V posloupnosti je stem:[\le n] ``Push``ů. -* V posloupnosti je stem:[\le n] ``Pop``ů (včetně těch v ``Multi-Pop``u). -* Celá posloupnost má tak nejvýše složitost stem:[2n]. -==== +**💡 TIP**\ +Viz bakalářská otázka [Korektnost a složitost algoritmu](../../szb/korektnost-a-slozitost-algoritmu/). -=== Accounting method (banker's method) +Základními pojmy analýzy složitosti jsou: -Používá fígl, kdy velké množství _levných_ operací "předplatí" jednu _drahou_ operaci. Využívá metaforu bankovního účtu. +- **Č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**: -* 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ů. + ```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)) \} + ``` -Pro každou operaci v posloupnosti: +- **Omega**\ + Spodní mez, složitost v nejlepším případě. Množina funkcí rostoucích stejně rychle jako $g$, nebo **rychleji**. -* 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_. + ```math + \Omega(g) = \{f : (\exists c, n_0 \in \mathbb{N}^+)(\forall n \geq n_0)(f(n) \ge c \cdot g(n)) \} + ``` -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í. +- **Theta**\ + Horní i spodní mez. Množina funkcí rostoucích stejně rychle jako $g$. -WARNING: Pokud stav účtu *kdykoliv během posloupnosti* klesne pod nulu, pak jsou kreditové ceny nastaveny [.underline]#*špatně*#! + ```math + \Theta(g) = \mathcal{O}(g) \cap \Omega(g) + ``` -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á. +### Aggregate method (brute force) -.Zásobník (kredity) -==== -[%header, cols=3] -|=== -| Operace -| Skutečná cena -| Kreditová cena +Analyzujeme celou sekvenci operací najednou. Nepoužíváme žádné chytristiky ani fígle. -| `Push` -| 1 -| 2 +**Zásobník (brute force)** -| `Pop` -| 1 -| 0 +- **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$. -| `Multi-Pop` -| stem:[\min(k,\|S\|)] -| 0 -|=== +### Accounting method (banker's method) -Invariant:: -Počet kreditů na účtu je rovný počtu prvků na zásobníku. +Používá fígl, kdy velké množství _levných_ operací "předplatí" jednu _drahou_ operaci. Využívá metaforu bankovního účtu. -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 stem:[2n]. -==== +- 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: -=== Potential method (physicist's method) +- 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 stem:[\Phi], která přiřadí dané struktuře stem:[S] hodnotu. Platí, že: -+ -[stem] -++++ -\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 stem:[c_i] je _skutečná_ cena operace, pak pro amortizovanou cenu stem:[\hat{c_i}] platí: -+ -[stem] -++++ -\hat{c_i} = c_i + \Phi(S_i) - \Phi(S_{i-1}) -++++ - -Potenciálová věta:: -Počínaje počátečním stavem stem:[S_0], celková _skutečná_ cena posloupnosti stem:[n] operací je nejvýše součet jejich amortizovaných cen. - -Důkaz:: -+ -[stem] -++++ -\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) -==== -stem:[\Phi(S) = |S|] (počet prvků na zásobníku) - -[%header, cols=3] -|=== -| 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\|)] -a| -[stem] -++++ +- **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 stem:[\mathcal{O}(n)] času. - -Důkaz (případ `Push`):: -* Skutečná cena je stem:[c_i = 1]. -* Amortizovaná cena je stem:[\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 stem:[c_i = 1]. -* Amortizovaná cena je stem:[\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 stem:[c_i = k]. -* Amortizovaná cena je stem:[\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 stem:[\hat{c_i} \le 2]. -* Součet amortizovaných cen posloupnosti stem:[n] operací je pak stem:[\sum_{i=1}^n \hat{c_i} \le 2n]. -* Z potenciálnové věty plyne, že skutečná cena posloupnosti je stem:[\le 2n]. - -==== +``` + +- **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:: -+ -[stem] -++++ -\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. link:https://en.wikipedia.org/wiki/Splay_tree[(zdroj)] -+ -[stem] -++++ -\Phi(T) = \sum_{x \in T} \lfloor \log_2 \text{size}(x) \rfloor -++++ - -Move-to-front:: -Transformace dat používaná při kompresi dat. link:https://en.wikipedia.org/wiki/Move-to-front_transform[(zdroj)] -+ -[stem] -++++ -\Phi(L) = 2 \cdot \text{inversions}(L, L^*) -++++ - -Preflow-push (push-relabel):: -+ -[stem] -++++ -\Phi(f) = \sum_{v \,:\, \text{excess}(v) > 0} \text{height}(v) -++++ - -Red-black trees:: -+ -[stem] -++++ -\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} -++++ - -[bibliography] - -== Zdroje - -* [[[iv003, 1]]] link:https://is.muni.cz/auth/el/fi/jaro2021/IV003/[IV003 Algoritmy a datové struktury II (jaro 2021)] -* [[[backtracking,5]]] https://betterprogramming.pub/the-technical-interview-guide-to-backtracking-e1a03ca4abad +**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 +/// +/// Computes the longest proper prefix of P[0..i] +/// that is also a suffix of P[0..i]. +/// +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 diff --git a/szmgr/SZP02_numericke_metody.md b/szmgr/SZP02_numericke_metody.md index c24d88d..b962cf1 100644 --- a/szmgr/SZP02_numericke_metody.md +++ b/szmgr/SZP02_numericke_metody.md @@ -1,136 +1,120 @@ -= Numerické metody -:url: ./numericke-metody/ -:page-group: szp -:page-order: SZP02 +--- +title: "Numerické metody" +description: "TODO" +--- + +
📌 NOTE
-[NOTE] -==== 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_ -==== - -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. <> -+ -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:: -+ --- -* stem:[x] je přesná hodnota, -* stem:[\tilde{x}] je aproximace stem:[x], -* stem:[x - \tilde{x}] je absolutní chyba stem:[\tilde{x}], -* stem:[\lvert x - \tilde{x} \rvert \leq \alpha] je odhad absolutní chyby, -* stem:[\frac{x - \tilde{x}}{x}] je relativní chyba, -* stem:[\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í*. <> - -Řá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_ stem:[h]. Pokud ho lze zvolit libovolně malý, a lze-li prohlásit, že pro chybu aproximace stem:[E] platí: <> <> <> -+ -[stem] -++++ -\begin{aligned} -E(h) &\leq C \cdot h^p \\ -E(h) &\in \mathcal{O}(h^p) +
-\end{aligned} -++++ -+ -kde stem:[C] je konstanta. Pak stem:[p] je řád metody. - -== Iterativní metody pro řešení nelineárních rovnic - -Root-finding problem:: -Problém nalezení _kořenů_ (root) funkce stem:[f]. T.j. takových parametrů stem:[x, ...], kde funkce vrací 0: <> -+ -[stem] -++++ -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. <> <> - -Řád metody / rate of convergence:: -Hodnota reprezentující, jak rychle metoda konverguje k výsledku. <> - -Prostá iterační metoda / metoda pevného bodu / fixed-point iteration:: -Používá se pro rovnice typu stem:[x = g(x)]. -+ -1. Zvolíme počáteční odhad stem:[x_0]. -2. Opakujeme stem:[x_{n+1} = g(x_n)] dokud stem:[\lvert x_{n+1} - x_n \rvert \leq \alpha] (kde stem:[\alpha] je požadovaná přesnost). -+ -image::img/szp02_fixed_point_method.png[width=400] - -Newtonova metoda / metoda tečen:: -Používá k odhadu kořene funkce stem:[f] její tečnu v bodě stem:[x_n]. Iterační funkce je: -+ -[stem] -++++ -g(x_{k+1}) = x_k - \frac{f(x_k)}{f'(x_k)} -++++ -+ -1. Zvolíme počáteční odhad stem:[x_0]. -2. Další odhad je stem:[x_{n+1} = g(x_n)], tedy průsečík tečny fukce stem:[f] v bodě stem:[x_n] s osou stem:[x]. -3. Opakujeme 2. dokud nedosáhneme požadované přesnosti odhadu. -+ -image::./img/szp02_newton_method.png[width=400] - -Metoda sečen / secant method:: -Používá k odhadu kořene funkce stem:[f] sečny, resp. _finite difference_, které aproximují derivaci funkce stem:[f]. Díky tomu není potřeba znát derivaci funkce stem:[f]. Volí se dva počáteční body. Iterační funkce je: -+ -[stem] -++++ -g(x_{k+1}) = x_k - \frac{f(x_k)(x_k - x_{k-1})}{f(x_k) - f(x_{k-1})} -++++ -+ -image::./img/szp02_secant_method.png[width=400] - -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. Narozdíl od metody sečen si _vybereš_, který z předchozích bodů se ti hodí víc (stem:[x_s]), nemusí to být striktně ten předchozí. <> -+ -[stem] -++++ -x_{k+1} = x_k - \frac{x_k - x_s}{f(x_k) - f(x_s)} f(x_k) -++++ -+ -kde stem:[s] je největší index takový, že stem:[f(x_k)f(x_s) < 0]. (mají různé znaménka) -+ -image::./img/szp02_regula_falsi.png[width=400] - -Metoda Binary search:: -Prvotní interval stem:[(x_0, x_1)] musí obsahovat kořen funkce stem:[f], tj. stem:[x_0] a stem:[x_1] mají různé znaménka. V každém kroku se rozdělí interval na dvě poloviny a dál hledáme v polovině která obsahuje kořen funkce. Metoda _regula falsi_ se pokouší o rychlejší kovergenci sofistikovanějším dělením intervalu. - -== 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_). <> 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 stem:[D], dolní trojúhelníkovou matici stem:[L] a horní trojúhelníkovou matici stem:[U]. <> - -Nechť stem:[A\mathbf{x} = \mathbf{b}] je systém stem:[n] lineárních rovnic. Tedy: - -[stem] -++++ +- **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). + + ![width=400](img/szp02_fixed_point_method.png) + +- **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. + + ![width=400](./img/szp02_newton_method.png) + +- **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})} + ``` + + ![width=400](./img/szp02_secant_method.png) + +- **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} \\ @@ -145,244 +129,216 @@ A = \begin{bmatrix} \mathbf{b} = \begin{bmatrix} b_{1} \\ b_2 \\ \vdots \\ b_n \end{bmatrix}. -++++ +``` Algoritmus vypadá takto: --- -1. Zvolíme počáteční odhad stem:[\mathbf{x}^{(0)}], nejčastěji stem:[\vec{0}]. +1. Zvolíme počáteční odhad $\mathbf{x}^{(0)}$, nejčastěji $\vec{0}$. 2. Nový odhad získáme ze vztahu: -+ -[stem] -++++ -\mathbf{x}^{(k+1)} = D^{-1}(\mathbf{b} - (L + U)\mathbf{x}^{(k)}) -++++ --- -Jelikož stem:[L + U = A - D], dá to zapsat i jako: + ```math + \mathbf{x}^{(k+1)} = D^{-1}(\mathbf{b} - (L + U)\mathbf{x}^{(k)}) + ``` + +Jelikož $L + U = A - D$, dá to zapsat i jako: -[stem] -++++ +```math \mathbf{x}^{(k+1)} = D^{-1}\mathbf{b} + (I - D^{-1} A) \mathbf{x}^{(k)} -++++ - -Spektrální poloměr:: -Spektrální poloměr stem:[\rho] matice stem:[A] je největší absolutní hodnota vlastního čísla matice stem:[A]. -+ -[stem] -++++ -\rho(A) = \max_{i=1,\ldots,n} |\lambda_i| -++++ - -(Řádková) diagonální dominance:: -Matice stem:[A] je diagonálně dominantní, pokud platí: -+ -[stem] -++++ -|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á (stem:[>]). -* _Slabá_: nerovnost je neostá (stem:[\ge]). --- -+ -Analogicky se definuje sloupcová diagonální dominance. - -Konvergence Jacobiho metody:: -Jacobiho metoda konveguje pokud všechny následující podmínky: -+ --- -1. Nechť stem:[T_j = I - D^{-1} A] je matice iterace Jacobiho metody. Pak Jacobiho metoda konverguje, pokud: -+ -[stem] -++++ -\rho(T_j) < 1 -++++ -+ -2. Jacobiho metoda konverguje pro libovolný počáteční odhad stem:[\mathbf{x}^{(0)}], pokud stem:[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 stem:[L_*] (včetně diagonály, tedy stem:[L_* = D + L]) a striktně horní trojúhelníkovou matici stem:[U] (diagonála je nulová). Algoritmus vypadá takto: <> - --- -1. Zvolíme počáteční odhad stem:[\mathbf{x}^{(0)}]. +``` + +- **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: -+ -[stem] -++++ -\mathbf{x}^{(k+1)} = L_*^{-1}(\mathbf{b} - U\mathbf{x}^{(k)}). -++++ --- + + ```math + \mathbf{x}^{(k+1)} = L_*^{-1}(\mathbf{b} - U\mathbf{x}^{(k)}). + ``` Alternativně: -[stem] -++++ +```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 stem:[T_j] se použije matice stem:[T_{gs} = (D + L)^{-1} U]. +- **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 +### Relaxační iterativní metody -Modifikace Gauss-Seidelovy metody. Využívá parametr stem:[\omega], který určuje, jak moc se má nový odhad lišit od předchozího. Vztah pro další iteraci se mění na: <> +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) -[stem] -++++ +```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 stem:[0 < \omega < 1] se názývá metodou dolní relaxace. Je vhodná v případě, kdy Gauss-Seidel nekonverguje. -* Pro stem:[\omega = 1] je totožná s Gauss-Seidelem. -* Pro stem:[\omega > 1] se názývá metodou horní relaxace / SOR metodou. Zrychluje konvergenci Gauss-Seidela. --- +- 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 +### Dekompozice matic Metody podobné Gaussově eliminaci, ale s vlastnostmi, které mohou být vyhodné. -LU dekompozice:: -Rozdělení matice stem:[A] na horní dolní trojúhelníkovou matici stem:[L] a horní trojúhelníkovou matici stem:[U], tak že stem:[A = LU]. -+ -Je to v podstatě Gaussova eliminace. Matice stem:[P] je permutační matice, která prohazuje řádky: -+ -[stem] -++++ -P \cdot A = L \cdot U -++++ -+ -Platí, že: -+ -[stem] -++++ -\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: -+ -[stem] -++++ -\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í stem:[A] a různými pravými stranami stem:[b]. -* Inverzi matice stem:[A]. -* Výpočet determinantu matice stem:[A]. --- - - -QR dekompozice:: -Rozdělení matice stem:[A] na ortogonální matici stem:[Q] a horní trojúhelníkovou matici stem:[R] (už ne stem:[U]), tak že stem:[A = QR]. -+ -[stem] -++++ -\begin{aligned} +- **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$. -A \cdot x &= b \\ -A = QR \Rightarrow U \cdot x &= Q^T \cdot b \\ + Je to v podstatě Gaussova eliminace. Matice $P$ je permutační matice, která prohazuje řádky: -\end{aligned} -++++ -+ -Protože je ortogonální a tedy stem:[Q^{-1} = Q^T]. -+ -Má lepší numerickou stabilitu než LU dekompozice. + ```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$. -== Numerická diferenciace +- **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$. -Algoritmy numerické diferenciace (derivace) počítají odhady derivace reálných funkcí -- aproximují stem:[f'(x)]. Využívají při tom známé hodnoty této funkce a jiné znalosti a předpoklady. <> + ```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 stem:[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 link:../krivky-a-povrchy/[Křivky 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í. <> -+ -Jednotlivým "odstínům" -- konkrétním výpočetním vzorcům -- téhle metody se říká _diferenciační schémata_. -+ -TIP: Různá _diferenciační schémata_ (dopředná / zpětná / centrální) dávají mnohem větší smysl na diskrétních případech, jako například na obraze. Viz link:../zpracovani-rastroveho-obrazu/[Zpracování rastrového obrazu]. Je to složitý způsob jak říct, že odečteš vedlejší pixel. - -(Konečné) diference prvního řádu / first-order (finite) differences:: -Nejjednodušší schéma numerické diferenciace. Vychází z definice derivace. <> -+ --- -* _Dopředná diference / forward (finite) difference_ -+ -[stem] -++++ -\frac{\partial f}{\partial x} \approx \frac{f(x+h) - f(x)}{h} -++++ - -* _Zpětná diference / backward (finite) difference_ -+ -[stem] -++++ -\frac{\partial f}{\partial x} \approx \frac{f(x) - f(x-h)}{h} -++++ - -* _Centrální diference / central (finite) difference_ -+ -[stem] -++++ -\frac{\partial f}{\partial x} \approx \frac{f(x+h) - f(x-h)}{2h} -++++ --- -+ -kde stem:[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. <> - -[bibliography] -== Zdroje -* [[[ma018,1]]] link:https://is.muni.cz/auth/el/fi/podzim2019/MA018/[MA018 Numerical Methods (podzim 2019)] -* [[[numerical-analysis,2]]] link:https://en.wikipedia.org/wiki/Numerical_analysis[Wikipedia: Numerical analysis] -* [[[root-finding,3]]] link:https://en.wikipedia.org/wiki/Root-finding_algorithms[Wikipedia: Root-finding algorithms] -* [[[rate, 4]]] link:https://en.wikipedia.org/wiki/Rate_of_convergence[Wikipedia: Rate of convergence] -* [[[regula-falsi,5]]] link:https://en.wikipedia.org/wiki/Regula_falsi[Wikipedia: Regula falsi] -* [[[gauss-elimination,6]]] link:https://en.wikipedia.org/wiki/Gaussian_elimination[Wikipedia: Gaussian elimination] -* [[[jacobi-method,7]]] link:https://en.wikipedia.org/wiki/Jacobi_method[Wikipedia: Jacobi method] -* [[[gauss-seidel,8]]] link:https://en.wikipedia.org/wiki/Gauss%E2%80%93Seidel_method[Wikipedia: Gauss-Seidel method] -* [[[relaxation-method, 9]]] link:https://en.wikipedia.org/wiki/Relaxation_(iterative_method)[Wikipedia: Relaxation (iterative method)] -* [[[differentiation, 10]]] link:https://en.wikipedia.org/wiki/Numerical_differentiation[Wikipedia: Numerical differentiation] -* [[[finite-difference, 11]]] link:https://en.wikipedia.org/wiki/Finite_difference[Wikipedia: Finite difference] -* [[[finite-difference-method, 12]]] link:https://en.wikipedia.org/wiki/Finite_difference_method[Wikipedia: Finite difference method] -* [[[richardson,13]]] link:https://en.wikipedia.org/wiki/Richardson_extrapolation[Wikipedia: Richardson extrapolation] -* [[[linear-eq, 14]]] link:https://en.wikipedia.org/wiki/System_of_linear_equations[Wikipedia: System of linear equations] -* [[[numerical-stability, 15]]] link:https://en.wikipedia.org/wiki/Numerical_stability[Wikipedia: Numerical stability] -* [[[numericka-metoda,16]]] link:https://cs.wikipedia.org/wiki/Numerick%C3%A1_metoda[Wikipedia: Numerická metoda] -* [[[order-question,17]]] link:https://math.stackexchange.com/questions/2873291/what-is-the-intuitive-meaning-of-order-of-accuracy-and-order-of-approximation[What is the intuitive meaning of order of accuracy and order of approximation?] +- **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)]() +- [[[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) diff --git a/szmgr/SZP03_statistika.md b/szmgr/SZP03_statistika.md index b920d19..7223c27 100644 --- a/szmgr/SZP03_statistika.md +++ b/szmgr/SZP03_statistika.md @@ -1,767 +1,544 @@ -= Statistika -:url: ./statistika/ -:page-group: szp -:page-order: SZP03 +--- +title: "Statistika" +description: "TODO" +--- + +
📌 NOTE
-[NOTE] -==== 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_ -==== - -.Opakování -==== -TIP: Viz bakalářské otázky link:../../szb/kombinatorika-a-pravdepodobnost/[Kombinatorika a pravděpodobnost] a link:../../szb/statistika/[Statistika]. +
-Statistika:: -Zabývá se sbíráním, organizací, analýzou, interpretací a prezentací dat. <> -+ -* _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í. +**Opakování** -Základní prostor stem:[\Omega]:: -Konečná množina možných jevů. Např stem:[\{1, 2, 3, 4, 5, 6\}] pro možné hody šestistěnkou. +**💡 TIP**\ +Viz bakalářské otázky [Kombinatorika a pravděpodobnost](../../szb/kombinatorika-a-pravdepodobnost/) a [Statistika](../../szb/statistika/). -Možný výsledek (elementární náhodný jev) stem:[\omega_k]:: -Prvek základního prostoru stem:[\Omega]. +- **Statistika**\ + Zabývá se sbíráním, organizací, analýzou, interpretací a prezentací dat. [statistics](#statistics) -Náhodný jev (event) stem:[A]:: -Podmnožina stem:[A \sube \Omega], která nás zajímá. Např. _"Na šestistěnce padne sudé číslo."_ + - _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č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 stem:[E] (třeba stem:[\mathbb{R}]). -+ -stem:[X : \Omega \to \mathbb{E}] +- **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í -Diskrétní NV je náhodná veličina, která nabývá konečně nebo spočetně mnoha hodnot. stem:[\mathbb{E}] je konečná nebo spočetná, např. stem:[\N]. +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 stem:[X : \Omega \to \R] je _diskrétní_, pokud se prvky stem:[\Omega] zobrazí do stem:[\R] jako izolované body stem:[\{x_1, x_2, \ldots\}]. +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. -Rozdělení pravděpodobnosti:: -Funkce stem:[P(X) : \mathbb{E} \to \R], která každé hodnotě popsané veličinou stem:[X] přiřazuje pravděpodobnost jejího výskytu. +- Každá $x_i$ má nenulovou pravděpodobnost: --- -* Každá stem:[x_i] má nenulovou pravděpodobnost. Jinými slovy - nějaká *určitě* nastane. -+ -[stem] -++++ -P(x_i) > 0 -++++ + ```math + P(x_i) > 0 + ``` -* Součet pravděpodobností všech možných hodnot stem:[x_i] je stem:[1]: -+ -[stem] -++++ -\sum_{x} P(x_i) = 1 -++++ --- +- Součet pravděpodobností všech možných hodnot $x_i$ je $1$: -=== Spojité + ```math + \sum_{x} P(x_i) = 1 + ``` -Spojitá NV je náhodná veličina, která nabývá až nespočetně nekonečně mnoha hodnot. Tedy stem:[\mathbb{E}] je nespočetná, např. stem:[\R]. +### 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 stem:[X : \Omega \to \R] je _spojitá_, pokud se prvky stem:[\Omega] zobrazí do stem:[\R] jako interval stem:[\lbrack a, b \rbrack]. - -Hustota pravděpodobnosti / probability density function (PDF):: -Funkce stem:[f(x) : \mathbb{E} \to \R], která každé hodnotě popsané veličinou stem:[X] přiřazuje pravděpodobnost jejího výskytu. - --- -* Každý bod tohoto intervalu má *nulovou* pravděpodobnost: -+ -[stem] -++++ -f(x) = 0 -++++ - -* Nicméně integrál pravděpodobnostní funkce stem:[f(x)] je stem:[1]: -+ -[stem] -++++ -\int_{-\infty}^{\infty} f(x) dx = 1 -++++ - -* Pravděpodobnost, že NV nabývá hodnoty z intervalu stem:[\lbrack a, b \rbrack] je pak: -+ -[stem] -++++ -P(a \leq X \leq b) = \int_{a}^{b} f(x) dx -++++ --- - -=== Základní rozložení - -Distribuční funkce / cumulative distribution function (CDF):: -+ --- - -Funkce stem:[F(X) : \mathbb{E} \to \R] udává pravděpodobnost, že NV stem:[X] nabývá hodnoty menší než stem:[x]. - -[stem] -++++ -\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 stem:[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: - -[stem] -++++ -P(a \leq X \leq b) = F(b) - F(a) -++++ - --- - -.Diskrétní rozložení -[%header,cols="1,4,3,2"] -|=== -| Název -| Definice -| Popis -| Příklad - -| Bernoulliho / alternativní -| stem:[ - 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é -| stem:[ - P(x, n, p) = \binom{n}{x} p^x (1-p)^{n-k} -] -| Sekvence stem:[n] pokusů. Popisuje pravděpodobnost, že stem:[x] bude úspěšných. -| Hod mincí stem:[n] krát. - -| Poissonovo -| stem:[ - P(k, \lambda) = \frac{\lambda^k e^{-\lambda}}{k!} -] -| Pokud se něco děje průměrně stem:[\lambda]-krát za jednotku času, jaká je pravděpodobnost, že se to stane stem:[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é -| stem:[ - 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í stem:[k] krát, než to konečně uspěje. -| Kolikrát musíš hodit mincí, než padne poprvé hlava. - -| (Diskrétní) rovnoměrné / uniformní -| stem:[ - P(x) = \begin{cases} - \frac{1}{\lvert A \rvert} & x \in A \\ - 0 & \text{jinak} \\ - \end{cases} -] -| Když jsou všechny jevy stem:[x] z dané množiny stem:[A] stejně pravděpodobné. -| Hod d20. -|=== - -.Spojité rozložení -[%header,cols="1,4,3,2"] -|=== -| Název -| Definice -| Popis -| Příklad - -| (Spojité) rovnoměrné / uniformní -| stem:[ - 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 stem:[(a, b)] (může být otevřený nebo uzavřený) jsou stejně pravděpodobné. -| Bod na kružnici. - -| Exponenciální -| stem:[ - f(x, \lambda) = \begin{cases} - \lambda e^{-\lambda x} & x \ge 0 \\ - 0 & x < 0 \\ - \end{cases} -] -| Čas mezi jevy v Poissonově procesu. Časovou jednotku si můžeme zvolit, ale musí být pak stejná všude. -| Jak dlouho budeš čekat na šalinu. - -| Normální / Gaussovo -| stem:[ - 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ě. (stem:[\mu] je mean, stem:[\sigma^2] je rozptyl). (95% obsahu je v intervalu stem:[\mu \pm \sigma] of stem:[\mu]) -| Výška lidí. - -| Standardní normální -| stem:[ - f(x) = f_\mathcal{N}(x, 0, 1) = \frac{1}{\sqrt{2 \pi}} e^{-\frac{x^2}{2}} -] -a| Je fajn, protože má standardní odchylku rovnu jedné, takže člověku stačí si pamatovat, že: - -* 68 % je v intervalu stem:[(-1, 1)], -* 95 % je v intervalu stem:[(-2, 2)], -* 99,7 % je v intervalu stem:[(-3, 3)]. - -| Výška lidí (ale přeškálovaná). - -| Cauchy -| stem:[ - 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 -| stem:[ - 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 stem:[\beta], pak čekací doba na stem:[n]-tý jev má Gamma rozdělení s stem:[\alpha = n]. -| Jak dlouho budeš čekat na stem:[n]-tou šalinu. - -| stem:[\chi^2] (Chi-square) -| stem:[ - 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ť stem:[Z_1, Z_2, ..., Z_n] jsou nezávislé náhodné proměnné se standardním normálním rozdělením a stem:[X = \sum_{i=1}^n Z_i^2], pak stem:[X] má stem:[\chi^2] rozdělení s stem:[n] stupni volnosti. -| Testování, jestli je mince férová. - -| Studentovo stem:[t] -| stem:[ - f(x, n) = \frac{ - \Gamma (\frac{n+1}{2}) - }{ - \sqrt{n \pi} \Gamma(\frac{n}{2}) - } - \left( - 1 + \frac{x^2}{n} - \right)^{-\frac{n+1}{2}} -] -| Používá se na odhadování meanu normálně distribuované populace, jejíž rozptyl neznáš (což je skoro vždycky), ale máš z ní samply. -| Odhadování průměru výšky lidí. - -|=== - -=== Číselné charakteristiky + +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 +#### Míry polohy -Střední hodnota / mean / expected value:: -Průměr hodnot veličiny vážený jejich pravděpodobností. Značí se stem:[\overline{X}] nebo stem:[E(X)]. -+ -NOTE: Taky někdy označovaný jako _obecný moment prvního řádu / první obecný moment_. <> +- **Střední hodnota / mean / expected value**\ + Průměr hodnot veličiny vážený jejich pravděpodobností. Značí se $\overline{X}$ nebo $E(X)$. -stem:[\alpha]-kvantil stem:[Q_\alpha]:: -Dělí statický soubor na stejně velké části. + **📌 NOTE**\ + Taky někdy označovaný jako _obecný moment prvního řádu / první obecný moment_. [moment](#moment) -Medián:: -Prostřední prvek uspořádaného statistického souboru. Kvantil stem:[Q_{0.5}]. -+ -[stem] -++++ -\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} -++++ +- **$\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}$. -Percentil:: -Výběrový kvantil (stem:[p]-tý kvantil, kde stem:[0 < p < 1]) stem:[Q_p]. + ```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} + ``` -Modus:: -Hodnota s největší četností. Je akceptovatelné, že je _modů_ vícero (bimodální - až multimodální). +- **Percentil**\ + Výběrový kvantil ($p$-tý kvantil, kde $0 < p < 1$) $Q_p$. +- **Modus**\ + Hodnota s největší četností. -==== Míry variability +#### Míry variability -[quote] 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 stem:[\sigma^2], stem:[\text{var}(X)] nebo stem:[D(X)]. -+ -[stem] -++++ -\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_. <> - -Směrodatná odchylka / standard deviation:: -Míra variability NV. Značí se stem:[\sigma] nebo stem:[\text{SD}(X)]. Je definovaná jako stem:[\sqrt{\sigma^2}]. - -ovariance veličin stem:[X] a stem:[Y]:: -Měří určitou podobnost mezi stem:[X] a stem:[Y]. -+ -[stem] -++++ -\text{cov}(X, Y) = E((X - E(X)) \cdot (Y - E(Y))) -++++ -+ -Ze vzorce výše plyne -+ -[stem] -++++ -\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 stem:[\rho_{X, Y}] náhodných veličin stem:[X] a stem:[Y]. Pokud stem:[X = X], pak stem:[\rho_{X, X} = 1]. Pokud jsou stem:[X] a stem:[Y] nezávislé, pak stem:[\rho_{X, Y} = 0]. -+ -[stem] -++++ -\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) - -[quote] -S rostoucím počtem sample výsledků stem:[X_i] se jejich distribuce blíží normálnímu rozdělení bez ohledu na jejich původní rozdělení. +- **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) \\ -Lévyho-Lindenbergova věta:: -+ -Mějme NV stem:[X]. Pokud je stem:[X] součtem stem:[n] vzájemně nezávislých NV stem:[X_1, X_2, ..., X_n] se shodným rozdělením libovolného typu, s konečnou střední hodnotou stem:[E(X_i) = \mu] a konečným rozptylem stem:[D(X_i) = \sigma^2], pak pro normovanou NV stem:[U] asymptoticky s stem:[n \to \infty] platí: + \frac{\sum_{i=1}^n X_i - n \mu}{\sqrt{n \sigma^2}} &\approx N(0, 1) -[stem] -++++ -\begin{aligned} + \end{aligned} + ``` -\overline{X} = \frac{1}{n} \sum_{i=1}^n X_i &\approx N \left( \mu, \frac{\sigma^2}{n} \right) \\ + **Výpočet s CLV** -\sqrt{n} \frac{\overline{X} - \mu}{\sqrt{\sigma^2}} &\approx N(0, 1) \\ + Nechť $X$ je náhodná proměnná popisují jak padá 6, když hodíme kostkou 100krát. Tedy: -\frac{\sum_{i=1}^n X_i - n \mu}{\sqrt{n \sigma^2}} &\approx N(0, 1) + ```math + X \approx \text{Binomial} \left( 100, \frac{1}{6} \right) + ``` -\end{aligned} -++++ + Podle CLV má $X$ asymptoticky $X \approx N(\frac{100}{6},\frac{500}{36})$. -.Výpočet s CLV -==== -Nechť stem:[X] je náhodná proměnná popisují jak padá 6, když hodíme kostkou 100krát. Tedy: + Pak například pravděpodobnost, že šestka padne méně než 16krát je: -[stem] -++++ -X \approx \text{Binomial} \left( 100, \frac{1}{6} \right) -++++ + ```math + \begin{aligned} -Podle CLV má stem:[X] asymptoticky stem:[X \approx N(\frac{100}{6},\frac{500}{36})]. + P(X < 16) &\doteq P(X \leq 16) = 0.429 \\ + P(X < 16) = P(X \leq 15) &\doteq F(X \leq 15) = 0.327 \\ -Pak například pravděpodobnost, že šestka padne méně než 16krát je: + \end{aligned} + ``` -[stem] -++++ -\begin{aligned} + S _continuity correction_ (opravou v důsledku změny z diskrétní na spojitou NV) je to: -P(X < 16) &\doteq P(X \leq 16) = 0.429 \\ -P(X < 16) = P(X \leq 15) &\doteq F(X \leq 15) = 0.327 \\ + ```math + P(X < 16) = P(X \leq 15.5) \doteq F(15.5) = 0.377 + ``` -\end{aligned} -++++ +## Odhady -S _continuity correction_ (opravou v důsledku změny z diskrétní na spojitou NV) je to: +- **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. -[stem] -++++ -P(X < 16) = P(X \leq 15.5) \doteq F(15.5) = 0.377 -++++ -==== + 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. -Moivreova-Laplacova věta:: -+ --- -TIP: Specializace Lévyho-Lindenbergovy věty - rychlejší pro Bernoulliho rozdělení +- **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: -Mějme NV stem:[X]. Pokud je stem:[X] součtem stem:[n] vzájemně nezávislých NV stem:[X_1, X_2, ..., X_n] s Bernoulliho rozdělením s parametrem stem:[\pi], má stem:[X] binomické rozdělení s parametry stem:[n] a stem:[\pi], pak s stem:[n \to \infty]: + - _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_. -[stem] -++++ -\frac{X - n \pi}{\sqrt{n \pi (1 - \pi)}} \approx N(0, 1) -++++ + > 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) -== Odhady +- **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: -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 stem:[X] na základě informace z výběrového souboru (realizaci NV, datasetu). Chceme hodnotu a přesnost odhadu. + ```math + P(\theta_L < \theta < \theta_U) = 1 - \alpha + ``` -Metoda odhadu / estimator:: -Popisuje, jak odhad získat. + kde $\theta_L$ je **dolní mez intervalu** a $\theta_U$ je **horní mez intervalu**. -Nestranný odhad / unbiased estimator:: -Metoda odhadu parametru stem:[\theta] taková, že střední hodnota odhadu je rovna stem:[\theta]. Nestrannost je celkem rozumné omezení, protože nechceme, aby byl odhad odchýlený. +- **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}$. -Nejlepší nestranný odhad / best unbiased estimator:: -Nestranný odhad, který má nejmenší rozptyl ze všech nestranných odhadů. +**Tvorba intervalového odhadu** -Konzistentní odhad / consistent estimator:: -Metoda odhadu parametru stem:[\theta] taková, že s počtem vzorků stem:[n] konverguje k stem:[\theta] pro stem:[n \to \infty]. <> +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ý. -(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_, unbiased varianta:\ - stem:[\frac{1}{1-n} \sum_{i = 0}^{n}(x_i - \bar{x})^2] -* _Výběrovou směrodatnou odchylku / sample standard deviation_, -* _Výběrovou (empirickou) distribuční funkci / sample distribution function_. --- -+ -[quote] -____ -Náhodná veličina stem:[T_n], která vznikne aplikací funkce stem:[T] na náhodný výběr o velikosti stem:[n] stem:[\mathbf{X} = (X_1, X_2, \ldots, X_n)] se nazývá statistika. +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: -[stem] -++++ -T_n = T(X_1, X_2, \ldots, X_n) -++++ -____ -+ -TIP: _Estimator_ je funkce počítající statistiku použitá k odhadu parametru. <> + ```math + T(X) = \frac{\overline{X} - \mu}{S / \sqrt{n}} \sim t_{n - 1} + ``` -Bodový odhad / point estimate / pointwise estimate:: -Odhad parametru daný *jednou hodnotou*, která hodnotu parametru aproximuje. + Tedy víme, že $T(X) \sim t(n-1)$ -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. +2. Určíme kvantily $t_\frac{\alpha}{2} = t_{0.025}$ a $t_{1 - \frac{\alpha}{2}} = t_{0.975}$ z $T(X)$: -Interval spolehlivosti / confidence interval:: -Interval spolehlivosti parametru stem:[\theta] s hladinou spolehlivosti stem:[1 - \alpha], kde stem:[\alpha \in \lbrack 0, 1 \rbrack] je dvojice statistik stem:[\lbrack \theta_L, \theta_U \rbrack] taková, že: -+ -[stem] -++++ -P(\theta_L < \theta < \theta_U) = 1 - \alpha -++++ -+ -kde stem:[\theta_L] je *dolní mez intervalu* a stem:[\theta_U] je *horní mez intervalu*. - -Hladina významnosti a spolehlivosti / significance and confidence level:: -* Hladina významnosti stem:[\alpha] je pravděpodobnost, že parametr *nespadá* do intervalového odhadu. -* Hladina spolehlivosti stem:[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í)_: stem:[P(\theta_L \le \theta) = 1 - \alpha]. -* _Pravostranný (horní)_: stem:[P(\theta_U \ge \theta) = 1 - \alpha]. -* _Oboustranný_: stem:[P(\theta_L < \theta) = P(\theta < \theta) = \frac{\alpha}{2}]. - -.Tvorba intervalového odhadu -==== -Máme vzorek velikosti stem:[n] s výběrovým průměrem stem:[\overline{X}] a výběrovým rozptylem stem:[S^2]. Odhadněte střední hodnotu stem:[\mu] s hladinou spolehlivosti 0.95, pokud víte, že stem:[X \approx N(\mu, \sigma^2)], kde rozptyl stem:[\sigma^2] je neznámý. - -1. Zvolíme vhodnou výběrovou statistiku stem:[T(X)] jejíž rozdělení závislé na stem:[\mu] známe. V tomhle případě Studentův t-test: -+ -[stem] -++++ -T(X) = \frac{\overline{X} - \mu}{S / \sqrt{n}} \sim t_{n - 1} -++++ -+ -Tedy víme, že stem:[T(X) \sim t(n-1)] - -2. Určíme kvantily stem:[t_\frac{\alpha}{2} = t_{0.025}] a stem:[t_{1 - \frac{\alpha}{2}} = t_{0.975}] z stem:[T(X)]: -+ -[stem] -++++ -\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} -++++ + ```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. +- **Věrohodnost / likelihood** -NOTE: Pravděpodobnost je funkce jevů. Likelihood je funkce parametrů modelu. + Říká, jak dobře náš model (rozdělení pravděpodobnosti náhodné veličiny dané parametry) sedí na naměřená data. -NOTE: Likelihood nemusí nutně vracet čísla z intervalu stem:[\lbrack 0, 1 \rbrack]. --- + **📌 NOTE**\ + Pravděpodobnost je funkce jevů. Likelihood je funkce parametrů modelu. -Maximum likelihood estimation (MLE):: -Metoda odhadu parametru založená na maximalizaci likelihoodu, že model sedí na naměřená data. <> + **📌 NOTE**\ + Likelihood nemusí nutně vracet čísla z intervalu $\lbrack 0, 1 \rbrack$. -Method of moments (MOM):: -Metoda odhadu parametru založená na rovnosti teoretického a výběrového momentu. <> +- **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 -== 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. -Hypotéza:: -Nějaký předpoklad o datech, který chceme ověřit. Často je formulovaná pomocí parametrů modelu. Např. _"střední hodnota je 5."_ + - _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$. -Testování hypotézy:: -Cílem testování hypotéz je ověřit, že data *nepopírají* nějakou hypotézu. -+ --- -* _Null hypothesis stem:[H_0]_: "výchozí nastavení"; často tvrdí, že nějaká vlastnost neexistuje. -* _Alternative hypothesis stem:[H_1]_: "to co, chceme dokázat"; opak stem:[H_0]. --- -+ -Alternativní hypotézu _potvrzujeme_ tak, že _vyvracíme_ nulovou hypotézu. Pokud se nám nepodaří vyvrátit stem:[H_0], pak o stem:[H_1] nevíme nic. <> -+ -[quote, MV013] -____ -Na testování použijeme statistiku stem:[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 stem:[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_). + 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 základě realizace náhodného výběru stem:[\mathbf{x} = (x_1, ..., x_n)'] vypočítáme hodnotu testovací statistiky stem:[t_n = T(\mathbf{x})]. + > 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 -* Pokud hodnota testovací statistiky stem:[t_n] nabude hodnoty z kritické oblasti, t.j. stem:[t_n = T(\mathbf{x}) \in W_\alpha], pak *nulovou hypotézu [.underline]#zamítáme#*. -* Pokud hodnota testovací statistiky stem:[t_n] nabude hodnoty z oblasti nezamítnutí, t.j. stem:[t_n = T(\mathbf{x}) \not\in W_\alpha], pak *nulovou hypotézu [.underline]#nezamítáme#*. -____ +**Metafora se soudem** -.Metafora se soudem -==== Platí presumpce nevinny. Předpokládáme, že člověk zločin nespáchal, dokud tuhle hypotézu nevyvrátíme. -* _stem:[H_0]_: "Obžalovaný *neukradl* papamobil." -* _stem:[H_1]_: "Obžalovaný *ukradl* papamobil." -==== - -Chyby v testování hypotéz:: -* _Typ I_: zamítnutí stem:[H_0], i když je pravdivá -- _false positive_. -* _Typ II_: nezamítnutí stem:[H_0], i když je nepravdivá -- _false negative_. -+ -[NOTE] -==== -_Positive_ = zamítnutí stem:[H_0], tedy potvrzení stem:[H_1]. - -_Negative_ = nezamítnutí stem:[H_0], tedy o stem:[H_1] nevíme nic. -==== - -stem:[p]-hodnota (hladina významnosti):: -Nejmenší hladina významnosti stem:[\alpha], při které ještě zamítáme stem:[H_0]. <> -+ -Pravděpodobnost, že došlo k chybě typu I -- zavrhnuli jsme stem:[H_0], ačkoli platí. -+ -stem:[ - p = P(\text{type I error}) = P(\text{we reject } H_0 \;|\; H_0) -] -+ -TIP: Pokud stem:[p]-value vyjde menší než požadovaná hladina významnosti stem:[\alpha], pak pravděpodobnost, že došlo k chybě typu I je dostatečně malá na to, abychom mohli tvrdit, že zavrhujeme stem:[H_0], protože stem:[H_0] neplatí, a tedy akceptujeme stem:[H_1]. - -=== Parametrické testy +- _$H_0$_: "Obžalovaný **neukradl** papamobil." +- _$H_1$_: "Obžalovaný **ukradl** papamobil." -Parametrické testy jsou založené na parametrech pravděpodobnostních rozdělení. +- **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_. + +
📌 NOTE
+ + _Positive_ = zamítnutí $H_0$, tedy potvrzení $H_1$. + + _Negative_ = nezamítnutí $H_0$, tedy o $H_1$ nevíme nic. +
+ +- **$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í. -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. <> + stem:[ + p = P(\text{type I error}) = P(\text{we reject } H_0 \;|\; H_0) + ] -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í. <> Je to alternativa k dělání testů _každý s každým_. + **💡 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$. -=== Neparametrické testy +### 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árový test!) při pozorování liší konzistentně. Jinými slovy, zda střední 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 (stem:[\chi^2]) test:: -Umožňuje ověřit, že dvě kategorické NV jsou nezávislé. <> - -=== Testy (ne)závislosti náhodných veličin - -.Opakování -==== -Statistická / stochastická nezávislost:: -Náhodné jevy stem:[A] a stem:[B] jsou stochasticky nezávislé, pokud stem:[P(A \cap B) = P(A) \cdot P(B)]. -+ -*Výskyt stem:[A] nemá vliv na výskyt stem:[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. <> -==== - -Nezávislost diskrétních NV:: -+ --- -Pokud stem:[X], stem:[Y] a stem:[Z] jsou diskrétní náhodné veličiny, pak definujeme stem:[X] a stem:[Y] jako _podmíněně nezávislé_ vzhledem k stem:[Z], pokud: - -[stem] -++++ -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 stem:[x], stem:[y] a stem:[z] takové, že stem:[P(Z = z) > 0]. --- - -Nezávislost spojitých NV:: -+ --- -Pokud stem:[X], stem:[Y] a stem:[Z] jsou spojité náhodné veličiny a mají společnou hustotu pravděpodobnosti stem:[f_{XYZ}(x,y,z)], pak definujeme stem:[X] a stem:[Y] jako _podmíněně nezávislé_ vzhledem k stem:[Z], pokud: - -[stem] -++++ -f_{X,Y|Z}(x,y|z) = f_{X|Z}(x|z) \cdot f_{Y|Z}(y|z) -++++ - -pro všechna stem:[x], stem:[y] a stem:[z] takové, že stem:[f_Z(z) > 0]. --- - -[quote, Wikipedia: Statistická nezávislost] -____ -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é. -____ - -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: -+ -[stem] -++++ -Y_i = \beta_0 + \beta_1 \cdot X_i + \varepsilon_i -++++ -+ -Kde: -+ --- -* stem:[Y] je NV závislá na stem:[X], -* stem:[\beta_0] je konstanta, -* stem:[\beta_1] je směrnice (slope), -* stem:[\varepsilon_i] je stem:[i]-tá pozorovaná hodnota chyby -- náhodná složka / šum. --- -+ -Platí: -+ --- -* stem:[E(\varepsilon_i) = 0], -* stem:[D(\varepsilon_i) = \sigma^2], -* stem:[\text{cov}(\varepsilon_i, \varepsilon_j) = 0] pro stem:[i \neq j], -* stem:[\varepsilon_i \sim N(0, \sigma^2)] -- náhodná složka má normální rozdělení, -* regresní parametry stem:[\beta_0] a stem:[\beta_1] mohou mít libovolnou hodnotu. --- - -Celkový F-test:: -Pracuje s nulovou hypotézou ve tvaru: -+ -[stem] -++++ -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 stem:[H_0] zamítnuta, pak alespoň jedna závislost existuje. Pokud je stem:[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 stem:[i]-tou vysvětlující NV. Testujeme nulovou hypotézu: -+ -[stem] -++++ -H_0: \beta_i = 0 -++++ -+ -Pokud nelze zamítnout, pak stem:[i]-tá vysvětlující NV nemá vliv na analyzovanou NV a můžeme ji vynechat. -+ -Testová statistika má Studentovo t-rozdělení. - - -[bibliography] -== Zdroje - -* [[[statistics,1]]] link:https://en.wikipedia.org/wiki/Statistics[Wikipedia: Statistics] -* [[[nv,2]]] link:https://cs.wikipedia.org/wiki/N%C3%A1hodn%C3%A1_veli%C4%8Dina[Wikipedia: Náhodná veličina] -* [[[cdf,3]]] link:https://en.wikipedia.org/wiki/Cumulative_distribution_function[Wikipedia: Cumulative distribution function] -* [[[mean,4]]] link:https://en.wikipedia.org/wiki/Mean[Wikipedia: Mean] -* [[[clv,5]]] link:https://cs.wikipedia.org/wiki/Centr%C3%A1ln%C3%AD_limitn%C3%AD_v%C4%9Bta[Wikipedia: Centrální limitní věta] -* [[[consistent-estimator,6]]] link:https://en.wikipedia.org/wiki/Consistent_estimator[Wikipedia: Consistent estimator] -* [[[statistic, 7]]] link:https://en.wikipedia.org/wiki/Statistic[Wikipedia: Statistic] -* [[[mle, 8]]] link:https://en.wikipedia.org/wiki/Maximum_likelihood_estimation[Wikipedia: Maximum likelihood estimation] -* [[[mom, 9]]] link:https://en.wikipedia.org/wiki/Method_of_moments_(statistics)[Wikipedia: Method of moments] -* [[[null, 10]]] link:https://en.wikipedia.org/wiki/Null_hypothesis[Wikipedia: Null hypothesis] -* [[[p-value, 11]]] link:https://cs.wikipedia.org/wiki/P-hodnota[Wikipedia: P-hodnota] -* [[[mv013,12]]] link:https://is.muni.cz/auth/el/fi/jaro2021/MV013/[MV013 Statistics for Computer Science (jaro 2021)] -* [[[anova, 13]]] link:https://en.wikipedia.org/wiki/Analysis_of_variance[Wikipedia: Analysis of variance] -* [[[nezavislost,14]]] link:https://cs.wikipedia.org/wiki/Statistick%C3%A1_nez%C3%A1vislost[Wikipedia: Statistická nezávislost] -* [[[t-test, 15]]] link:https://cs.wikipedia.org/wiki/T-test[Wikipedia: T-test] -* [[[chi-squared,16]]] link:https://www.scribbr.com/statistics/chi-square-tests/[Chi-square tests] -* [[[moment, 17]]] link:http://kfe.fjfi.cvut.cz/~limpouch/sigdat/pravdh/node10.html[Momenty rozdělení] +- **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]() +- [[[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) diff --git a/szmgr/SZP04_3d_modelovani.md b/szmgr/SZP04_3d_modelovani.md index 1bdf3a7..3dc2cf5 100644 --- a/szmgr/SZP04_3d_modelovani.md +++ b/szmgr/SZP04_3d_modelovani.md @@ -1,250 +1,234 @@ -= 3D modelování a datové struktury -:url: ./3d-modelovani-a-datove-struktury/ -:page-group: szp -:page-order: SZP04 +--- +title: "3D modelování a datové struktury" +description: "TODO" +--- -[NOTE] -==== -Mnohoúhelníkové a trojúhelníkové sítě: datové struktury, modelování, pass:[filtrování], změna struktury sítě, **zjednodušování sítě**. Implicitní **a parametrické** reprezentace a modelování **(SDF, CSG, B-Rep)**. +
📌 NOTE
+ +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_ -==== - -== 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. <> - -Topologie:: -* Nemění ji deformace. -* Např. to jak jsou body propojené. -* Sousednost (neighborhood), souvislost (connectedness), adjacency. atd. <> -+ -.Topology <> -image::./img/szp04_topology.png[Topology, 500] - -Topological manifold:: -Prostor/útvar, který lokálně _připomíná_ (je homeomorfní) stem:[n]-dimenzionální Euklidovský prostor. <> <> -+ -stem:[n]-manifold je takový topologický manifold, kde okolí každého bodu je homeomorfní s stem:[n]-dimenzionálním Euklidovským prostorem. <> -+ -Manifoldy jsou typicky fyzikálně validní a efektivní (např. pomocí half-edge). -+ -* Souřadnicový prostor stem:[\mathbb{R}^n] je stem:[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. <> -* stem:[n]-dimenzionální koule je stem:[n]-manifold. -+ -image::./img/szp04_manifold.png[width=100%] - -Orientability / orientace:: -+ -[quote, PA010] -____ -* 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. -____ -+ -.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í. - -image:./img/szp04_mobius_strip.jpg[Möbiova páska, 50%] -image:./img/szp04_klein_bottle.jpg[Kleinova láev, 30%] -==== - -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. -+ -[quote, PA010] -____ -Genus of an orientable surface is the maximum number of cuttings along nonintersecting simple closed curves without separating it. -____ -+ -[TIP] -==== -Podle Wikipedie je _genus_ česky _rod plochy_. -==== -+ -[TIP] -==== -Je to *maximální* počet těch řezů. - -Následující povrch<> 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í*. - -image::./img/szp04_genus.png[width=500rem] -==== - -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. -+ -stem:[R = L - F] -+ -image::./img/szp04_rings.png[width=200rem] - -Shells (S):: -Spojené komponenty povrchu (množiny stěn). -+ -image::./img/szp04_shells.png[width=500rem] - -Eulerova charakteristika / Euler-Poincaré formula:: -Eulerova charakteristika stem:[\chi] popisuje topologický prostor či geometrický útvar stem:[M]. Je to topologický invariant -- nezmění se jakkoli je tento útvar pozohýbán. -+ -[stem] -++++ -\chi(M) = V - E + F \text{ (bez děr)} \\ -\chi(M) = V - E + F - R = 2 \cdot (S - G) \text{ (s děrami)} -++++ -+ -[IMPORTANT] -==== -Pro libovolný mnohostěn (polyhedron) bez děr je stem:[\chi = 2]. -==== -+ -[IMPORTANT] -==== -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 stem:[E = \frac{3}{2} F]. - -TIP: Intuitivně: pokud jsme neúsporní, pak máme tři hrany pro každý trojúhelník (stem:[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 (stem:[2E]), proto stem:[3F = 2E], tedy stem:[E = \frac{3}{2} F]. - -Z Euler-Poincaré plyne, že - -[stem] -++++ -V = 2 + E - F = 2 + \frac{3}{2} F - F = 2 + \frac{1}{2} F \sim \frac{1}{2} -++++ - --- -* Tedy platí poměr stem:[E:F:V = 3:2:1]. -* Tedy průmeřný vertex degree (počet hran, které vycházejí z vertexu) je stem:[2 \cdot \frac{E}{V} \sim 6]. --- - -[TIP] --- -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 stem:[2E], proto stem:[2E \sim 6V]. --- - -==== - -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. -+ -image::./img/szp04_adjacency_matrix.png[width=500] - -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ě. -+ --- -* stem:[c.v] -- vertex rohu, -* stem:[c.t] -- trojúhelník rohu, -* stem:[c.n] -- následující roh trojúhelníku, -* stem:[c.p] -- předchozí roh trojúhelníku, -* stem:[c.o] -- opačný roh v sousedním trojúhelníku (opačný roh kdyby to byl quad). -* stem:[c.r] -- "pravý" roh v sousedním trojúhelníku, -* stem:[c.l] -- "levý" roh v sousedním trojúhelníku. --- -+ -image::./img/szp04_corner_table.png[width=500] - -Half-edge data structure:: -Použitelná pro 2-manifoldy. Poskytuje rychlé hledání sousednosti. Umožňuje efektivní modifikace meshů. -+ -[source, 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; } -} ----- -+ -image::./img/szp04_half_edge.png[width=500] - - -=== Modelování - -IMPORTANT: Tahle sekce má docela průnik s otázkou link:../modelovani-3d-postav/[Modelování 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í. <> -+ -_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: stem:[V] -- vertices, stem:[E] -- edges, stem:[F] -- faces, stem:[H] -- components, stem:[S] -- shells, stem:[G] -- genus. <> <> -+ -NOTE: Zdá se, že stem:[H] -- components je ekvivalentní stem:[R] -- rings. -+ -Ač Eulerových operátorů se dá zadefinovat mnoho, v praxi stačí: -+ -[%header,cols="1,4"] -|==== -| Operátor -| Popis + +
+ +## 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)** + + ![Topology](./img/szp04_topology.png) + +- **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. + + ![width=100%](./img/szp04_manifold.png) + +- **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í. + + ![Möbiova páska](./img/szp04_mobius_strip.jpg) + ![Kleinova láev](./img/szp04_klein_bottle.jpg) + +- **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 + +
💡 TIP
+ + Podle Wikipedie je _genus_ česky _rod plochy_. +
+ +
💡 TIP
+ + 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í**. + + ![width=500rem](./img/szp04_genus.png) +
+ +- **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$ + + ![width=200rem](./img/szp04_rings.png) + +- **Shells (S)**\ + Spojené komponenty povrchu (množiny stěn). + + ![width=500rem](./img/szp04_shells.png) + +- **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)} + ``` + +
❗ IMPORTANT
+ + Pro libovolný mnohostěn (polyhedron) bez děr je $\chi = 2$. +
+ +
❗ IMPORTANT
+ + 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$. + +
+ +- **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. + + ![width=500](./img/szp04_adjacency_matrix.png) + +- **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. + + ![width=500](./img/szp04_corner_table.png) + +- **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; } + } + ``` + + ![width=500](./img/szp04_half_edge.png) + +### 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 @@ -279,273 +263,235 @@ Ač Eulerových operátorů se dá zadefinovat mnoho, v praxi stačí: | 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 stem:[\cap^*] -* `OR` - sjednocení stem:[\cup^*] -* `SUB` - rozdíl stem:[\setminus^*] --- -+ -Regularizace vypadá tak, že nejprve je provedena booleovská operace, poté je vypočítán _interior_ a následně _closure_. <> -+ --- -* _Interior point_ stem:[p] tělesa stem:[S] je takový bod, že existuje stem:[r] takové, že otevřená koule s poloměrem stem:[r] a středem v stem:[p] obsahuje jen body z stem:[S]. -* _Exterior point_ stem:[p] tělesa stem:[S] je takový bod, že existuje stem:[r] takové, že otevřená koule s poloměrem stem:[r] a střem v stem:[p] *nemá žádný průnik* s stem:[S]. -* _Interior_ tělesa stem:[S] je množina všech jeho interior pointů. -* _Exterior_ tělesa stem:[S] je množina všech jeho exterior pointů. -* _Boundary_ tělesa stem:[S] je množina bodů, které nejsou ani interior ani exterior tělesa stem:[S]. -* _Clusure_ tělesa stem:[S] je sjednocení jeho interior a boundary. --- -+ -[TIP] --- -_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 stem:[A \cap B] <> -image::./img/szp04_interior_boundary.png[width=200] -+ -.Příklad regularizovaného průniku <> -image::./img/szp04_rbo.png[width=100%] - -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 link:https://help.autodesk.com/view/3DSMAX/2016/ENU/?guid=GUID-51233298-312D-4773-AD22-ADB08E70CCE1[3ds Max] -image::./img/szp04_tapering.png[width=300] - -* _Twisting / screw / šroubování_ -- nekonstantní rotace okolo osy, -+ -.Twisting in link:https://help.autodesk.com/view/3DSMAX/2022/ENU/?guid=GUID-0AD7CE08-9992-4E49-BA11-672DEA3B13CF[3ds Max] -image::./img/szp04_twisting.png[width=300] - -* _Bending / ohýbání_ -- ohnutí rozsahu vertexů okolo daného bodu o daný úhel. -+ -.Bending in link:https://docs.blender.org/manual/en/latest/modeling/meshes/editing/mesh/transform/bend.html[Blender] -image::./img/szp04_bending.png[width=300] - --- - -Free-form deformations (FFD):: -Lokální deformace vertexů v dané "kleci" / mřížce / lattice -- Bezierově objemu. -+ --- -. Vyrob FFD mřížku (Bezierův objem). -. "Umísti" do objemu objekt, který chceš deformovat. -. Deformuj mřížku (hýbej s jejími body). -. Transformuj vertexy v mřížce podle změn v FFD prostoru. --- -+ -image::./img/szp04_ffd.png[width=400] -+ -Má řadu rozšíření s různými tvary mřížky. - -//// - -=== Filtrování - -Podobně jako 2D obrazy i meshe se dají filtrovat. Používá se k např. k odstranění šumu a zdůraznění důležitých částí. - -IMPORTANT: Filtrům se věnuje otázka link:../zpracovani-rastroveho-obrazu/[Zpracování rastrového obrazu]. - -Gaussian filter:: -Vážený součet vertexů. Vyhlazuje i hrany. - -Bilateral filter:: -Vyhlazuje, ale zachovává hrany. -+ -.Bilateral Normal Filtering for Mesh Denoising <> -image::./img/szp04_bilateral_filter.png[width=400] - -//// - - -=== Změna struktury sítě - -IMPORTANT: Modifikace meshů mají značný přesah do otázky link:../krivky-a-povrchy/[Křivky a povrchy] a taky link:../pokrocila-pocitacova-grafika/[Pokročilá počítačová grafika] - -Překlápění hrany / edge flip:: -Lokální změna, která nahradí hranu stem:[(b,c)] hranou stem:[(a,d)]. Trojúhelníky stem:[(a,b,c)] a stem:[(b,d,c)] se stanou stem:[(a,d,c)] a stem:[(a,b,d)]. <> -+ -image::./img/szp04_edge_flip.png[width=400] - -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. <> -+ -image::./img/szp04_edge_split.png[width=400] - -Zhroucení grany / edge collapse:: -Lokální změna, která nahrazuje hranu vrcholem. <> -+ -image::./img/szp04_edge_collapse.png[width=400] - -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. <> -+ -image::./img/szp04_subdivision.png[width=400] - -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ů. <> -+ -image::./img/szp04_mesh_regularization.png[width=400] +- **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)** -Isotropic remeshing:: -Algoritmus pro regularizaci meshů. Opakuje čtyři kroky: -+ --- -. Rozděl hrany delší než stem:[4 / 3] průměrné délky. -. Zhruť hrany kratší než stem:[4 / 5] průměrné délky. -. Překlop hrany, pokud to zlepší stupeň vrcholu (ideální je 6). -. 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_). <> -+ -image::./img/szp04_isotropic_remeshing.png[width=400] + ![width=200](./img/szp04_interior_boundary.png) + **Příklad regularizovaného průniku [pa010-2021](#pa010-2021)** -== Implicitní reprezentace a modelování + ![width=100%](./img/szp04_rbo.png) + +- **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)** + + ![width=300](./img/szp04_tapering.png) + + - _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)** + + ![width=300](./img/szp04_twisting.png) + + - _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)** + + ![width=300](./img/szp04_bending.png) + +- **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. + + ![width=400](./img/szp04_ffd.png) + + 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) + + ![width=400](./img/szp04_edge_flip.png) + +- **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) + + ![width=400](./img/szp04_edge_split.png) + +- **Zhroucení grany / edge collapse**\ + Lokální změna, která nahrazuje hranu vrcholem. [pa010-2021](#pa010-2021) + + ![width=400](./img/szp04_edge_collapse.png) + +- **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) + + ![width=400](./img/szp04_subdivision.png) + +- **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) + + ![width=400](./img/szp04_mesh_regularization.png) + +- **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) + + ![width=400](./img/szp04_isotropic_remeshing.png) + +## 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 stem:[p] a normálou stem:[N], ohraničuje poloprostor. Vzdálenost bodu od roviny je dána (za předpokladu, že stem:[N] je normalizovaná): -+ -[stem] -++++ -f(x) = (x - p) \cdot N -++++ - -Kvadriky / kvadratické plochy:: -* _Elipsoid_ (třeba koule): stem:[\frac{x^2}{a^2} + \frac{y^2}{b^2} + \frac{z^2}{c^2} = 1], -+ -.An ellipsoid by link:https://commons.wikimedia.org/w/index.php?curid=18447750[Sam Derbyshire] -image::./img/szp04_ellipsoid.png[width=200] - -* _Hyperboloid_ (třeba kužel): stem:[\frac{x^2}{a^2} + \frac{y^2}{b^2} - \frac{z^2}{c^2} = 1], -+ -.A one-sheeted hyperboloid by link:https://commons.wikimedia.org/w/index.php?curid=18447776[Sam Derbyshire] -image::./img/szp04_hyperboloid.png[width=200] - - -* _Válec (cylinder)_: stem:[\frac{x^2}{a^2} + \frac{y^2}{b^2} = 1], -+ -.A cylinder by link:https://commons.wikimedia.org/w/index.php?curid=18447784[Sam Derbyshire] -image::./img/szp04_cylinder.png[width=200] - -* _Paraboloid_ (třeba miska): stem:[\frac{x^2}{a^2} + \frac{y^2}{b^2} - z = 0], -+ -.A paraboloid by link:https://commons.wikimedia.org/w/index.php?curid=18447777[Sam Derbyshire] -image::./img/szp04_paraboloid.png[width=200] - -Kvartiky / kvartické plochy:: -* _Torus_ (donut): stem:[\left( \sqrt{x^2 + y^2} - R \right)^2 + z^2 - r^2 = 0]. -+ -.link:https://commons.wikimedia.org/w/index.php?curid=979546[A torus] -image::./img/szp04_torus.png[width=200] - -Distance surfaces:: -Tělesa lze definovat pomocí vzdálenosti od jiných entit: -+ --- -* _Sphere_: stem:[d(x, \text{point}) = r], -* _Cylinder / capsule_: stem:[d(x, \text{line}) = r], -* _Torus_: stem:[d(x, \text{circle}) = r], -* _Generalized cylinder_: stem:[d(x, \text{curve}) = r], -* _Offset surface_: stem:[d(x, \text{surface}) = r]. --- -+ -kde stem:[d(x, A)] je nejmenší vzdálenost bodu stem:[x] od entity stem:[A]. <> - -Constructive solid geometry (CSG):: -Umožňuje kombinovat implicitní objekty pomocí logických operací. Předpokládáme, že pokud stem:[f(x, y, z) < 0] pak je bod uvnitř objektu daném stem:[f]. Tato metoda nezachovává stem:[C^1] spojitost. Pro dva objekty stem:[f] a stem:[g]: <> -+ --- -* _Sjednocení_: stem:[\min(f, g)], -* _Průnik_: stem:[\max(f, g)], -* _Rozdíl_: stem:[\max(f, -g)]. -* _Komplement_: stem:[-f]. --- - -Bloby (kapky):: -Součet několika Gaussových křivek. <> -+ -[stem] -++++ -\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: -+ --- -* stem:[B_i] je "blobbiness", -* stem:[R_i] je poloměr blobu v klidu, -* stem:[D(r_i)] je Gaussova křivka, -* stem:[r_i] je funkce poloměru kapky. --- -+ -image::./img/szp04_blobs.png[width=300] - -Metaballs:: -Podobné blobům, ale nepoužívá exponenciální funkci. Organicky se "slévající" koule. <> -+ -[stem] -++++ -\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 link:https://commons.wikimedia.org/w/index.php?curid=5237220[SharkD] -image::./img/szp04_metaballs.png[width=100%] - - -[bibliography] -== 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]]] link:/fi/pa010/[Moje poznámky z PA010 (podzim 2020)] -* [[[manifold-wiki,4]]] link:https://en.wikipedia.org/wiki/Topological_manifold[Wikipedia: Topological manifold] -* [[[klein-bottle,5]]] link:https://plus.maths.org/content/imaging-maths-inside-klein-bottle[Konrad Polthier: Imaging maths - Inside the Klein bottle ] -* [[[genus,6]]] link:https://www.researchgate.net/publication/228393582_Notes_on_the_complex_of_curves[Saul Schleimer: Notes on the complex of curves] -* [[[topology, 7]]] link:https://www.austincc.edu/herbling/shape-of-space.pdf[Topology vs. Geometry] -* [[[boundaries, 8]]] link:https://link.springer.com/book/10.1007/978-1-84628-616-2[Ian Stroud: Boundary Representation Modelling Techniques] -* [[[rbo, 9]]] link:https://pages.mtu.edu/~shene/COURSES/cs3621/NOTES/model/closure.html[Interior, Exterior and Closure] -* [[[validity,10]]] link:https://www.sciencedirect.com/science/article/pii/S0010448500000476[Representational validity of boundary representation models] -* [[[denoising,11]]] link:https://ieeexplore.ieee.org/document/5674028[Bilateral Normal Filtering for Mesh Denoising] +- **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)** + + ![width=200](./img/szp04_ellipsoid.png) + + - _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)** + + ![width=200](./img/szp04_hyperboloid.png) + + - _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)** + + ![width=200](./img/szp04_cylinder.png) + + - _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)** + + ![width=200](./img/szp04_paraboloid.png) + +- **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)** + + ![width=200](./img/szp04_torus.png) + +- **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. + + ![width=300](./img/szp04_blobs.png) + +- **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)** + + ![width=100%](./img/szp04_metaballs.png) + +## 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) diff --git a/szmgr/SZP05_krivky_a_povrchy.md b/szmgr/SZP05_krivky_a_povrchy.md index ebc1238..f492069 100644 --- a/szmgr/SZP05_krivky_a_povrchy.md +++ b/szmgr/SZP05_krivky_a_povrchy.md @@ -1,430 +1,390 @@ -= Křivky a povrchy -:url: ./krivky-a-povrchy/ -:page-group: szp -:page-order: SZP05 +--- +title: "Křivky a povrchy" +description: "TODO" +--- -[NOTE] -==== -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:[NURBS, ]Coonsovy pass:[křivky a ]pláty. Povrchy tvořené rekurzivním dělením polygonů. +
📌 NOTE
+ +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_ -==== -== Druhy reprezentace +
+ +## Druhy reprezentace Jak povrchy tak křivky mohou být reprezentovány třemi způsoby: -=== Explicitní reprezentace +### Explicitní reprezentace -Křivka nebo povrch je vyjádřen pomocí *funkce*. +Křivka nebo povrch je vyjádřen pomocí **funkce**. -[stem] -++++ +```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 +### Implicitní reprezentace Máme k dispozici rovnici ve tvaru: -[stem] -++++ +```math \begin{align*} F(x, y) &= c & \text{ pro křivku} \\ F(x, y, z) &= c & \text{ pro povrch} \end{align*} -++++ +``` -kde stem:[c] je konstanta a je obvykle rovná 0. +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**\ +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 link:../3d-modelovani-a-datove-struktury/[3D modelování a datové struktury] -> _Implicitní reprezentace a modelování_. +**❗ IMPORTANT**\ +Tahle sekce přesahuje do [3D modelování a datové struktury](../3d-modelovani-a-datove-struktury/) -> _Implicitní reprezentace a modelování_. -=== Parametrická reprezentace +### 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í. +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: -[stem] -++++ +```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 stem:[t] je "čas" z intervalu stem:[\lbrack t_\text{min}, t_\text{max} \rbrack], nejčastěji stem:[\lbrack 0, 1 \rbrack]. Výhodné je, že takto zadaná křivka se může sama křížit, uzavírat, a podobně. +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: -[stem] -++++ +```math Q(u, v) = \lbrack x(u, v), y(u, v), z(u, v) \rbrack -++++ +``` -kde pro stem:[u] a stem:[v] už metafora s časem nefunguje. Obvykle obě náleží do intervalu stem:[\lbrack 0, 1 \rbrack]. +kde pro $u$ a $v$ už metafora s časem nefunguje. Obvykle obě náleží do intervalu $\lbrack 0, 1 \rbrack$. -== Terminologie +## 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 stem:[\vec{q}] ho lze v čase stem:[t_0] získat jako derivaci: -+ -[stem] -++++ -\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 stem:[\vec{p}] je pak stem:[\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: -+ -[stem] -++++ -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: -+ -[stem] -++++ -\begin{align*} +- **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: -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} + ```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) + ``` -\end{align*} -++++ -+ -Zapsáno pomocí matice: -+ -[stem] -++++ -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 stem:[\vec{q'}] je pak: -+ -[stem] -++++ -\vec{q'}(t) = \frac{\partial}{\partial t} \cdot C = \lbrack 3t^2, 2t, 1, 0 \rbrack \cdot C -++++ -+ -U kubik platí, že stem:[C = M \cdot G], kde stem:[M] je bázová matice a stem:[G] je vektor geometrických podmínek. -+ --- -* stem:[T \cdot M] definuje polynomiální bázi -- skupinu polynomů -- která je společná pro všechny křivky určitého typu. -* stem:[G] pak obsahuje parametry konkrétní křivky -- řídící a dotykové body. -* stem:[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 stem:[Q] je tečná plocha stem:[T] dána jako: -+ -[stem] -++++ -\begin{align*} + Rovnice tečny $\vec{p}$ je pak $\vec{p}(u) = \vec{q}(t_0) + \vec{q}'(t_0) \cdot u$. -\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) \\ +- **Polynomiální křivka**\ + Velmi častý druh křivek v počítačové grafice. Vypadají jako: -\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) \\ + ```math + Q_n(t) = a_0 + a_1 \cdot t + a_2 \cdot t^2 + \ldots + a_n \cdot t^n + ``` -T(r,s) &= Q(u,v) + r.\vec{q_{u}} + s.\vec{q_{v}}, \quad r,s \in \mathbb{R} + Je velmi snadné je evaluovat a derivovat. Z nich často skládáme křivky po částech. -\end{align*} -++++ -+ -kde stem:[\vec{q_u}] je tečný vektor ve směru parametru stem:[u], a analogicky stem:[\vec{q_v}] +- **Kubika**\ + Polynomiální křivka třetího stupně. -Normála / kolmice:: -Normálu stem:[\vec{n}] parametricky dané plochy stem:[Q] určíme jako vektorový součin tečných vektorů: -+ -[stem] -++++ -\vec{n} = \frac{\vec{q_u} \times \vec{q_v}}{\left\lVert \vec{q_u} \times \vec{q_v} \right\rVert} -++++ + Parametricky: -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 stem:[f] zadán implicitně, pak je gradient: -+ -[stem] -++++ -\nabla f = \left( - \frac{\partial f}{\partial x}, - \frac{\partial f}{\partial y}, - \frac{\partial f}{\partial z} -\right) -++++ + ```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} -== Interpolace a aproximace + \end{align*} + ``` -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 stem:[G] obsahuje body, kterými křivka prochází. -==== -+ -==== -Mějmě funkci stem:[f(x)], jejíž hodnotu známe v bodech stem:[f(x_0), f(x_1), \ldots, f(x_n)]. Interpolace znamená nalezení hodnot stem:[f(x)] pro všechna stem:[x_0 < x < x_n]. -==== + Zapsáno pomocí matice: -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 stem:[G] obsahuje _řídící_ body, které sice udávají směr křivky, ale ta jimi neprochází. -==== + ```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} + ``` -== Spojitost + Tečný vektor $\vec{q'}$ je pak: -Představme si, že máme dva segmenty křivky: stem:[Q_1] a stem:[Q_2], spojené v bodě stem:[t], tedy stem:[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. + ```math + \vec{q'}(t) = \frac{\partial}{\partial t} \cdot C = \lbrack 3t^2, 2t, 1, 0 \rbrack \cdot C + ``` -=== Parametrická spojitost stupně stem:[n] (stem:[C^n]) + U kubik platí, že $C = M \cdot G$, kde $M$ je bázová matice a $G$ je vektor geometrických podmínek. -Křivka stem:[Q] patří do třídy stem:[C^n], pokud má ve všech bodech stem:[t] spojitou derivaci až do řádu stem:[n]. + - $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. --- -* stem:[C^0] -- dva segmenty jsou spojené; konečný bod jednoho segmentu je počátečním bodem druhého. -* stem:[C^1] -- platí stem:[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. -* stem:[C^2] -- platí stem:[C^1] a druhé derivace v uzlu jsou si rovny. -* stem:[C^n] -- platí stem:[C^{n-1}] a navíc jsou si stem:[n]-té derivace v uzlu rovny. --- +- **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: -==== -* Bod pohybující se po stem:[C^0]-spojité dráze sebou "trhne" *v prostoru*, když projde uzlem. -* V případě stem:[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ě stem:[C^2] křivky se při průchodu uzlem *nezmění* už ani zrychlení. -==== + ```math + \begin{align*} -=== Geometrická spojitost stupně stem:[n] (stem:[G^n]) + \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) \\ -Je podobná parametrické spojitosti, ale vyžaduje jen "geometrickou" spojitost. Vyžaduje, aby si derivace byly *sobě úměrné*. <> <> + \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) \\ --- -* stem:[G^0] -- koncový bod prvního segmentu je totožný s počátečním bodem druhého segmentu (stem:[C^0 = G^0]). -* stem:[G^1] -- platí stem:[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.* -* stem:[G^2] -- platí stem:[G^1] a navíc mají stejný *střed křivosti* (center of curvature). <> --- + T(r,s) &= Q(u,v) + r.\vec{q_{u}} + s.\vec{q_{v}}, \quad r,s \in \mathbb{R} -Platí, že stem:[C^n \Rightarrow G^n], ale obráceně stem:[G^n \not\Rightarrow C^n]. + \end{align*} + ``` -NOTE: Podle slidů z PB009 musí faktor úměrnosti být různý od 0. <> Podle Barskyho a DeRoseho musí v první derivaci být stem:[> 0] a v dalších už je to šumák. <> Co je správně? Kdo ví. Nemám dost častu to zjistit, takže to ponechávám jako cvičení čtenáři. + kde $\vec{q_u}$ je tečný vektor ve směru parametru $u$, a analogicky $\vec{q_v}$ -== Křivky +- **Normála / kolmice**\ + Normálu $\vec{n}$ parametricky dané plochy $Q$ určíme jako vektorový součin tečných vektorů: -=== Lagrangeův interpolační polynom + ```math + \vec{n} = \frac{\vec{q_u} \times \vec{q_v}}{\left\lVert \vec{q_u} \times \vec{q_v} \right\rVert} + ``` -Základní metoda interpolace funkce, jejíž hodnotu známe jen v stem:[n + 1] diskrétních bodech stem:[P_0, P_1, ... P_n]. Sestává se z pomocných polynomů stem:[\ell_i]: <> +- **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: -[stem] -++++ + ```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: -[stem] -++++ +```math \ell_i(x_k) = \begin{cases} 1 & \text{ pro } i = k \\ 0 & \text{ pro } i \neq k \end{cases} -++++ +``` -Pak polynom stem:[P] interpoluje danou množinu bodů: +Pak polynom $P$ interpoluje danou množinu bodů: -[stem] -++++ +```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: <> -+ -[stem] -++++ -\begin{aligned} +- **Hornerovo schéma / Horner’s method**\ + Metoda evaluace polynomů. Vychází z myšlenky, že násobení se dá nestovat: [horner](#horner) -& a_0 + a_1 \cdot x + a_2 \cdot x^2 + ... + a_n \cdot x_n \\ + ```math + \begin{aligned} -& = a_0 + x(a_1 + x(a_2 + ... + x(a_{n-1} + x \cdot a_n)...)) -\end{aligned} -++++ -+ -Vyžaduje jen stem:[n] násobení a stem:[n] sčítání, což je optimální. + & a_0 + a_1 \cdot x + a_2 \cdot x^2 + ... + a_n \cdot x_n \\ -=== Hermitovské křivky + & = a_0 + x(a_1 + x(a_2 + ... + x(a_{n-1} + x \cdot a_n)...)) + \end{aligned} + ``` -Asi nejznámnější interpolační křivky v počítačové grafice. Jsou určeny dvěma řídícími body -- stem:[P_0] a stem:[P_1] -- a dvěma dotykovými vektory -- stem:[\vec{p_0'}] a stem:[\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. + Vyžaduje jen $n$ násobení a $n$ sčítání, což je optimální. -Je jednoduché je na sebe navázat v stem:[C^1], neboť tečné vektory jsou přímo součástí definice. +### Hermitovské křivky -Cubic Hermite spline / Ferguson curve:: -Pro Hermitovskou kubiku platí: <> <> -+ -[stem] -++++ -\begin{aligned} +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. -Q(t) &= +Je jednoduché je na sebe navázat v $C^1$, neboť tečné vektory jsou přímo součástí definice. -\begin{bmatrix} - t^{3} & t^{2} & t & 1 -\end{bmatrix} +- **Cubic Hermite spline / Ferguson curve**\ + Pro Hermitovskou kubiku platí: [hermite-spline](#hermite-spline) [ferguson](#ferguson) -\cdot + ```math + \begin{aligned} -\begin{bmatrix} - 2 & -2 & 1 & 1 \\ - -3 & 3 & -2 & -1 \\ - 0 & 0 & 1 & 0 \\ - 1 & 0 & 0 & 0 -\end{bmatrix} + Q(t) &= -\cdot + \begin{bmatrix} + t^{3} & t^{2} & t & 1 + \end{bmatrix} -\begin{bmatrix} - P_{0} \\ - P_{1} \\ - \vec{p'}_{0} \\ - \vec{p'}_{1} -\end{bmatrix} = \\ + \cdot -&= 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) + \begin{bmatrix} + 2 & -2 & 1 & 1 \\ + -3 & 3 & -2 & -1 \\ + 0 & 0 & 1 & 0 \\ + 1 & 0 & 0 & 0 + \end{bmatrix} -\end{aligned} -++++ -+ -kde stem:[F_1, F_2, F_3, F_4] jsou Hermitovské polynomy 3. stupně: -+ -[stem] -++++ -\begin{aligned} + \cdot -\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 + \begin{bmatrix} + P_{0} \\ + P_{1} \\ + \vec{p'}_{0} \\ + \vec{p'}_{1} + \end{bmatrix} = \\ -\end{aligned} -++++ -+ -image::./img/szp05_hermite.png[width=500] + &= 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) -=== Bézierova křivka + \end{aligned} + ``` -Asi nejčastěji používaná *aproximační* křivka. Využívá se zejména ve 2D grafice, třeba při definici fontů. + kde $F_1, F_2, F_3, F_4$ jsou Hermitovské polynomy 3. stupně: --- -* Bézierova křivka stem:[n]-tého stupně je definována stem:[n + 1] řídícími body stem:[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. --- + ```math + \begin{aligned} -Základem jsou *Bernsteinovy polynomy* stem:[n]-tého stupně: + \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 -[stem] -++++ -b_{\nu,n}(x) = \binom{n}{\nu} x^{\nu} \left( 1 - x \right)^{n - \nu}, \quad \nu = 0, \ldots, n, -++++ + \end{aligned} + ``` -Mezi jejich vlastnosti patří: + ![width=500](./img/szp05_hermite.png) + +### Bézierova křivka --- -* Nezápornost: stem:[b_{\nu,n}(x) \ge 0] pro stem:[x \in \lbrack 0, 1 \rbrack]. -* Jejich součet je roven jedné: stem:[\sum_{\nu = 0}^n b_{\nu,n}(x) = 1]. -* Dají se vyjádřit rekurzí: stem:[b_{\nu,n}(x) = (1 - x) \cdot b_{\nu,n-1}(x) + x \cdot b_{\nu-1,n-1}(x)]. --- +Asi nejčastěji používaná **aproximační** křivka. Využívá se zejména ve 2D grafice, třeba při definici fontů. -.Bernstein basis polynomials for 4th degree curve blending by link:https://commons.wikimedia.org/w/index.php?curid=40129768[VisorZ] -image::./img/szp05_bernstein.svg[width=500] +- 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. -DeCasteljau algorithm:: -Rekurzivní algoritmus pro konstrukci Bézierových křivek. Využívá vlastností Bernsteinových polynomů. -+ -image::./img/szp05_decasteljau.png[width=100%] +Základem jsou **Bernsteinovy polynomy** $n$-tého stupně: -Bézierova kubika:: -Bézierova křivka třetího stupně. Je dána čtyřmi řídícími body stem:[P_0, P_1, P_2, P_3]: -+ [stem] -++++ -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ě stem:[n] po částech definovaná polynomiální funkce stupně stem:[n-1] proměnné stem:[x]. <> -+ -[TIP] --- -_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í stem:[t_0, t_1, ..., t_n] a řazeny v neklesajícím pořadí. -* Pokud jsou uzly unikátní, pak je splajn v uzlech stem:[C^{n-2}] spojitý. <> -* Pokud je stem:[r] uzlů shodných, je v tomto místě pouze stem:[C^{n-r-1}] spojitý. --- +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)** + +![width=500](./img/szp05_bernstein.svg) + +- **DeCasteljau algorithm**\ + Rekurzivní algoritmus pro konstrukci Bézierových křivek. Využívá vlastností Bernsteinových polynomů. + + ![width=100%](./img/szp05_decasteljau.png) + +- **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ě stem:[n] je aproximační křivka / splajn daná sekvencí stem:[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. +**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: +Lze ji definovat pomocí **Cox-de Boorovy** rekurzivní formule: -TIP: de Boorův algoritmus je generalizací DeCasteljauova algoritmu ale pro B-splajny. +**💡 TIP**\ +de Boorův algoritmus je generalizací DeCasteljauova algoritmu ale pro B-splajny. -[stem] -++++ +```math \begin{aligned} B_{i,0}(x) &= \begin{cases} @@ -438,383 +398,291 @@ 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 stem:[x] jde od stem:[t_i] k stem:[t_{i+n}], červený výraz začíná na 1 a klesá k 0. +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 stem:[x] jde od stem:[t_{i+1}] k stem:[t_{i+n+1}], modrý výraz začíná na 0 a roste k 1. +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í stem:[\sum_{i=0}^{n} B_{i,n}(x) = 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ě stem:[n] daný sekvencí uzlů lze vyjádřit jako lineární kombinaci B-splajnů: +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ů: -[stem] -++++ +```math S(x) = \sum_{i=0} c_i B_{i,n}(x) -++++ +``` -NOTE: Uzlů je zpravidla víc než stem:[n+1], protože pak teprve máme víc než jeden B-spline, který kombinujeme. +**📌 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 stem:[t_i] a stem:[t_{i+1}] je stejná vzdálenost stem:[h]. -+ -Příklad: -+ -[stem] -++++ -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 stem:[P] daná 4 řídícími body stem:[P_0, P_1, P_2, P_3]. Neprochází ani jedním z kontrolních bodů. <> -+ -[stem] -++++ -\begin{aligned} +- **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(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 \\ + Příklad: -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 + ```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} + ``` -\end{aligned} -++++ -+ -image::./img/szp05_coons_basis.png[width=400] -+ -NOTE: Něco ohledně tohohle termínu mi hrozně smrdí. Zdá se, že jediní, kdo používají "coons cubic curve" jsme my a ČVUT. - -//// - -Coonsovy křivky / uniformní neracionální B-splajny:: -+ --- -* Vzniká navazování Coonsových kubik. -* Vyžaduje stem:[m \ge 4] body. -* Skládá se pak z stem:[m - 3] segmentů. -* Každý segment stem:[Q_i] je určený body stem:[P_{i-3}, P_{i-2}, P_{i-1}, P_i]. -* Segmenty na sebe navazují s stem:[C^2] spojitostí. -* Změna pozice jednoho kontrolního bodu ovlivňuje jen ty segmenty, které řídí. Tedy nejvýše 3. Zejména tedy ne celou křivku. -* Jsou invariantní (neměnné) vzhledem k otočení, posunutí a škálování. -* Leží v konvexním obalu řídících bodů. --- -+ -image::./img/szp05_coons_bspline.png[width=400] - -Non-Uniform Rational B-Splines (NURBS):: -Zevšeobecnění uniformních neracionálních B-splajnů. -+ --- -* Neuniformní jsou, protože vzdálenost mezi stem:[t_0, t_1, ..., t_n] nemusí být stejná. -* Racionální znamená, že řídící body mají váhy. -** Váhy jsou uloženy pomocí homogenních souřadnic v dimenzi stem:[w]. -** S vyšší vahou křivka víc lne ke danému bodu. -** Pokud jsou nezáporné, křivka bude v konvexním obalu polygonu daného řídícími body. -** Při stem:[w = \infty] křivka podem prochází, ale dochází ke ztrátě spojitosti. -* Je dána pomocí: -** stem:[n \ge 4] body stem:[P_0, P_1, ..., P_n], -** řádem stem:[k], který říká, že polynomy budou mít stupeň nejvýše stem:[k-1], -** uzlovým vektorem stem:[(t_0, t_1, ..., t_{n+k})], který obsahuje neklesající posloupnost uzlových hodnot. -* Pro konstrukci se používá de Booreho vztah výše. --- -+ -[stem] -++++ -Q(t) = \frac{ - \sum_{i=0}^n w_i \cdot P_i \cdot B_{i,k}(t) -} -{ - \sum_{i=0}^n w_i \cdot B_{i,k}(t) -} -++++ -+ -image::./img/szp05_nurbs.png[width=400] - -Kuželosečky pomocí NURBS:: -Vahy umožňují NURBS vyjádřit kuželosečky (kruhy, elipsy, atd.). -+ -image::./img/szp05_kuzelosecky.png[width=400] - -//// - -== Povrchy +- **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} + ``` + + ![width=400](./img/szp05_coons_basis.png) + + **📌 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 +### Interpolační plocha -Plocha stem:[\vec{P}]. +Plocha $\vec{P}$. Dáno: -* stem:[(m + 1) \times (n + 1)] řídících bodů stem:[\vec{P}_{i,j}]. -* stem:[m + 1] hodnot stem:[u_k] a stem:[n + 1] hodnot stem:[v_l]. +- $(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 stem:[\vec{P}(u_k, u_l) = \vec{P}_{k,l}] pro stem:[k = 0, 1, ..., m] a stem:[l = 0, 1, ..., n]. +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 stem:[\vec{a}_{i,j}]: +Interpolujeme vektorovým polynomem $\vec{a}_{i,j}$: -[stem] -++++ +```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 stem:[\vec{a}_{i,j} = \ell_i^m(u) \cdot \ell_j^n(v)]. +V případě Lagrangeova polynomu je $\vec{a}_{i,j} = \ell_i^m(u) \cdot \ell_j^n(v)$. - -=== Hermitovský plát +### Hermitovský plát Interpolační povrch. -12-ti vektorová varianta:: -4 rohové body a 8 tečných vektorů. -+ -image::./img/szp05_hermite_plate_12.png[width=300] +- **12-ti vektorová varianta**\ + 4 rohové body a 8 tečných vektorů. + + ![width=300](./img/szp05_hermite_plate_12.png) -16-ti vektorová varianta:: -4 rohové body, 8 tečných vektorů a 4 zkrutové vektory. -+ -image::./img/szp05_hermite_plate_16.png[width=300] +- **16-ti vektorová varianta**\ + 4 rohové body, 8 tečných vektorů a 4 zkrutové vektory. + ![width=300](./img/szp05_hermite_plate_16.png) -=== Coonsovy pláty / Coonsovy plochy / Coons patch +### 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í*. +**⚠️ 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 stem:[P(u, 0), P(u, 1), P(0, v), P(1, v)], které tvoří okraj plátu. +- **Bilineární Coonsovy pláty** -Implicitně se dá zapsat jako: + Určeny 4 křivkami $P(u, 0), P(u, 1), P(0, v), P(1, v)$, které tvoří okraj plátu. -[stem] -++++ -\begin{bmatrix} -1-u & -1 & u -\end{bmatrix} + Implicitně se dá zapsat jako: -\cdot + ```math + \begin{bmatrix} + 1-u & -1 & u + \end{bmatrix} -C + \cdot -\cdot + C -\begin{bmatrix} -1-v \\ -1 \\ v -\end{bmatrix} + \cdot -= 0 -++++ + \begin{bmatrix} + 1-v \\ -1 \\ v + \end{bmatrix} -Povrch je pak tvořen body stem:[C], které tuto rovnici splňují. + = 0 + ``` -Explicitně se dá zapsat jako: + Povrch je pak tvořen body $C$, které tuto rovnici splňují. -[stem] -++++ -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} -++++ - -image::./img/szp05_bilinear.png[width=400] - -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: + Explicitně se dá zapsat jako: -[stem] -++++ -\begin{aligned} + ```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} + ``` -F_1(t) &= 2t^3 - 3t^2 + 1 \\ -F_2(t) &= -2t^3 + 3t^2 \\ + ![width=400](./img/szp05_bilinear.png) -\end{aligned} -++++ + 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. -Implicitně je pak tento plát dán: +- **Bikubické Coonsovy pláty** -[stem] -++++ -\begin{bmatrix} -F_1(u) & -1 & F_2(u) -\end{bmatrix} + Podobné bilineárním, ale používájí Hermitovské polynomy: -\cdot + ```math + \begin{aligned} -C + F_1(t) &= 2t^3 - 3t^2 + 1 \\ + F_2(t) &= -2t^3 + 3t^2 \\ -\cdot + \end{aligned} + ``` -\begin{bmatrix} -F_1(v) \\ -1 \\ F_2(v) -\end{bmatrix} + Implicitně je pak tento plát dán: -= 0 -++++ + ```math + \begin{bmatrix} + F_1(u) & -1 & F_2(u) + \end{bmatrix} -Stejně jako u bilineárních ploch, i tady je těžké získat tečné vektory na okrajích. --- + \cdot -Obecná bikubická plocha:: -+ --- -Kromě rohů je parametrizována i tečnými vektory na okrajích. Konečně tedy umožňuje snadné navazování. --- + C -=== Bézierovy plochy + \cdot -Aproximační plochy dány stem:[(m + 1) \times (n + 1)] řídícími body. Jsou: + \begin{bmatrix} + F_1(v) \\ -1 \\ F_2(v) + \end{bmatrix} --- -* snadno diferencovatelné, -* jednoduše se modelují, -* lze z nich relativně snadno spočítat průnik s paprskem, -* speciální případ NURBS ploch. --- + = 0 + ``` -[stem] -++++ + 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 stem:[B_i^m(u)] a stem:[B_j^n(v)] jsou Bernsteinovy polynomy. +Kde $B_i^m(u)$ a $B_j^n(v)$ jsou Bernsteinovy polynomy. -image::./img/szp05_bezier_plate.png[width=400] +![width=400](./img/szp05_bezier_plate.png) -Při změně jendoho z bodů se změní celá plocha, proto se často více plátů spojuje dohromady. Pro spojitost stem:[G^0] se musí rovnat řídící body na okrajích. Pro stem:[G^0] musí tečné vektory na okrajích být lineárně závislé. +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 +### 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ě stem:[k] garantují spojitost stem:[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. --- +- 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. <> Jsou invariantní k lineárním transformacím i k perspektivní projekci. +- **NURBS plochy** -[stem] -++++ -S(u,v) = \sum_{i=1}^k \sum_{j=1}^l R_{i,j}(u,v) \mathbf{P}_{i,j} -++++ + 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. -kde stem:[\mathbf{P}_{i,j}] jsou řídící body a stem:[R_{i,j}(u,v)] jsou NURBS bázové funkce: + ```math + S(u,v) = \sum_{i=1}^k \sum_{j=1}^l R_{i,j}(u,v) \mathbf{P}_{i,j} + ``` -[stem] -++++ -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}} -++++ + kde $\mathbf{P}_{i,j}$ jsou řídící body a $R_{i,j}(u,v)$ jsou NURBS bázové funkce: -stem:[N_{i,n}(u)] a stem:[N_{j,m}(v)] jsou B-spline bázové funkce stupně stem:[n] a stem:[m]. stem:[w_{i,j}] jsou váhy. --- + ```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}} + ``` -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. <> + $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ů +## 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 stem:[C^1] křivkou. --- - -Catmull-Clark:: -+ --- -Aproximuje původní mesh. Zachovává stem:[C^2], na mimořádných bodech ale jen stem:[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. - -image::./img/szp05_doo_sabin.png[width=400] --- - -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. --- - -[bibliography] -== 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]]] link:https://en.wikipedia.org/wiki/Smoothness[Wikipedia: Smoothness] -* [[[mallinus,5]]] link:https://www.cs.helsinki.fi/group/goa/mallinnus/curves/curves.html[Jaakko Kurhila and Matti Mäkelä: Parametric Curves] -// mallinus = modeling in Finnish -* [[[geometric-continuity,6]]] link:https://ieeexplore.ieee.org/document/41470[Geometric Continuity of Parametric Curves: Three Equivalent Characterizations] -* [[[lagrange, 7]]] link:https://en.wikipedia.org/wiki/Lagrange_polynomial[Wikipedia: Lagrange polynomial] -* [[[bspline, 8]]] link:https://en.wikipedia.org/wiki/B-spline[Wikipedia: B-spline] -* [[[hermite-spline, 9]]] link:https://en.wikipedia.org/wiki/Cubic_Hermite_spline[Wikipedia: Cubic Hermite spline] -* [[[ferguson, 10]]] link:https://marian.fsik.cvut.cz/~kongo/download/pcgr/lectures/01%20crv_ferg.pdf[ČVUT: Ferguson curve] -* [[[coons, 11]]] link:https://marian.fsik.cvut.cz/~kongo/download/pcgr/lectures/03%20crv_coons.pdf[ČVUT: Coons curve] -* [[[coons-path, 12]]] link:https://en.wikipedia.org/wiki/Coons_patch[Wikipedia: Coons patch] -* [[[nurbs, 13]]] link:https://en.wikipedia.org/wiki/Non-uniform_rational_B-spline[Wikipedia: Non-uniform rational B-spline] -* [[[sweeping,14]]] link:https://en.wikipedia.org/wiki/Solid_modeling#Sweeping[Wikipedia: Solid modeling] -* [[[horner,15]]] link:https://en.wikipedia.org/wiki/Horner%27s_method[Wikipedia: Horner's method] - -== Další zdroje - -* link:http://nurbscalculator.in/[NURBS Calculator] -* link:https://mat.fs.cvut.cz/computer-graphics/[ČVUT: Computer Graphics] - -[pass] -
-
+- **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. + + ![width=400](./img/szp05_doo_sabin.png) + +- **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> diff --git a/szmgr/SZP06_strojove_uceni.md b/szmgr/SZP06_strojove_uceni.md index 03eaf0c..5a517f5 100644 --- a/szmgr/SZP06_strojove_uceni.md +++ b/szmgr/SZP06_strojove_uceni.md @@ -1,260 +1,225 @@ -= Strojové učení -:url: ./strojove-uceni/ -:page-group: szp -:page-order: SZP06 +--- +title: "Strojové učení" +description: "TODO" +--- -[NOTE] -==== -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:[Hopfieldova síť, ]konvoluční sítě, rekurentní sítěpass:[, samo-organizující mapy]. +
📌 NOTE
+ +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_ -==== -TIP: Velkou část zpracování téhle otázky jsem ukradl link:/fi/pv021/[sám sobě]. +
-== Strojové učení a rozpoznávání vzorů +**💡 TIP**\ +Velkou část zpracování téhle otázky jsem ukradl [sám sobě](/fi/pv021/). -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. <> <> +## Strojové učení a rozpoznávání vzorů -Používá se např. pro: +- **Machine learning / strojové učení** -* filtrování spamu v emailech, -* rozpoznávání řeči, rukopisu, tváří, zvuků, atd., -* klasifikaci textů, -* herní strategie, -* analýzu trhu, -* autonomní řízení vozidel. --- + 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) -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_. <> + Používá se např. pro: -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ří. <> + - filtrování spamu v emailech, + - rozpoznávání řeči, rukopisu, tváří, zvuků, atd., + - klasifikaci textů, + - herní strategie, + - analýzu trhu, + - autonomní řízení vozidel. -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. <> -+ -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. <> +- **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) -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. <> -+ -Souvisejícím problémem je vyjádření toho, že jsou si data v nějakém smyslu _podobná_. + 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) -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. <> +- **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) -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. <> + Souvisejícím problémem je vyjádření toho, že jsou si data v nějakém smyslu _podobná_. -== Neuronové sítě +- **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) -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í. +## Neuronové 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í). --- +- **Neural network / neuronová síť** -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_. + 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í. -Stav sítě:: -Vektor výstupů všech neuronů sítě (nejen output). + 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í). -Stavový prostor sítě:: -Množina všech možných stavů sítě. +- **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. -Vstup sítě:: -Vektor reálných čísel (prvek stem:[\Reals^n]), kde stem:[n] je počet vstupů. + Síť být cyklická -- _recurrent_ -- nebo acyklická -- _feed-forward_. -Vstupní prostor sítě:: -Množina všech vstupů sítě. +- **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: -Iniciální stav:: -Input neuronům je za výstup (stem:[y]) dán vektor vstupů (stem:[\vec{x}]). Všem ostatním neuronům je výstup (stem:[y]) nastaven na 0. + 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ýstup sítě:: -Vektor výstupů (stem:[y]) output neuronů. Výstup se v průběhu výpočtu může měnit. + 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. -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í). -Konfigurace:: -Vektor hodnot všech vah. +## Multilayer perceptron (MLP) / vícevrstvé neuronové sítě -Vahový prostor:: -Množina všech konfigurací. +- **Perceptron -- jeden neuron** -Iniciální konfigurace:: -Počáteční hodnoty vah (než začne trénování). + - 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ě. + ![width=400](./img/szp06_perceptron.png) -== Multilayer perceptron (MLP) / vícevrstvé neuronové sítě + - $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 -Perceptron -- jeden neuron:: -+ --- + **📌 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$. -* Hrubá matematická aproximace biologického neuronu. -* Binární klasifikátor -- rozlišuje jestli vstup patří nebo nepatří do nějaké jedné kategorie.<> -* Linerání klasifikátor -- jeho funkce kombinuje vstupy lineárně. +- **Multilayer perceptron (MLP)** -image::./img/szp06_perceptron.png[width=400] + MLP je feed-forward (neobsahuje cykly) architektura NN, kde platí: -* stem:[x_i] -- inputy -* stem:[w_i] -- váhy -* stem:[\xi = w_0 + \sum_{i=1}^n w_i x_i] -- vnitřní potenciál -* stem:[y] -- výstup -* stem:[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) -* stem:[x_0] -- pro snažší implementaci se závádí dodatečný vstup, který má vždy hodnotu 1 a váhu rovnu -bias + - 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ě. -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 stem:[\xi < 0] a kde stem:[\xi > 0]. + ![width=400](./img/szp06_mlp.png) --- + Kde: -Multilayer perceptron (MLP):: -+ --- + - $\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) -MLP je feed-forward (neobsahuje cykly) architektura NN, kde platí: +### Aktivita -* 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 stem:[i]-té vrstvě je napojen na každý neuron v stem:[(i + 1)]-ní vrstvě. +- **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á". -image::./img/szp06_mlp.png[width=400] + ```math + \sigma(\xi) = \frac{1}{1 + e^{-\lambda \cdot \xi}} + ``` -Kde: + kde $\lambda$ je _steepness_ parametr, který určuje, jak rychle sigmoid roste. -* stem:[\textcolor{green}{X}] -- množina input neuronů -* stem:[\textcolor{red}{Y}] -- množina output neuronů -* stem:[Z] -- množina všech neuronů -* Neurony mají indexy stem:[i], stem:[j], ... -* stem:[\xi_j] -- vnitřní potenciál neuronu stem:[j] po skončení výpočtu -* stem:[y_j] -- výstup neuronu stem:[j] po skončení výpočtu -* stem:[x_0 = 1] -- hodnota formálního jednotkového vstupu (kvůli biasům) -* stem:[w_{j,i}] -- váha spojení *z* neuronu stem:[i] *do* neuronu stem:[j] (dst <- src) -* stem:[w_{j,0} = -b_j] -- bias -- váha z formální jednotky do neuronu stem:[j] -* stem:[j_{\leftarrow}] -- množina neuronů stem:[i], jenž mají spojení *do* stem:[j] (j <- i) -* stem:[j^{\rightarrow}] -- množina neuronů stem:[i], do nichž vede spojení *z* stem:[j] (j -> i) + ![width=400](./img/szp06_sigmoid.png) --- +### Trénink -=== Aktivita +**❗ IMPORTANT**\ +Pro likelihood viz otázka [Statistika](../statistika/). -Pravidlo pro výběr neuronů při výpočtu:: -V i-tému kroku vezmi i-tou vrstvu. +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_. -Vnitřní potenciál neuronu stem:[j]:: -stem:[\xi_j = \sum_{i \in j_{\leftarrow}} w_{ji}y_i] +- **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. -Aktivační funkce neuronu stem:[j]:: -stem:[\sigma_j : \Reals \to \Reals] (třeba logistic sigmoid) + ```math + \mathcal{T} = \{(\vec{x}_1, \vec{d}_1), (\vec{x}_2, \vec{d}_2), ..., (\vec{x}_p, \vec{d}_p)\} + ``` -Stav nevstupního neuronu stem:[j]:: -stem:[y_j = \sigma_j(\xi_j)] resp. stem:[y_j(\vec{w}, \vec{x})] +- **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. -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á". -+ -[stem] -++++ -\sigma(\xi) = \frac{1}{1 + e^{-\lambda \cdot \xi}} -++++ -+ -kde stem:[\lambda] je _steepness_ parametr, který určuje, jak rychle sigmoid roste. -+ -image::./img/szp06_sigmoid.png[width=400] + Její volba závisí na tom, co NN modeluje. Např. volíme: -=== Trénink + - _mean squared error_ (MSE) -- pro regresi, -IMPORTANT: Pro likelihood viz otázka link:../statistika/[Statistika]. + ```math + \begin{aligned} -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 stem:[\cal T]. Tomuhle přístupu se říká _maximum likelihood principle_. + E_k(\vec{w}) &= \frac{1}{2} \sum_{j \in Y} + \left( + y_j(\vec{w}, \vec{x_k}) - d_{kj} + \right)^2 \\ -Training set stem:[\cal T]:: -je množina stem:[p] samplů, kde stem:[\vec{x} \in \Reals^{|X|}] jsou vstupní vektory a stem:[\vec{d} \in \Reals^{|Y|}] jejich očekáváné výstupy. -+ -[stem] -++++ -\mathcal{T} = \{(\vec{x}_1, \vec{d}_1), (\vec{x}_2, \vec{d}_2), ..., (\vec{x}_p, \vec{d}_p)\} -++++ + E(\vec{w}) &= \textcolor{red}{\frac{1}{p}} \sum_{k=1}^p E_k(\vec{w}) -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, -+ -[stem] -++++ -\begin{aligned} + \end{aligned} + ``` -E_k(\vec{w}) &= \frac{1}{2} \sum_{j \in Y} - \left( - y_j(\vec{w}, \vec{x_k}) - d_{kj} - \right)^2 \\ + - _(categorical) cross-entropy_ -- pro (multi-class) klasifikaci. -E(\vec{w}) &= \textcolor{red}{\frac{1}{p}} \sum_{k=1}^p E_k(\vec{w}) + ```math + \begin{aligned} -\end{aligned} -++++ + E(\vec{w}) = -\frac{1}{p} \sum_{k=1}^p \sum_{j \in Y} d_{kj} \ln(y_j) -* _(categorical) cross-entropy_ -- pro (multi-class) klasifikaci. -+ -[stem] -++++ -\begin{aligned} + \end{aligned} + ``` -E(\vec{w}) = -\frac{1}{p} \sum_{k=1}^p \sum_{j \in Y} d_{kj} \ln(y_j) +- **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. -\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. -+ -[stem] -++++ -\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 stem:[T], a váhy upravuješ až po zpracování minibatche. -+ -[stem] -++++ -\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 stem:[\varepsilon]:: -Hyperparametr stem:[0 < \varepsilon \le 1] ovlivňující rychlost učení. Může záviset na iteraci stem:[t], pak je to funkce stem:[\varepsilon(t)]. - -.Gradient descent v MLP -==== - -[stem] -++++ + ```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)} @@ -274,14 +239,14 @@ w_{ji}^{(t+1)} \cdot \textcolor{purple}{\sigma'_j(\xi_j)} \cdot \textcolor{teal}{y_i} \end{aligned} -++++ +``` -Za předpokladu, že stem:[E] je squared error, pak: +Za předpokladu, že $E$ je squared error, pak: -WARNING: V případě, že stem:[E] není squared error, následující výpočet neplatí. +**⚠️ WARNING**\ +V případě, že $E$ není squared error, následující výpočet neplatí. -[stem] -++++ +```math \large \textcolor{red}{\frac{\partial E_k}{\partial y_j}} = \begin{cases} @@ -294,321 +259,191 @@ WARNING: V případě, že stem:[E] není squared error, následující výpoče \cdot \textcolor{forestgreen}{w_{rj}} & \text{ jinak}. \end{cases} -++++ - -.Algoritmus pro výpočet stem:[\frac{\partial E}{\partial w_{ji}}] -1. Inicializuj stem:[\varepsilon_{ji} := 0]. -2. forward pass -- vyhodnoť NN pro sample stem:[k] (t.j. stem:[y_j(\vec{w}, \vec{x_k})] pro všechny stem:[j \in Z]) -3. backward pass -- od konce pro každou vrstvu spočítej stem:[\frac{\partial E_k}{\partial y_j}] - a. pokud stem:[j \in Y], pak stem:[\frac{\partial E_k}{\partial y_j} = y_j - d_{kj}] - b. pokud stem:[j \in Z \setminus Y \cup X ], a stem:[j] je v stem:[l]-té vrstvě, pak - stem:[\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 stem:[w_{ji}] spočítej - stem:[\frac{\partial E_k}{\partial w_{ji}} := \frac{\partial E_k}{\partial y_j} \cdot \sigma'_j(\xi_j) \cdot y_i] -5. stem:[\varepsilon_{ji} := \varepsilon_{ji} + \frac{\partial E_k}{\partial w_{ji}}] -6. stem:[\varepsilon_{ji}] obsahuje výslednou hodnotu stem:[\frac{\partial E}{\partial w_{ji}}] - -==== - -//// - -== Hopfieldova síť - -Rekurentní neuronová síť s modelem "asociativní" paměti, která modeluje tu lidskou. Je to forma strojového učení bez učitele. <> "Asociativní" znamená, že proces vybavení si informace probíhá na základě její částečné znalosti spíš než hledání v paměti podle adresy. - -.A Hopfield net with four units by link:https://commons.wikimedia.org/w/index.php?curid=37811881[Zawersh] -image::./img/szp06_hopfield.svg[width=300] - --- -* Neurony jsou spojeny symetricky každý s každým. -* Neurony mají binární hodnoty (typicky -1 a 1) podle toho jestli je jejich input vyšší než threshold. -* V základním modelu nejsou biasy a neurony nejsou spojeny samy se sebou. -* Na rozdíl od vícevrstvých sítí, Hopfieldova síť neodpovídá okamžitě. Potřebuje čas k ústalení do stabilního stavu. -* Existují rozšíření, která mají reálné místo binárních hodnot, nebo si místo jednotlivých stavů pamatují celé sekvence stavů. --- - -Vyhodnocení / evaluation:: -+ --- - -1. Nastav stav neuronů na hodnoty podle vstupního vzoru. -2. Aktualizuj hodnoty neuronů tak dlouho, dokud se neustálí (neustanou změny). -+ -[stem] -++++ -s_i \gets \begin{cases} - +1 & \text{ pokud } \sum_j w_{ij} s_j > \theta_i \\ - -1 & \text{ jinak } -\end{cases} -++++ -+ -kde: -+ -* stem:[s_i] je stav neuronu stem:[i], -* stem:[w_{ij}] je váha spojení mezi neurony stem:[i] a stem:[j], -* stem:[\theta_i] je theshold neuronu stem:[j]. +``` -3. Výstup je stav neuronů. +**Algoritmus pro výpočet $\frac{\partial E}{\partial w_{ji}}$** -TIP: Aktualizace mohou probíhat buď asynchronně -- jen jeden neuron je aktualizován najednou -- nebo synchronně -- všechny neurony jsou aktualizovány najednou. +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ě -Energie:: -+ --- -Skalární hodnota popisující *globální* stav 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) -[stem] -++++ -E = -\frac{1}{2} \sum_{i,j} w_{ij} s_i s_j + \sum_i \theta_i s_i -++++ +**❗ IMPORTANT**\ +Pro konvoluci viz otázka [Zpracování rastrového obrazu](../zpracovani-rastroveho-obrazu/). -Opakovanou aktualizací síť dokonverguje do lokálního minima -- stabilního stavu -- který reprezentuje naučenou informaci. +**Typical CNN by [Aphex34](https://commons.wikimedia.org/w/index.php?curid=45679374)** -.Energy Landscape of a Hopfield Network by link:https://commons.wikimedia.org/w/index.php?curid=23796681[Mrazvan22] -image::./img/szp06_hopfield_energy.png[width=100%] +![width=100%](./img/szp06_cnn.png) --- +- **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** -Učení / training:: -+ --- -Je založeno na Hebbově zákoně asociace, který zjednodušeně říká, že _"Cells that fire together, wire together."_ Nicméně, nestačí, že jsou aktivovány společně, aktivace jedné buňky musí mít přímý vliv na aktivaci druhé buňky. + Algoritmus je potřeba trochu poupravit, aby podporovat konvoluční a pooling vrstvy. -Učení spočívá ve snižování energie síťe na základě vstupu, na kterém se síť učí. + 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: -Předpokládejme, že se síť učí stem:[n] binárních vzorů. Nechť stem:[\mu] je jeden z nich a stem:[\epsilon_i^\mu] je jeho stem:[i]-tý bit (dosadí se do neuronu stem:[i]). Pak váhy jsou po zpracování všech stem:[n] vzorů nastaveny na: <> + ```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 + ``` -[stem] -++++ -w_{ij} = \frac{1}{n} \sum_{\mu=1}^n \epsilon_i^\mu \epsilon_j^\mu -++++ --- + 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í: -== Konvoluční sítě + ```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} + ``` -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é. <> +## Rekurentní sítě -IMPORTANT: Pro konvoluci viz otázka link:../zpracovani-rastroveho-obrazu/[Zpracování rastrového obrazu]. +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) -.Typical CNN by link:https://commons.wikimedia.org/w/index.php?curid=45679374[Aphex34] -image::./img/szp06_cnn.png[width=100%] +- **Výhody** -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. + - 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. -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. +- **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). -Backpropagation:: -+ --- -Algoritmus je potřeba trochu poupravit, aby podporovat konvoluční a pooling vrstvy. +![width=100%](./img/szp06_rnn.png) -U konvolučních vrstev nestačí pro každou váhu stem:[w_{ji}] spočítat stem:[\frac{\partial E_k}{\partial w_{ji}}], protože pro každou váhu existuje víc než jeden výstup stem:[y_j]. Tedy: +- **Notace**\ + V čase $t$: -[stem] -++++ -\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 -++++ + - $\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''$. -kde stem:[\color{red}\bf \lbrack ji \rbrack] je množina spojení (dvojic neuronů) sdílících váhu stem:[w_{ji}]. +- **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) \} + ``` -Pokud stem:[j \in Z \setminus Y] a stem:[j^{\rightarrow}] je max-pooling, pak stem:[j^{\rightarrow} = \{ i \}] a platí: + **📌 NOTE**\ + Ano, to znamená, že $x_{lt1}$ je první prvek $t$-ho prvku v $l$-té vstupní sekvenci. -[stem] -++++ -\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ěť. <> - -[IMPORTANT] --- -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. --- - -[WARNING] --- -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). --- - -image::./img/szp06_rnn.png[width=100%] - -Notace:: -V čase stem:[t]: -+ -* stem:[\vec{x_t} = (x_{t, 1}, x_{t, 2}, ..., x_{t, M})] je vstupní vektor předávaný stem:[M] vstupním neuronům, -* stem:[\vec{h_t} = (h_{t, 1}, h_{t, 2}, ..., h_{t, H})] je vektor hodnot stem:[H] skrytých neuronů, -* stem:[\vec{y_t} = (y_{t, 1}, y_{t, 2}, ..., y_{y, N})] je výstupní vektor stem:[N] neuronů, -* stem:[U_{j, i}] je váha mezi inputem stem:[i] a hiddenem stem:[j], -* stem:[W_{j', i'}] je váha mezi hiddenem stem:[i'] a hiddenem stem:[j'], -* stem:[V_{j'', i''}] je váha mezi hiddenem stem:[i''] a outputem stem:[j'']. - -Aktivita:: -* Na počátku je výstup neuronky vynulován. Paměť je tedy prázdná. -* RNN zpracovává sekvenci vstupů stem:[\mathbb{x} = \vec{x_1}, \vec{x_2}, ..., \vec{x_T}] délky stem:[T]. -* Pro každý prvek stem:[\vec{x_t} \in \mathbb{x}], síť vyprodukuje výstup z hidden neuronů: -+ -[stem] -++++ -\vec{h_t} = \sigma(U \cdot \vec{x}_t + W \cdot \vec{h}_{t-1}) -++++ -* Pro výstup pak: -+ -[stem] -++++ -\vec{y_t} = \sigma(V \cdot \vec{h}_t) -++++ - -Trénink:: -+ --- -Trénovací set je množina dvojic -- (vstupní *sekvence*, výstupní *sekvence*). - -[stem] -++++ -\mathcal{T} = \{ (\bold{x}_1, \bold{d}_1), ..., (\bold{x}_p, \bold{d}_p) \} -++++ - -NOTE: Ano, to znamená, že stem:[x_{lt1}] je první prvek stem:[t]-ho prvku v stem:[l]-té vstupní sekvenci. - -Squared error samplu stem:[(\bold{x}, \bold{d})]: - -[stem] -++++ -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: - -[stem] -++++ -\begin{aligned} + Squared error samplu $(\bold{x}, \bold{d})$: -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'} \\ + ```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: -\end{aligned} -++++ + ```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'} \\ -Za předpokladu squared error je backpropagation: + \end{aligned} + ``` + + Za předpokladu squared error je backpropagation: -[stem] -++++ -\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 stem:[\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 stem:[\sigma] typicky stem:[\tanh]. V LSTM obsahuje jeden hidden neuron vlastně čtyři "podvrstvy", které mimo jiné umožňují část paměti zapomenout: -+ -image::./img/szp06_lstm.png[width=100%] - --- - -//// - -== Samo-organizující mapy / self-organizing maps (SOM) / Kohonenova síť - -Metoda unsupervised learningu určená primárně k vizualizaci vysoce dimenzionálních dat. Využívá se například pro shlukovou analýzu. - -.Kohonen Network - Background Information <> -image::./img/szp06_som.gif[width=400] - --- -* Má dvě vrstvy: jednu vrstvu vstupních neuronů a jednu vrstvu Kohenenových neuronů, kterou jsou výstupem sítě. -* Kohenenovy neurony nejsou spojeny densely, ale v 2D (čtvercové nebo hexagonální) mřížce. -* Každý vstupní neuron je spojen s každým Kohenenovým neuronem. -* Každý Kohenenův neuron má kladnou vazbu sám na sebe (posiluje se) a zápornou na okolní neurony (oslabuje je). -* Tak, pokud více neuronů reaguje na stejný podnět, je poznat, který z nich byl nejsilnější. -* Nemá fázi učení, ale pouze fázi vyhodnocení. Učí se za chodu. Snaží se charakterizovat shluky dat ve vstupu. --- - -Algoritmus:: -Běh SOM vypadá takto: <> -+ --- -1. Inicializuj váhy náhodně. -2. Vyber jeden vstupní vzor. -3. Najdi Kohenenův neuron jehož vektor vah je nejvíce podobný (např. Euklidovsky) vstupnímu vzoru -- _Best Matching Unit_ (BMU). -4. Spočítej okolí BMU. Počet sousedů se snižuje s časem. -5. Uprav váhy BMU a jeho okolí aby líp seděly k vstupnímu vzoru. -6. Opakuj 2. až 5. pro další vzor. --- -+ -Po skončení learningu obsahují vahy Kohenenových neuronů informaci o shlucích dat ve vstupu. - -//// - - -[bibliography] -== Zdroje - -* [[[pv021, 1]]] T. Brázdil: PV021 Neural Networks -* [[[ml, 2]]] https://en.wikipedia.org/wiki/Machine_learning[Wikipedia: Machine learning] -* [[[classification, 3]]] link:https://en.wikipedia.org/wiki/Statistical_classification[Wikipedia: Statistical classification] -* [[[regression, 4]]] link:https://en.wikipedia.org/wiki/Regression_analysis[Wikipedia: Regression analysis] -* [[[clustering, 5]]] link:https://en.wikipedia.org/wiki/Cluster_analysis[Wikipedia: Cluster analysis] -* [[[pattern-recognition, 6]]] link:https://en.wikipedia.org/wiki/Pattern_recognition[Wikipedia: Pattern recognition] -* [[[hopfield, 7]]] https://en.wikipedia.org/wiki/Hopfield_network[Wikipedia: Hopfield network] -* [[[hebb, 8]]] https://en.wikipedia.org/wiki/Hebbian_theory[Wikipedia: Hebbian theory] -* [[[cnn, 9]]] https://en.wikipedia.org/wiki/Convolutional_neural_network[Wikipedia: Convolutional neural network] -* [[[rnn, 10]]] https://en.wikipedia.org/wiki/Recurrent_neural_network[Wikipedia: Recurrent neural network] -* [[[som, 11]]] https://en.wikipedia.org/wiki/Self-organizing_map[Wikipedia: Self-organizing map] -* [[[som-tutorial, 12]]] https://sites.pitt.edu/~is2470pb/Spring05/FinalProjects/Group1a/tutorial/som.html[Self-Organizing Maps: Tutorial] -* [[[som-sdl, 13]]] http://www.lohninger.com/helpcsuite/kohonen_network_-_background_information.htm[SDL Component Suite: Kohonen Network] + ```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: + + ![width=100%](./img/szp06_lstm.png) + +## 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) diff --git a/szmgr/SZP07_grafy.md b/szmgr/SZP07_grafy.md index 98f5922..6a46913 100644 --- a/szmgr/SZP07_grafy.md +++ b/szmgr/SZP07_grafy.md @@ -1,104 +1,97 @@ -= Grafy a grafové algoritmy -:url: ./grafy-a-grafove-algoritmy/ -:page-group: szp -:page-order: SZP07 +--- +title: "Grafy a grafové algoritmy" +description: "TODO" +--- + +
📌 NOTE
-[NOTE] -==== 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_ -==== - -TIP: Tahle otázka má solidní překryv s bakalářskými otázkami link:../../szb/grafy/[Grafy] a link:../../szb/grafove-problemy/[Grafové problémy]. - -== Terminologie - -Graf:: -Dvojice stem:[G = (V, E)] kde: -+ --- -* stem:[V] je množina vrcholů; stem:[\lvert V \rvert = n], -* stem:[E] je množina hran; stem:[\lvert E \rvert = m], -* hrana stem:[e \in E] je dvojice vrcholů stem:[e = (u, v)]. --- - -Váha grafu:: -Váha grafu je součet vah hran grafu stem:[G]. -+ -[stem] -++++ -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 link:https://commons.wikimedia.org/w/index.php?curid=121779105[Watchduck] -image::./img/szp07_bipartite_graph.svg[width=400] - -(Silná) souvislost grafu / (strongly) connected graph:: -Graf stem:[G] je souvislý, pokud pro každé dva vrcholy stem:[u, v \in V(G)] existuje cesta z stem:[u] do stem:[v]. - -Slabá souvislost grafu / weakly connected graph:: -Graf stem:[G] je slabě souvislý, pokud je souvislý jeho podgraf stem:[G'] vzniklý odebráním orientace hran. -+ -[quote] -____ -Je souvislý alespoň, pokud zapomeneme, že hrany mají směr? -____ - -Silně souvislá komponenta / strongly connected component:: -Silně souvislá komponenta grafu stem:[G] je jeho maximální podgraf stem:[G'] takový, že je silně souvislý. Jinými slovy pro každé dva vrcholy stem:[u, v \in V(G')] existuje cesta z stem:[u] do stem:[v]. - -Planární / rovinný graf:: -Graf stem:[G] je planární, pokud se dá nakreslit do roviny tak, že se žádné dvě hrany nekříží. -+ -Platí v nich Eulerova formule: -+ -[stem] -++++ -\lvert V \rvert - \lvert E \rvert + \lvert F \rvert = 2 -++++ -+ -Kde stem:[\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 stem:[C \subseteq E(G)] taková, že po odebrání hran stem:[C] se graf stem:[G] rozpadne na více komponent -- stem:[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 stem:[v \in V] máme seznam (např. dynamic array nebo linked list) stem:[N(v)] jeho následníků. -+ -Zabírá stem:[\Theta(\lvert V \rvert + \lvert E \rvert)] paměti. - -Matice sousednosti / adjacency matrix:: -Máme matici velikosti stem:[\lvert V \rvert \times \lvert V \rvert] kde stem:[A_{u,v} = 1] pokud existuje hrana mezi stem:[u] a stem:[v], jinak stem:[A_{u,v} = 0]. -+ -Dá se pěkně použít k uložení vah. - -Matice incidence / incidence matrix:: -Máme matici velikosti stem:[\lvert V \rvert \times \lvert E \rvert] kde stem:[A_{u,e} = 1] pokud stem:[u] je vrcholem hrany stem:[e], jinak stem:[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) + +
+ +**💡 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)** + + ![width=400](./img/szp07_bipartite_graph.svg) + +- **(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 stem:[\mathcal{O}(\lvert V \rvert + \lvert E \rvert)]. +- Prohledávání po "vrstvách". +- Je implementovaný pomocí _fronty_ (queue / FIFO). +- Časová složitost je $\mathcal{O}(\lvert V \rvert + \lvert E \rvert)$. -[source, python] ----- +```python def dfs(graph: List[List[bool]], stamps: List[int], vertex: int) -> None: if stamps[vertex] == -1: stamps[vertex] = 0 @@ -107,19 +100,18 @@ def dfs(graph: List[List[bool]], stamps: List[int], vertex: int) -> None: 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) +### 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 stem:[\mathcal{O}(\lvert V \rvert + \lvert E \rvert)]. +- 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)$. -[source, python] ----- +```python def bfs(graph: List[List[bool]], stamps: List[int], vertex: int) -> None: stamp = 0 queue = deque() @@ -131,27 +123,24 @@ def bfs(graph: List[List[bool]], stamps: List[int], vertex: int) -> None: for i in range(0, len(graph)): if graph[current][i] and stamps[i] == -1: queue.append(i) ----- +``` -== Nejkratší vzdálenosti +## 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 stem:[(u, v)]:: -Zkrácení vzdálenosti k vrcholu stem:[v] průchodem přes vrchol stem:[u]. Musí platit stem:[u\text{.distance} + w(u, v) < v\text{.distance}]. Hrana stem:[(u, v)] je v takovém případě _napjatá_. +- **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 +### 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 stem:[\mathcal{O}(\lvert V \rvert \cdot \lvert E \rvert)]. --- +- 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)$. -[source, python] ----- +```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) @@ -176,23 +165,22 @@ def bellmanford(graph: List[List[Tuple[int, int]]], s: int) \ return (False, None, None) return (True, distance, parent) ----- +``` -=== Dijkstrův algoritmus +### 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. --- +- 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 stem:[\Theta(V)] insertů, stem:[\Theta(V)] hledání nejmenšího prvku, stem:[\Theta(E)] snížení priority. +**💡 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 stem:[\Theta(V^2)], jelikož hledání minima je lineární. +**📌 NOTE**\ +Implementace níže používá pole (resp. Pythoní `list`), tedy složitost je $\Theta(V^2)$, jelikož hledání minima je lineární. -[source, python] ----- +```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) @@ -210,439 +198,376 @@ def dijkstra(graph: List[List[Tuple[int, int]]], s: int) \ distance[v] = distance[u] + w parent[v] = u return (distance, parent) ----- +``` -V binární haldě by to bylo stem:[\Theta(V \log V + E \log V)] a ve Fibonacciho haldě stem:[\Theta(V \log V + E)]. +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 link:../umela-inteligence-v-pocitacovych-hrach/[Umělá inteligence v počítačových hrách]. --- - -== Kostry - -Spanning tree / kostra:: -Kostra grafu stem:[G = (V, E)] je podgraf stem:[T \sube G] takový, že stem:[V(T) = V(G)] je stem:[T] je strom. -+ -image::./img/szp07_spanning_tree.svg[width=400] - -Minimum spanning tree (MST) / minimální kostra:: -Je kostra stem:[M] grafu stem:[G] s nejmenší možnou váhou. Tedy pro každou kostru stem:[T] grafu stem:[G]: -+ -[stem] -++++ -w(M) \le w(T) -++++ - -Fundamental cycle:: -Fundamental cycle je cyklus stem:[C] v grafu stem:[G] takový, že odebráním libovolné hrany stem:[e \in C] získáme kostru. - -Fundamental cutset / řez:: -Fundamental cutset je množina hran stem:[D] v grafu stem:[G] taková, že přidáním libovolné hrany stem:[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čí stem:[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 stem:[v] a přidej ho do kostry stem:[S]. -2. Opakuj stem:[n-1] krát: - . Vyber hranu stem:[e] s nejmenší cenou, která má právě jeden vrchol v stem:[S]. - . Přidej druhý vrchol stem:[e] do stem:[S]. --- -+ -_Složitost_: použijeme binární haldu -+ --- -* Inicializace (stem:[\infty] jako cena hrany mezi prázdnou kostrou a každým vrcholem): stem:[\mathcal{O}( \lvert V \rvert )] -* Odstranění minima z binární haldy pro každý vrchol ve stem:[V]: stem:[\mathcal{O}( \lvert V \rvert \log \lvert V \rvert )] -* Procházení každé hrany z stem:[E] a snižování ceny: stem:[\mathcal{O}( \lvert E \rvert \log \lvert V \rvert )] -* Celková složitost: stem:[\mathcal{O}( \lvert E \rvert \log \lvert V \rvert )] -* S Fibonacciho haldou jde zlepšit na: stem:[\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: stem:[\mathcal{O}( \lvert V \rvert )] -* Seřazení hran: stem:[\mathcal{O}( \lvert E \rvert \log \lvert E \rvert )] -* Pro každou hranu provádíme dvakrát `find` (stem:[\mathcal{O}(\log \lvert V \rvert )]) a eventuálně `union` (stem:[\mathcal{O}(\log \lvert V \rvert )]): stem:[\mathcal{O}( \lvert E \rvert \log \lvert V \rvert )] -* Celková složitost: stem:[\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_: -.. 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: stem:[\lvert V \rvert]. -* V každé fázi se zmenší počet komponent na polovin. Tím pádem bude stem:[\log \lvert V \rvert] fází. -* Každá fáze zabere stem:[\mathcal{O}( \lvert E \rvert )] času, protože procházíme všechny hrany. -* Celková složitost: stem:[\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ů -[%header, cols="2,1,1"] -|=== -| Algoritmus -| Časová složitost -| Prostorová složitost - -| Jarník (Prim) s prioritní frontou -| stem:[\mathcal{O}(\lvert E \rvert \log \lvert V \rvert )] -| stem:[\mathcal{O}( \lvert V \rvert )] - -| Jarník (Prim) s Fibonacciho haldou -| stem:[\mathcal{O}(\lvert E \rvert + \lvert V \rvert \log \lvert V \rvert )] -| stem:[\mathcal{O}( \lvert V \rvert )] - -| Kruskal -| stem:[\mathcal{O}(\lvert E \rvert \log \lvert V \rvert )] -| stem:[\mathcal{O}( \lvert V \rvert )] - -| Borůvka -| stem:[\mathcal{O}(\lvert E \rvert \log \lvert V \rvert )] -| stem:[\mathcal{O}( \lvert V \rvert )] - - -|=== - -== Toky v sítích - -Síť toků / flow network:: -Je čtveřice stem:[(G, s, t, c)], kde: -+ --- -* stem:[G = (V, E)] je orientovaný graf, -* stem:[s \in V] je zdroj / source, -* stem:[t \in V] je cíl / stok / sink; stem:[s \neq t], -* stem:[c: E \rightarrow \mathbb{R}^+] je funkce udávající kapacitu hran. --- - -Network flow / tok:: -Je funkce stem:[f: E \rightarrow \mathbb{R}^+], která splňuje: -+ --- -* podmínku kapacity: stem:[(\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: stem:[(\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 stem:[f]:: -+ -[stem] -++++ -\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 stem:[f]. Umožnuje algoritmům změnit přechozí rozhodnutí a získat využitou kapacitu zpět. -+ -Je to pětice stem:[G_f = (V, E_f, s, t, c_f)], kde -+ -* stem:[E_f = \{ e \in E : f(e) < c(e) \} \cup \{ e^R : f(e) > 0 \}], -* pokud stem:[e = (u, v) \in E], stem:[e^R = (v, u)], -* stem:[ +- 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. + + ![width=400](./img/szp07_spanning_tree.svg) + +- **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 + c(e) - f(e) & \text{ pokud } e \in E \\ + f(e) & \text{ pokud } e^R \in E \end{cases} -] - -Augmenting path stem:[P]:: -Jednoduchá stem:[s \rightsquigarrow t] cesta v residuální síti stem:[G_f]. -+ -NOTE: T.j. cesta která může jít i proti směru toku stem:[f]. -+ -_Bottleneck kapacita_ je nejmenší kapacita hran v augmenting path stem:[P]. -+ -To krásné na augmenting cestách je, že pro flow stem:[f] a augmenting path stem:[P] v grafu stem:[G_f], existuje tok stem:[f'] takový, že stem:[\text{val}(f') = \text{val}(f) + \text{bottleneck}(G_f, P)]. Nový tok stem:[f'] lze získat takto: -+ -[source,subs=normal] ----- -*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. stem:[f(e) = 0] pro každou stem:[e \in E]. -2. Najdi stem:[s \rightsquigarrow t] cestu stem:[P] v reziduální síti stem:[G_f]. -3. Augmentuj tok podél stem:[P]. -4. Opakuj dokud se nezasekneš. --- -+ -[source,subs=normal] ----- -*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 stem:[f] taková, že -+ -* platí _kapacitní podmínka_: stem:[(\forall e \in E)(0 \le f(e) \le c(e))], -* platí _relaxováné zachování toku_: stem:[ + ] + +- **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 stem:[v \in V - \{ s, t \}], do kterého více přitéká než odtéká. -+ -[stem] -++++ -\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. -+ -[stem] -++++ -e_f(v) = \sum_{e \text{ do } v} f(e) - \sum_{e \text{ ven z } v} f(e) -++++ - -Height function:: -Funkce stem:[h : V \to \N_0]. Řekneme, že stem:[h] je _kompatibilní s preflow stem:[f]_, právě když -+ -* _source_: stem:[h(s) = |V| = n], -* _sink_: stem:[h(t) = 0], -* _height difference_: stem:[(\forall (v, w) \in E_{G_f})(h(v) \le h(w) + 1)]. -+ -NOTE: Pokud mezi dvěma vrcholy stem:[(v, w)] v reziduální síti vede hrana, pak je stem:[v] nejvýše o jednu úroveň výš než stem:[w]. - -Push operace:: -Pro (reziduálně-grafovou) hranu stem:[(v, w)] se pokusí přesunout excess flow z stem:[v] do stem:[w], aniž by porušil (reziduální) kapacitu stem:[(v, w)]. -+ -[source, subs=normal] ----- -// 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 stem:[h(v)] natolik, aby neporušil kompatibilitu stem:[h] s stem:[f]. -+ -[source, subs=normal] ----- -// 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. -+ -[source, subs=normal] ----- -*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 stem:[2^n] Relabelů. -* stem:[2nm] saturujících Push. -* stem:[4n^2m] nesaturujících Push. -* Relabel i Push jsou v stem:[\mathcal{O}(1)]. -* Celkem: stem:[O(n^2m)]. --- + ]. + +- **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 -[%header,cols="1,1"] -|=== -| Ford-Fulkerson -| Push-Relabel (Goldberg) - -| global character -| local character - -| update flow along an augmenting path -| update flow on edges - -| flow conservation -| preflow -|=== - -== Maximální párování v bipartitních grafech - -Párování / matching:: -Množina stem:[M \sube E] taková, že žádné dvě hrany v stem:[M] nemají společný vrchol. <> -+ -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 link:https://commons.wikimedia.org/w/index.php?curid=45306558[RRPPGG] -image::./img/szp07_matching.jpg[width=400] - -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: <> -+ --- -1. Mejmě bipartitní graf stem:[G=(X+Y,E)]. -+ -image::./img/szp07_mcm_01.png[width=150] -2. Přidej zdroj stem:[s] a hranu stem:[(s, v)] pro každý vrchol stem:[v] z stem:[X]. -3. Přidej stok stem:[t] a ranu stem:[(v, t)] pro každý vrchol stem:[v] z stem:[Y]. -+ -image::./img/szp07_mcm_02.png[width=300] -4. Každé hraně dej kapacitu 1. -5. Spusť algoritmus Ford-Fulkerson. -+ -image::./img/szp07_mcm_03.png[width=300] --- - -[bibliography] -== Zdroje - -* [[[ib000,1]]] link:https://is.muni.cz/auth/el/fi/podzim2022/IB000/um/[IB000 Matematické základy informatiky (podzim 2022)] -* [[[ib002,2]]] link:https://is.muni.cz/auth/el/fi/jaro2020/IB002/um/[IB002 Algoritmy a datové struktury (jaro 2020)] -* [[[ib003,3]]] link:https://is.muni.cz/auth/el/fi/jaro2021/IV003/um/[IV003 Algoritmy a datové struktury II (jaro 2021)] -* [[[matching,4]]] link:https://cs.wikipedia.org/wiki/P%C3%A1rov%C3%A1n%C3%AD_grafu[Wikipedia: Párování grafu] -* [[[mcm, 5]]] link:https://en.wikipedia.org/wiki/Maximum_cardinality_matching[Wikipedia: Maximum cardinality matching] - - -== Další zdroje - -* link:https://visualgo.net/en/maxflow[Vizualizace max-flow algoritmů] -* link:http://www.adrian-haarbach.de/idp-graph-algorithms/implementation/maxflow-push-relabel/index_en.html[Vizualizace push-relabel] +**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)** + + ![width=400](./img/szp07_matching.jpg) + +- **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)$. + + ![width=150](./img/szp07_mcm_01.png) + + 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$. + + ![width=300](./img/szp07_mcm_02.png) + + 4. Každé hraně dej kapacitu 1. + 5. Spusť algoritmus Ford-Fulkerson. + + ![width=300](./img/szp07_mcm_03.png) + +## 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) diff --git a/szmgr/SZP08_modelovani_a_projekce.md b/szmgr/SZP08_modelovani_a_projekce.md index efb9dba..411716b 100644 --- a/szmgr/SZP08_modelovani_a_projekce.md +++ b/szmgr/SZP08_modelovani_a_projekce.md @@ -1,5 +1,5 @@ --- -title: 8. Modelování a projekce +title: Modelování a projekce description: A guide in my new Starlight docs site. --- diff --git a/szmgr/SZP09_zpracovani_obrazu.md b/szmgr/SZP09_zpracovani_obrazu.md index 259928a..50a1771 100644 --- a/szmgr/SZP09_zpracovani_obrazu.md +++ b/szmgr/SZP09_zpracovani_obrazu.md @@ -1,756 +1,658 @@ -= Zpracování rastrového obrazu -:url: ./zpracovani-rastroveho-obrazu/ -:page-group: szp -:page-order: SZP09 +--- +title: "Zpracování rastrového obrazu" +description: "TODO" +--- + +
📌 NOTE
-[NOTE] -==== 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_ -==== - -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_. <> -+ -[quote] -____ -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: <> -+ --- -* 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í:: + +
+ +- **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í + - Bodové + - Lokální + - Globální - Geometrické -== Bodové transformace +## Bodové transformace -Transformace hodnot pixelů *nezávisle* na jejich okolí. Nemění velikost obrazu. +Transformace hodnot pixelů **nezávisle** na jejich okolí. Nemění velikost obrazu. -=== Homogenní +### Homogenní -Bodové transformace, které *nezávisí* na pozici pixelu v obraze. Je definována pomocí _převodní funkce_ stem:[I'(u, v) \leftarrow f(I(u,v))]. Patří sem třeba: +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í. --- +- ú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 stem:[f(a) = ka + q]. +#### Lineární transformace -- Identita: stem:[k = 1, q = 0] -- Inverze intenzit (negativ): stem:[k = -1, q = a_{max}] -- Zvýšení jasu: stem:[k = 1, q > 0] -- Snížení jasu: stem:[k = 1, q < 0] -- Zvýšení kontrastu: stem:[k > 1, q = 0] -- Snížení kontrastu: stem:[0 < k < 1, q = 0] +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 -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: -+ -[stem] -++++ -f(x) = 255 - x -++++ - -Lineární roztažení:: -Přemapování rozsahu intenzit stem:[(a_\text{low}, a_\text{high})] na rozsah stem:[(a_\text{min}, a_\text{max})] pomocí lineární interpolace. Často ke zvýraznění kontrastu. -+ -[stem] -++++ -f(x) = \frac{a_\text{max} - a_\text{min}}{a_\text{high}-a_\text{low}} \cdot (x - a_\text{min}) + a_\text{min} -++++ -+ -kde stem:[a_\text{low}] je nejnižší hodnota a stem:[a_\text{high}] nejvyšší hodnota v obraze. Obvykle stem:[a_\text{min} = 0] a stem:[a_\text{max} = 255]. -+ -Alternativně lze použít *percentilové roztažení*, které převede stem:[p] procent nejnižších a nejvyšších hodnot na stem:[a_\text{min}] a stem:[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 stem:[(0, 1)]. -2. Každá hodnota stem:[x] je transformována typicky pomocí stem:[x^\gamma]. -3. Výsledný obraz je přeškálován na původní rozsah. --- -+ -image::./img/szp09_gamma.png[width=400] - -Kvantizace:: -Nelineární bodová transformace, která snižuje bitovou hloubku obrazu. Výsledkem je obraz s menším počtem barev. -+ -[quote] -____ -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. -+ -[stem] -++++ -f(x) = \begin{cases} 0 & \text{pokud } x < T \\ 1 & \text{pokud } x \geq T \end{cases} -++++ -+ -kde stem:[T] je práh. Pokud je stem:[T] konstanta, pak se jedná o _globální prahování_. -+ -[IMPORTANT] --- -Prahování se pořádně věnuje otázka link:../analyza-rastroveho-obrazu/[Analýza rastrového 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_ stem:[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 +- **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. + + ![width=400](./img/szp09_gamma.png) + +- **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 stem:[H] v indexu stem:[i] odpovídá počtu pixelů v obraze s intenzitou stem:[i]. -* Šedotónní obraz má jeden histogram. RGB obraz má tři. --- - -Kumulativní histogram:: -Kumulativní histogram stem:[\mathbb{H}] bbsahuje množství pixelů s intenzitou *menší nebo rovnou* než stem:[i]. Ve statické terminologii je to aproximace distribuční funkce. -+ -[stem] -++++ -\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í. <> -+ -Typicky k tomu využíváme funkci stem:[f(x) = \mathbb{H}[x\] \cdot \frac{a_{\text{max}}}{w \cdot h}], kde stem:[\text{cumhist}] je kumulativní histogram pro barvu v bodě x, stem:[a_{\text{max}}] je maximální intenzita a stem:[w \cdot h] je velikost obrazu. -+ -==== - -.Před vyrovnáním histogramu --- -image:./img/szp09_histogram_eq_before_01.jpg[width=49%] -image:./img/szp09_histogram_eq_before_02.svg[width=49%] --- - -.Po vyrovnání histogramu --- -image:./img/szp09_histogram_eq_after_01.jpg[width=49%] -image:./img/szp09_histogram_eq_after_02.svg[width=49%] --- - -NOTE: Původní fotku vyfotil link:https://commons.wikimedia.org/w/index.php?curid=855363[Phillip] link:https://commons.wikimedia.org/w/index.php?curid=855383[Capper]. -==== - -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: <> <> -+ --- -* 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. <> - -Š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; stem:[g = f + n], kde stem:[f] je originální funkce signálu a stem:[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 stem:[f] a stem:[g] a produkuje třetí funkci stem:[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: <> -+ -[stem] -++++ -(f * g)(t) = \int_{-\infty}^{\infty} \cdot f(\tau) g(t - \tau) d\tau -++++ -+ -Pokud jsou funkce stem:[f] a stem:[g] diskrétní a stem:[g] navíc je doména (množina povolených vstupů) stem:[g] konečná a je třeba stem:[\{ -M, -M+1, ..., M-1, M \}], pak se používá _diskrétní konvoluce_: -+ -[stem] -++++ -(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: -+ -[stem] -++++ -(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 stem:[h] je _kernel / konvoluční jádro_ dáno jako matice velikosti stem:[(2k + 1) \times (2k + 1)]. -+ -WARNING: Všimni si, že kvůli stem:[f \lbrack x - m, x - n \rbrack] se jádro při aplikaci na obraz překlápí. Kdyby to bylo stem:[f \lbrack x + m, x + n \rbrack], tak jde o *korelaci*, ne o konvoluci. -+ -Konvoluce má složitost stem:[O(MNKL)], kde stem:[M \times N] je velikost obrazu a stem:[K \times L] je velikost jádra. Pro velká jádra se složitost blíží stem:[O(M^2 N^2)]. -+ -Konvoluce je *komutativní*, *asociativní*, *xy separabilní* (lze ji rozdělit na dvě jednorozměrné konvoluce, pokud platí, že stem:[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í. --- -+ -image::./img/szp09_okraje.png[width=500] - -=== Lineární - -Lineární filtr:: -Je takový filtr stem:[\Theta: \mathbb{I}^{w \times h} \to \mathbb{I}^{w \times h}], kde stem:[\mathbb{I}] je množina povolených hodnot pixelů v obraze a stem:[\mathbb{I}^{w \times h}] je množina všech obrazů s šířkou stem:[w] a výškou stem:[h]. Musí splňovat _podmínky linearity_: -+ -[stem] -++++ -\begin{aligned} +- 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. -a \cdot \Theta(I) &= \Theta(a \cdot I) \\ -\Theta(I_1 + I_2) &= \Theta(I_1) + \Theta(I_2) +- **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. -\end{aligned} -++++ -+ -kde stem:[I, I_1, I_2] jsou obrazy a stem:[a] je skalární hodnota. - -Posunutí:: -Jednoduchý lineární filtr, který posune obraz o nějaký vektor. -+ -[stem] -++++ -\begin{bmatrix} -0 & 0 & 0 \\ -0 & 0 & 0 \\ -0 & 0 & 1 -\end{bmatrix} -++++ - -Box filtr / box blur:: -Rozmazání pomocí okolních pixelů. -+ -[stem] -++++ -\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 stem:[\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í + ```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** + + ![width=49%](./img/szp09_histogram_eq_before_01.jpg) + ![width=49%](./img/szp09_histogram_eq_before_02.svg) + + **Po vyrovnání histogramu** + + ![width=49%](./img/szp09_histogram_eq_after_01.jpg) + ![width=49%](./img/szp09_histogram_eq_after_02.svg) + + **📌 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í. + + ![width=500](./img/szp09_okraje.png) + +### 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 +## 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 link:../numericke-metody/[Numerické 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: -+ -[stem] -++++ -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: -+ -[stem] -++++ -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: -+ -[stem] -++++ -\lvert \nabla f(m, n) \rvert \approx \sqrt{(P_x * I)^2 + (P_y * I)^2} -++++ -+ -kde stem:[I] je vstupní obraz. -+ -[NOTE] -==== -Všimni si podobnosti s Sobelovým operátorem. Jen místo Gaussovského rozmazání používá box filtr. -==== - -Sobelův operátor:: -Aproximuje velikost gradientu pomocí *centrálních* konečných diferencí. Skládá se ze dvou konvolucí s jádry: -+ -[stem] -++++ -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: -+ -[stem] -++++ -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} -++++ -+ -[NOTE] --- -Všimni si, že jeden kernel je Gaussovo rozmázání a druhý jsou centrální diference. --- -+ -Aproximace je pak dána jako: -+ -[stem] -++++ -\lvert \nabla f(m, n) \rvert \approx \sqrt{(G_x * I)^2 + (G_y * I)^2} -++++ -+ -kde stem:[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°. -+ -[stem] -++++ -\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: -+ -[stem] -++++ -\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. <> <> -+ --- -* 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 +- 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. + +
📌 NOTE
+ + Všimni si podobnosti s Sobelovým operátorem. Jen místo Gaussovského rozmazání používá box filtr. +
+ +- **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: <> -+ -[stem] -++++ -\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 stem:[\Delta] hledá hrany pomocí divergence gradientu. -+ --- -* Produkuje spojité hrany. -* Uzavřené kontury. -* Invariantní k otáčení o násobky stem:[\pi/2]. -* Ale je velmi citlivý na šum. -* Nedetekuje orientaci hrany. --- -+ -[stem] -++++ -\Delta f = \nabla^2 f = \nabla \cdot \nabla f = f_{xx} + f_{yy} -++++ -+ -kde stem:[f] je vstupní obraz. -+ -Jeho diskrétní aproximace v maticové podobě potom vypadá jako: -+ -[stem] -++++ - -\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: -+ -[stem] -++++ -\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_. -+ -image::./img/szp09_mexican_hat.png[width=300] - -// Difference of Gaussian (DoG):: -// Aproximuje LoG pomocí rozdílu dvou Gaussovských rozmazání. <> -// + -// [stem] -// ++++ -// \Gamma_{\sigma_1, \sigma_2} = I * G_{\sigma_1} - I * G_{\sigma_2} -// ++++ -// + -// kde stem:[I] je vstupní obraz a stem:[G_{\sigma_1}] a stem:[G_{\sigma_2}] jsou Gaussovská jádra s různými rozptylem. Platí stem:[\sigma_1 < \sigma_2]. - -== Integrální transformace - -Transformace, která mapuje funkci stem:[f: A \to B] z jejího původního funkčního prostoru stem:[A \to B] do nějakého jiného funkčního prostoru stem:[A' \to B']. Používá se, protože s některými vlastnostmi funkcí je snazší pracovat v jiném prostoru. <> +- **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_. + + ![width=300](./img/szp09_mexican_hat.png) + +## 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 - -[quote, Nika Kunzová] -____ -Fourierka je ako more. Je to hromada vlniek. -____ - -[TIP] -==== -3Blue1Brown má skvělý link:https://www.youtube.com/watch?v=spUNpyF58BY[video o Fourierově transformaci], ze kterého to pochopíš! _(a evidentně je tak dobrý, že mi Copilot sám nabídl správný link...)_ -==== - -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ě. <> - --- -* 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. -+ -[stem] -++++ -e^{i \theta} = \cos \theta + i \sin \theta -++++ -+ -Lidskými slovy říká (viz 3b1b), že komplexní číslo stem:[e^{i t}] popisuje pohyb po jednotkové kružnici v komplexní rovině proti směru hodinových ručiček. Jedna otáčka je stem:[t = 2 \pi] radianů. - -1D Fourierova transformace:: -Eulerovu formuli využijeme při popisu Fourierovy transformace: -+ -[stem] -++++ -\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): <> -+ -[stem] -++++ -\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): -+ -[stem] -++++ -\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): <> -+ -[stem] -++++ -\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): -+ -[stem] -++++ -\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). <> - -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é. <> -+ -[stem] -++++ -\mathcal{F} \{ f * g \} = \mathcal{F} \{ f \} \cdot \mathcal{F} \{ g \} -++++ -+ -kde stem:[\mathcal{F}] je Fourierova transformace. - - -== Sampling / vzorkování - -Samplování je převod spojitého signálu na diskrétní. <> - -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. <> - -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. <> -+ --- -* 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 link:../renderovani-s-vyuzitim-gpu/[Renderování s využitím 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. <> - -Rekonstrukční filtr:: -Filtr pro rekonstrukci signálu. -+ --- -* _box_: nejbližší soused, -* _tent_: lineární interpolace, -* sinc, -* Lanczos, -* Gaussian. --- - -== Geometrické transformace - -Geometrická transformace stem:[T] je bijekce mezi body dvou obrazů stem:[I] a stem:[J]. Díky tomu, že je to bijekce, k ní musí vždy existovat inverze. <> - -[stem] -++++ +- Fourierova transformace, +- vlnková transformace, +- Houghova transformace, +- Radonova transformace. + +## Fourierova transformace + +> Fourierka je ako more. Je to hromada vlniek. +> +> — Nika Kunzová + +
💡 TIP
+ +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...)_ + +
+ +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 stem:[I] a hledáme jejich umístění v stem:[J] (_metoda "Kam s ním?"_). - -Zpětné mapování / backward mapping:: -Pro každý pixel stem:[J] počítáme jeho původní umístění v stem:[I] (_metoda "Kde je?"_). - - -== Vlnková transformace / wavelet transform - -[TIP] -==== -Opět výborné video, bohužel ne od 3b1b, ale obdobně kvalitně zpracované: link:https://www.youtube.com/watch?v=jnxqHcObNK4[Wavelets: a mathematical microscope]. -==== - -Vlnka / wavelet:: -Funkce stem:[\psi], která je omezená v čase. Je to "brief oscillation". <> -+ -image::./img/szp09_wavelet.svg[width=300] -+ --- -* *Má konečnou energii*: -+ -[stem] -++++ -\int_{-\infty}^{\infty} |\psi(t)|^2 dt < \infty -++++ - -* Splňuje podmínku přípustnosti: -+ -[stem] -++++ -C_\psi = \int_{0}^{\infty} { {|\hat{\psi}(\omega)|^{2}}\over{\omega} } \, \mathrm{d}\omega < \infty -++++ -+ -kde stem:[\hat{\psi}] je Fourierova transformace stem:[\psi]. Tato podmínka zajišťuje invertibilitu vlnkové transformace. - -* Z podmínky přípustnosti plyne, že vlnka *musí mít nulovou střední hodnotu*: -+ -[stem] -++++ -\int_{-\infty}^{\infty} \psi(t) \, \mathrm{d}t = 0 -++++ --- +- 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 + +
💡 TIP
+ +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). + +
+ +- **Vlnka / wavelet**\ + Funkce $\psi$, která je omezená v čase. Je to "brief oscillation". [wavelet](#wavelet) + + ![width=300](./img/szp09_wavelet.svg) + + - **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é. <> +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. --- +- 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 stem:[\psi] (je spousta různých, ale nejznámnější je Morletova vlnka stem:[\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}}] -+ -image::./img/szp09_wavelet_steps1.png[width=500] -2. Tuto vlnku můžeme posouvat a škálovat pomocí parametrů stem:[a] a stem:[b] - stem:[\psi_{a,b} = \psi \frac{t-b}{a}]. -+ -image::./img/szp09_wavelet_steps2.png[width=500] -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 stem:[\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 stem:[\langle f, \psi_{a,b} \rangle]. -+ -image::./img/szp09_wavelet_steps3.png[width=500] -4. Pokud toto uděláme pro každý bod časové (stem:[a]) a frekvenční (stem:[b]) domény, dostaneme výsledný obraz vlnkové transformace. -+ -image::./img/szp09_wavelet_steps4.png[width=500] +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}}$ + + ![width=500](./img/szp09_wavelet_steps1.png) + +2. Tuto vlnku můžeme posouvat a škálovat pomocí parametrů $a$ a $b$ - $\psi_{a,b} = \psi \frac{t-b}{a}$. + + ![width=500](./img/szp09_wavelet_steps2.png) + +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$. + + ![width=500](./img/szp09_wavelet_steps3.png) + +4. Pokud toto uděláme pro každý bod časové ($a$) a frekvenční ($b$) domény, dostaneme výsledný obraz vlnkové transformace. + + ![width=500](./img/szp09_wavelet_steps4.png) + 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. -+ -image::./img/szp09_wavelet_steps5.png[width=500] + ![width=500](./img/szp09_wavelet_steps5.png) -Ve výsledku je to fakt jen *dot product funkce stem:[f] s upravenou vlnkou stem:[\psi_{a,b}]*! +Ve výsledku je to fakt jen **dot product funkce $f$ s upravenou vlnkou $\psi_{a,b}$**! -[stem] -++++ +```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\\ @@ -758,85 +660,76 @@ Ve výsledku je to fakt jen *dot product funkce stem:[f] s upravenou vlnkou stem &=f*\psi _{a}^{\ast }(b)\\&={\frac {1}{2\pi }}\langle {\hat {f}},{\hat {\psi }}_{a,b}\rangle , \end{aligned} -++++ +``` kde: --- -* stem:[\psi] je mateřská vlnka, -* stem:[\psi_{a,b}] je škálovaná a posunutá mateřská vlnka, -* stem:[a] je škálovací parametr, -* stem:[b] je posunutí. -* stem:[\hat {f}] je Fourierova transformace funkce stem:[f], -* stem:[\hat {\psi }] je Fourierova transformace vlnky stem:[\psi], -* stem:[\langle \cdot ,\cdot \rangle ] je skalární součin, -* stem:[\ast ] u stem:[\psi^\ast] je komplexně sdružená funkce, -* stem:[*] je spojitá konvoluce, -* stem:[\psi _{a}(t)={\frac {1}{\sqrt {a}}}\psi \left({{-t} \over {a}}\right)] je spojitý filtr, který odpovídá vlnce stem:[\psi], pro dané měřítko stem:[a]. --- +- $\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. --- +- 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. <> -==== +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 + +
💡 TIP
+ +Super [minutu a půl dlouhé video, co ti řekne úplně všechno](https://www.youtube.com/watch?v=X1DxCPS1iwA). + +
+ +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$. -== Houghova transformace + 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. -[TIP] -==== -Super link:https://www.youtube.com/watch?v=X1DxCPS1iwA[minutu a půl dlouhé video, co ti řekne úplně všechno]. -==== + ![width=600](./img/szp09_hough_space.png) -Integrální transformace, která identifikuje přímky v obraze. V rozšířené podobě hledá libovolné tvary zadané parametricky. <> + 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. --- -* 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. --- + ![width=600](./img/szp09_hough_transform.png) -Houghův prostor:: -Prostor je definován jednoduchou rovnicí stem:[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. -+ -image::./img/szp09_hough_space.png[width=600] -+ -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. -+ -image::./img/szp09_hough_transform.png[width=600] +## Radonova transformace +
💡 TIP
-== Radonova transformace +Jako je již tradicí, mám pro vás [video](https://www.youtube.com/watch?v=f0sxjhGHRPo)... -[TIP] -==== -Jako je již tradicí, mám pro vás link:https://www.youtube.com/watch?v=f0sxjhGHRPo[video]... -==== +
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"). <> +Užitečná je především inverzní Radonova transformace, která se používá v tomografii ("CTčko"). [radon](#radon) -image::./img/szp09_radon.png[width=100%] +![width=100%](./img/szp09_radon.png) -Mějme 3D objekt, který chceme "proskenovat" z různých úhlů stem:[\phi]. Pro každý úhel chceme získat 1D projekci objektu stem:[p(s, \phi)]. Tato projekce je dána integrálem funkce stem:[f(x, y)] přes přímku. +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 stem:[\phi] a potom provedeme jednoduchou projekci všech bodů na této přímce. +Uvažme, že nejprve celý prostor otočíme o úhel $\phi$ a potom provedeme jednoduchou projekci všech bodů na této přímce. -image::./img/szp09_radon_space.png[width=500] +![width=500](./img/szp09_radon_space.png) -[stem] -++++ +```math \begin{pmatrix} x \\ y @@ -857,73 +750,65 @@ u x = s \cos \phi - u \sin \phi \\ y = s \sin \phi + u \cos \phi \end{aligned} -++++ +``` -[stem] -++++ +```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: -image::./img/szp09_sinogram.png[width=300] +![width=300](./img/szp09_sinogram.png) 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 -[%header, cols=2] -|=== -| 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ů -|=== - - -[bibliography] -== Zdroje - -* [[[pb130,1]]] link:https://is.muni.cz/auth/el/fi/podzim2022/PB130/[PB130 Úvod do digitálního zpracování obrazu (podzim 2022)] -* [[[pv131,2]]] link:https://is.muni.cz/auth/el/fi/jaro2023/PV131/[PV131 Digitální zpracování obrazu (jaro 2023)] -* [[[raster,3]]] link:https://en.wikipedia.org/wiki/Raster_graphics[Wikipedia: Raster graphics] -* [[[dip,4]]] link:https://en.wikipedia.org/wiki/Digital_image_processing[Wikipedia: Digital image processing] -* [[[filter,5]]] link:https://en.wikipedia.org/wiki/Filter_(signal_processing)[Wikipedia: Filter (signal processing)] -* [[[convolution,6]]] link:https://en.wikipedia.org/wiki/Convolution[Wikipedia: Convolution] -* [[[edge-detection,7]]] link:https://en.wikipedia.org/wiki/Edge_detection[Wikipedia: Edge detection] -* [[[fourier, 8]]] link:https://en.wikipedia.org/wiki/Fourier_transform[Wikipedia: Fourier transform] -* [[[fft, 9]]] link:https://en.wikipedia.org/wiki/Fast_Fourier_transform[Wikipedia: Fast Fourier transform] -* [[[sampling, 10]]] link:https://en.wikipedia.org/wiki/Sampling_(signal_processing)[Wikipedia: Sampling (signal processing)] -* [[[scaling, 11]]] link:https://en.wikipedia.org/wiki/Image_scaling[Wikipedia: Image scaling] -* [[[n-s, 12]]] link:https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem[Wikipedia: Nyquist–Shannon sampling theorem] -* [[[geometric-transform,13]]] link:https://en.wikipedia.org/wiki/Geometric_transformation[Wikipedia: Geometric transformation] -* [[[reconstruction, 14]]] link:https://en.wikipedia.org/wiki/Signal_reconstruction[Wikipedia: Signal reconstruction] -* [[[wavelet,15]]] link:https://en.wikipedia.org/wiki/Wavelet_transform[Wikipedia: Wavelet transform] -* [[[hough, 16]]] link:https://en.wikipedia.org/wiki/Hough_transform[Wikipedia: Hough transform] -* [[[radon, 17]]] link:https://en.wikipedia.org/wiki/Radon_transform[Wikipedia: Radon transform] -* [[[integral-transform, 18]]] link:https://en.wikipedia.org/wiki/Integral_transform[Wikipedia: Integral transform] -* [[[histogram, 19]]] link:https://en.wikipedia.org/wiki/Histogram[Wikipedia: Histogram] -* [[[histogram-eq, 20]]] link:https://en.wikipedia.org/wiki/Histogram_equalization[Wikipedia: Histogram equalization] -* [[[histogram-bbc, 21]]] link:https://www.bbc.co.uk/bitesize/guides/zspfcwx/revision/3[Bitesize: Histograms - Higher only] -* [[[sobel, 22]]] link:https://en.wikipedia.org/wiki/Sobel_operator[Wikipedia: Sobel operator] -* [[[canny, 23]]] link:https://en.wikipedia.org/wiki/Canny_edge_detector[Wikipedia: Canny edge detector] -* [[[canny-tds, 24]]] link:https://towardsdatascience.com/canny-edge-detection-step-by-step-in-python-computer-vision-b49c3a2d8123[Canny Edge Detection Step by Step in Python — Computer Vision] -* [[[divergence, 25]]] link:https://cs.wikipedia.org/wiki/Divergence_(oper%C3%A1tor)[Wikipedia: Divergence (operátor)] -* [[[dog, 26]]] link:https://en.wikipedia.org/wiki/Difference_of_Gaussians[Wikipedia: Difference of Gaussians] -* [[[others, 27]]] https://hackmd.io/@fi-muni-viz-2022/SywCznl2t -* [[[waveleet, 28]]] link:https://cs.wikipedia.org/wiki/Vlnka[Wikipedia: Vlnka] +**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)]() +- [[[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)]() +- [[[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)]() +- [[[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) diff --git a/szmgr/SZP10_analyza_obrazu.md b/szmgr/SZP10_analyza_obrazu.md index 89fd55e..8fd9f39 100644 --- a/szmgr/SZP10_analyza_obrazu.md +++ b/szmgr/SZP10_analyza_obrazu.md @@ -1,643 +1,542 @@ -= Analýza rastrového obrazu -:url: ./analyza-rastroveho-obrazu/ -:page-group: szp -:page-order: SZP10 +--- +title: "Analýza rastrového obrazu" +description: "TODO" +--- + +
📌 NOTE
-[NOTE] -==== 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_ -==== - -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í. +- **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. -5. Porozumění -** Pochopení smyslu objektů v obraze. +## Segmentace obrazu -== 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. -Rozdělení definičního oboru obrazu stem:[\Omega] na _segmenty_ stem:[\Omega = \Omega_0 \cup \Omega_1 \cup \dots \cup \Omega_{n-1}] (oblasti, regiony, spojené množiny) podle nějaké společné vlastnosti. - -[quote, Haralick a Shapiro] -____ -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. -____ +> 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) +- **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) +- **Algoritmus záplava** (watershed) - Hierarchické segmentace - Metody pracující s modelem tvaru (ASM, AAM) -- *Neuronové sítě* (zejména konvoluční) +- **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í. +- **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ě -=== 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ě. +**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 +### Prahování / thresholding -[quote] -____ -Prahuje se v Prahe často? [.small]#Badumtsss# -____ +> 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. --- +- Prahování je jedna z nejjednodušších metod segmentace obrazu. +- Práh lze určit manuálně nebo automaticky. + +#### Globální prahování -==== 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í. -+ -[stem] -++++ -\sigma^2_w(t) = q_1(t) \sigma_1^2(t) + q_2(t) \sigma_2^2(t) -++++ -+ -image::./img/szp10_otsu.png[width=500] -+ -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. -+ -[stem] -++++ -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:; -+ -[stem] -++++ -\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} -++++ -+ -image::./img/szp10_unimodal.png[width=500] - -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í. --- -+ -image::./img/szp10_hysteresis.png[width=400] - -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í +- **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) + ``` + + ![width=500](./img/szp10_otsu.png) + + 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} + ``` + + ![width=500](./img/szp10_unimodal.png) + +- **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í. + + ![width=400](./img/szp10_hysteresis.png) + +- **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) +### 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ů 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 link:../3d-modelovani-a-datove-struktury/[3D modelování a datové struktury]. - -Ohraničující obdélník / bounding box:: -Nejmenší obdélník ohraničující objekt. -+ -image::./img/szp10_bounding_box.png[width=300] - -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. -+ -image::./img/szp10_feret_diameter.png[width=300] --- - -Kruhovost / circularity:: -Jak moc je objekt podobný kruhu? -+ -[stem] -++++ -\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 stem:[m_{pq}(R) = \sum_{(u,v) \in R} I(u,v) \cdot u^p v^q], kde stem:[I(u,v)] je intenzita pixelu na pozici stem:[(u,v)] a stem:[R] je oblast objektu. -+ -Vidíme, že obsah odpovídá stem:[m_{00}] a geometrický střed (=těžiště) stem:[(m_{10}/m_{00}, m_{01}/m_{00})]. -+ -Můžeme využít *centrální momenty*, které jsou posunuté do těžiště objektu stem:[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. <> -+ -==== -Provazochodci využívají moment setrvačnosti při chůzi po laně. - -image::./img/szp10_provazochodec.jpg[] -==== - -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. <> - -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. -+ -image::./img/szp10_lbp.png[width=300] - +- **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. + + ![width=300](./img/szp10_bounding_box.png) + +- **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. + + ![width=300](./img/szp10_feret_diameter.png) + +- **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í. -== Klasifikace objektů + 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ě. + + ![szp10_provazochodec](./img/szp10_provazochodec.jpg) + +**💡 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. + + ![width=300](./img/szp10_lbp.png) + +## 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 link:../strojove-uceni/[Strojové učení]. - -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. --- -+ -image::./img/szp10_hierarchical_clustering.png[width=300] - -K-means clustering:: -Shlukuje objekty podle těžišť. Počet shluků je pevně stanovený na stem:[k]. -+ -image::./img/szp10_k_means.png[width=300] - -=== 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*. --- -+ -image::./img/szp10_classification_results.png[width=300] - -Precision:: -+ -[stem] -++++ -\frac{TP}{TP + FP} -++++ - -Sensitivity / recall:: -+ -[stem] -++++ -\frac{TP}{TP + FN} -++++ - -Specificity:: -+ -[stem] -++++ -\frac{TN}{TN + FP} -++++ - -Accuracy:: -+ -[stem] -++++ -\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í +**❗ 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. + + ![width=300](./img/szp10_hierarchical_clustering.png) + +- **K-means clustering**\ + Shlukuje objekty podle těžišť. Počet shluků je pevně stanovený na $k$. + + ![width=300](./img/szp10_k_means.png) + +### 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**. + + ![width=300](./img/szp10_classification_results.png) + +- **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ů. --- - -image::./img/szp10_distance_maps.png[width=500] - -Metriky vzdálenosti:: -+ --- -* Euklidovská stem:[\textcolor{red}{D_E}]. -* Taxikářská stem:[\textcolor{blue}{D_4}]. -* Šachovnicová stem:[\textcolor{green}{D_8}]. --- -+ -[stem] -++++ -\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} -++++ -+ -image::./img/szp10_distance.png[] - -== 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. <> - -Binární obraz:: -Dá se vnímat jako funkce stem:[I: \Omega \rightarrow \{0, 1\}], kde stem:[\Omega \sub \mathbb{Z}^2]. -+ -Ale taky to je množina stem:[F = \{ (x, y) | I(x, y) = 1 \}] - -=== Základní operátory +- 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ů. + +![width=500](./img/szp10_distance_maps.png) + +- **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} + ``` + + ![szp10_distance](./img/szp10_distance.png) + +## 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. <> -+ --- -* Má definovaný _počátek_ -- stem:[(0, 0)]. Schematicky se značí křížkem. -* Aktuálně uvažovaná souřadnice do něj nemusí patřit. --- -+ -image::./img/szp10_structuring_elements.png[width=100%] - -Posunutí množiny:: -Nechť stem:[F] je množina souřadnic. Posunutí stem:[F] o vektor stem:[b] je množina: -+ -[stem] -++++ -F_b = \{ s | s = s' + b, s' \in F \} -++++ - -Zrcadlení SE:: -Překlopení souřadnic podle počátku. -+ -[stem] -++++ -\breve{B} = \{ (-x, -y) | (x, y) \in B \} -++++ - -Eroze:: -+ -[quote] -____ -*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. -+ -[stem] -++++ -\Large -\varepsilon_B (X) = \{ x | B_x \subseteq X \} -++++ -+ -kde stem:[B] je SE a stem:[X] je vyšetřovaná množina / obraz. -+ -_"Hloupý" algoritmus_: hledání minima v okolí daném SE. -+ -image::./img/szp10_erosion.png[width=400] - -Dilatace:: -+ -[qoute] -____ -*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. -+ -[stem] -++++ -\Large -\delta_B (X) = \{ x | B_x \cap X \neq \emptyset \} -++++ -+ -kde stem:[B] je SE a stem:[X] je vyšetřovaná množina / obraz. -+ -_"Hloupý" algoritmus_: hledání maxima v okolí daném SE. -+ -image::./img/szp10_dilation.png[width=400] - - -Otevření / opening:: -+ -[quote] -____ -*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. --- -+ -[stem] -++++ -\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 stem:[B] je SE a stem:[X] je vyšetřovaná množina / obraz. -+ -image::./img/szp10_opening.png[width=400] - -Uzavření / closing:: -+ -[quote] -____ -*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. --- -+ -[stem] -++++ -\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 stem:[B] je SE a stem:[X] je vyšetřovaná množina / obraz. -+ -image::./img/szp10_closing.png[width=400] - - -=== 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í. -+ -[stem] -++++ -\Large -B = (B_\text{fg}, B_\text{bg}), B_\text{fg} \cap B_\text{bg} = \emptyset -++++ -+ -image::./img/szp10_compound_se.png[width=200] -+ -[quote] -____ -*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 -____ -+ -[stem] -++++ -\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. --- -+ -image::./img/szp10_hmt.png[width=400] - -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. --- -+ -image::./img/szp10_top_hat.png[width=500] - -Watershed:: -Algoritmický přístup k segmentaci skrze matematickou morfologii. Kombinuje segmentaci _narůstáním oblastí_ a _detekcí hran_. <> -+ --- -* 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: -+ --- -. Vyhlaď obrázek např. pomocí Gaussova filtru. -. Zjisti maximální a minimální intenzitu obrazu: stem:[(a_\text{high}, a_\text{low})]. -. Urči značky pro budoucí objekty (manuálně nebo z lokálních minim). -. Inicializuj binární obraz stem:[B] vynulováním. -. Pro stem:[a] od stem:[a_\text{low}] do stem:[a_\text{high}]: -.. Nech narůst oblasti značek, tak aby byly do stem:[B] přidány pixely s intenzitou stem:[\leq a]. -.. Nedovol spojení oblastí různých značek. -. stem:[B] nyní definuje oblasti objektů. Počet objektů je roven počtu značek. --- -+ -image::./img/szp10_watershed.png[width=600] - -[bibliography] -== Zdroje - -* [[[pb130,1]]] link:https://is.muni.cz/auth/el/fi/podzim2022/PB130/[PB130 Úvod do digitálního zpracování obrazu (podzim 2022)] -* [[[pv131,2]]] link:https://is.muni.cz/auth/el/fi/jaro2023/PV131/[PV131 Digitální zpracování obrazu (jaro 2023)] -* [[[image-moment,3]]] link:https://en.wikipedia.org/wiki/Image_moment[Wikipedia: Image moment] -* [[[moment, 4]]] link:https://en.wikipedia.org/wiki/Moment_(mathematics)[Wikipedia: Moment (mathematics)] -* [[[morphology, 5]]] link:https://en.wikipedia.org/wiki/Mathematical_morphology[Wikipedia: Mathematical morphology] - - -== Další zdroje - -* Haralick, Shapiro: Image segmentation techniques -* link:https://www.sciencedirect.com/science/article/pii/S1077314207001294#bib46[Zhang, Fritts, Goldman: Image segmentation evaluation: A survey of unsupervised methods] -* link:https://hsm.stackexchange.com/questions/11433/what-is-the-reasoning-behind-using-moment-in-the-moment-of-inertia[What is the reasoning behind using "moment" in the "moment of inertia"?] +- **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. + + ![width=100%](./img/szp10_structuring_elements.png) + +- **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. + + ![width=400](./img/szp10_erosion.png) + +- **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. + + ![width=400](./img/szp10_dilation.png) + +- **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. + + ![width=400](./img/szp10_opening.png) + +- **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. + + ![width=400](./img/szp10_closing.png) + +### 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 + ``` + + ![width=200](./img/szp10_compound_se.png) + + > **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. + + ![width=400](./img/szp10_hmt.png) + +- **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. + + ![width=500](./img/szp10_top_hat.png) + +- **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. + + ![width=600](./img/szp10_watershed.png) + +## 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)]() +- [[[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) diff --git a/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md b/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md index 4b95cf4..c8abf93 100644 --- a/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md +++ b/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md @@ -1,291 +1,263 @@ -= Grafické principy ve vývoji her (2024) -:url: ./graficke-principy-ve-vyvoji-her/ -:page-group: vph -:page-order: VPH01 2024 +--- +title: "Grafické principy ve vývoji her (2024)" +description: "TODO" +--- -[NOTE] -==== -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). +
📌 NOTE
+ +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_ -==== - - -== 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. <> - -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. <> - -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. <> 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: -+ -[stem] -++++ -F_\text{Schlick}(F_0, L, N) = F_0 + (1 - F_0) \cdot (1 - L \cdot N)^5 -++++ -+ -kde: -+ --- -* stem:[F_0] je Fresnelův odraz při úhlu 0 (dá se dohledat pro daný materiál), -* stem:[L] je vektor směru světla, -* stem:[N] je vektor normály povrchu. --- -+ -.Z určitého úhlu se povrchy, které normálně světlo odráží špatně, jeví jako zrcadla (link:https://commons.wikimedia.org/w/index.php?curid=2138545[tanakawho]) -image::./img/vph01_fresnel.jpg[width=300] - -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: -+ -[stem] -++++ -\frac{\sin \alpha_1}{\sin \alpha_2} = \frac{v_1}{v_2} = \frac{n_2}{n_1} -++++ -+ -kde: -+ -* stem:[\alpha_1] je úhel dopadu (angle of incidence), -* stem:[\alpha_2] je úhel lomu (angle of refraction), -* stem:[v_1] je rychlost šíření vlnění ve vnějším prostředí, -* stem:[v_2] je rychlost šíření vlnění v prostředí objektu, -* stem:[n_1] je index lomu vnějšího prostředí, -* stem:[n_2] je index lomu prostředí objektu. -+ -image::./img/vph01_snell.svg[width=500rem] - -Diffuse lighting:: -Když všechno (neabsorbované) světlo opustí objekt ze stejného místa, kam dopadlo. -+ -image::./img/vph01_diffuse.png[width=500rem] - -Subsurface scattering:: -Když neabsorbované světlo opustí objekt z jiného místa, než kam dopadlo. -+ -image::./img/vph01_subsurface_scattering.png[width=500rem] - -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). -+ -image::./img/vph01_microfacets.png[width=500rem] -+ -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 (stem:[\Phi]):: -"Energy per second." Bezva na popisování síly světel jako jsou žárovky, plošná světla, atd. -+ -[stem] -++++ -\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. -+ -[stem] -++++ -E = \frac{\partial \Phi}{\partial A} -++++ -+ -Jednotka: Watt per square meter (stem:[\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. -+ -[stem] -++++ -L = \frac{\partial^2 \Phi}{\partial A_\text{proj} \partial \omega} -++++ -+ -Jednotka: Watt per square meter per steradian (stem:[\frac{W}{m^2 \cdot sr}]) - -=== Bidirectional Reflectance Distribution Function (BRDF) + +
+ +## 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))** + + ![width=300](./img/vph01_fresnel.jpg) + +- **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. + + ![width=500rem](./img/vph01_snell.svg) + +- **Diffuse lighting**\ + Když všechno (neabsorbované) světlo opustí objekt ze stejného místa, kam dopadlo. + + ![width=500rem](./img/vph01_diffuse.png) + +- **Subsurface scattering**\ + Když neabsorbované světlo opustí objekt z jiného místa, než kam dopadlo. + + ![width=500rem](./img/vph01_subsurface_scattering.png) + +- **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). + + ![width=500rem](./img/vph01_microfacets.png) + + 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. -[stem] -++++ +```math f(\vec{l}, \vec{v}) = \frac{\partial L_o(\vec{v})}{\partial E_i(\vec{l})} -++++ +``` -_Povrch je nasvícen ze směru stem:[\vec{l}] s ozářením stem:[\partial E(\vec{l})]. stem:[\partial(L_o(\vec{v}))] je odražená zář ve směru stem:[\vec{v}]._ +_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}$._ -[TIP] --- -Udává pravděpodobnost, že světlo dopadající na povrch ze směru stem:[\vec{l}] bude odraženo ve směru stem:[\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ů. <> -+ -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. -+ -image::./img/vph02_lod.png[width=500rem] -+ -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 link:https://commons.wikimedia.org/w/index.php?curid=24515584[Sirotk] -image::./img/vph02_geomorphing.png[width=500rem] - -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. <> -+ -Součástí problému je potřeba odhadnout, jak velkou plochu polygon zabere na obrazovce. - -Mipmapy:: -+ -[quote] -____ -multum in parvo -- mnoho v malém prostoru -____ -+ -V zásadě LOD na texturách. Z velikosti stem:[\delta] otexturovaného polygonu je LOD stem:[D = \log_2(\max(\delta, 1))]. Výsledek je získán interpolací mezi LODy stem:[\lfloor D \rfloor] a stem:[\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 link:https://commons.wikimedia.org/w/index.php?curid=27311755[Phorgan1] -image::./img/vph02_mipmaps.png[width=300rem] -+ -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 stem:[\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). <> - -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. -+ -image::./img/vph02_occlusion_culling.png[width=500rem] - -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. -+ -image:./img/vph02_portal_culling_1.png[width=49.5%] -image:./img/vph02_portal_culling_2.png[width=49.5%] - - -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.) - - -[bibliography] -== Zdroje - -* [[[medek,1]]]: link:++http://decibel.fi.muni.cz/pv255/2018/slides/PV255_-_06_-_Zakladni_postupy_pri_tvorbe_assetu_a_herniho_vizualu.pdf++[Lukáš Medek (CBE), Základní postupy při tvorbě assetů a herního vizuálu] -* [[[modular,2]]]: http://wiki.polycount.com/wiki/Modular_environments -* [[[pv227-2022, 3]]] link:https://is.muni.cz/auth/el/fi/podzim2022/PV227/[PV227 GPU Rendering (podzim 2022)] -* [[[pv255-2022,4]]] link:https://is.muni.cz/auth/el/fi/podzim2022/PV255/um/[Chmelík, PV255 Game Development I] -* [[[texture-mapping, 5]]] link:https://en.wikipedia.org/wiki/Texture_mapping[Wikipedia: Texture mapping] -* [[[pa010-2021,6]]] link:https://is.muni.cz/auth/el/fi/podzim2021/PA010/um/[Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021)] \ No newline at end of file +## 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. + + ![width=500rem](./img/vph02_lod.png) + + 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)** + + ![width=500rem](./img/vph02_geomorphing.png) + +- **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)** + + ![width=300rem](./img/vph02_mipmaps.png) + + **💡 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. + + ![width=500rem](./img/vph02_occlusion_culling.png) + +- **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. + + ![width=49.5%](./img/vph02_portal_culling_1.png) + ![width=49.5%](./img/vph02_portal_culling_2.png) + +- **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/) diff --git a/szmgr/VPH01_pokrocila_grafika.md b/szmgr/VPH01_pokrocila_grafika.md index 5b4a8cc..cf8a279 100644 --- a/szmgr/VPH01_pokrocila_grafika.md +++ b/szmgr/VPH01_pokrocila_grafika.md @@ -1,411 +1,387 @@ -= Pokročilá počítačová grafika (2023) -:url: ./pokrocila-pocitacova-grafika/ -:page-group: vph -:page-order: VPH01 2023 +--- +title: "Pokročilá počítačová grafika (2023)" +description: "TODO" +--- -WARNING: Tato je stará verze otázky. Nová verze: link:./VPH01_graficke_principy_ve_vyvoji_her.ad[Grafické principy ve vývoji her]. +**⚠️ WARNING**\ +Tato je stará verze otázky. Nová verze: [Grafické principy ve vývoji her](./VPH01_graficke_principy_ve_vyvoji_her.ad). + +
📌 NOTE
-[NOTE] -==== 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_ -==== -== Techniky aproximace objektů +
+ +## 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 link:../graficke-a-fyzikalni-principy/[Grafické a fyzikální principy]. +**❗ 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. -=== Redukce počtu polygonů + - E.g. by using a weighted average of triangle normals. -Slučování polygonů (merging) či odstranění polygonů (culling), které nejsou vidět. <> + ![width=500rem](./img/vph01_vsa.jpg) -Variational Shape Approximation:: -1. Cluster surface elements (e.g. triangles) into stem:[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. -+ -image::./img/vph01_vsa.jpg[width=500rem] +- **Iterative Decimation -- Edge Collapse Simplification** -Iterative Decimation -- Edge Collapse Simplification:: -. Přiřaď každé hraně cenu (třeba quadratic error metric -- suma vzdáleností bodu od rovin) -. Zbab se hrany s nejnižší cenou sloučením jejích vrcholů. -. Opakuj, dokud nemáš požadovaný počet polygonů. -+ -image::./img/vph01_quadratic_error_metric.png[width=300rem] + 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 + ![width=300rem](./img/vph01_quadratic_error_metric.png) -Pokud dokážeme model vyjádřit pomocí matematických funkcí, nemusíme ukládat polygonovou síť. Např. koule je definována jako stem:[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. +### Implicitní reprezentace -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íť. +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. -=== Zjednodušení vzhledu +- **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) +### 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 stem:[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. +- **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 -== 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** -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 jsou definována nejčastěji jako mřížka voxelů. -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. + Při renderování objemů je třeba vyřešit několik souvisejících problémů s daty: -=== Bodový mrak (point cloud) + - 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 +### 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. <> <> -+ -.Marching cubes by link:https://commons.wikimedia.org/wiki/File:MarchingCubesEdit.svg[Ryoshoru] -image::./img/vph01_marching_cubes.svg[width=500rem] +- **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 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 cubes by [Ryoshoru](https://commons.wikimedia.org/wiki/File:MarchingCubesEdit.svg)** -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. <> + ![width=500rem](./img/vph01_marching_cubes.svg) -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. <> +- **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) -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ů. <> -+ -image::./img/vph01_delaunay.svg[width=300] + ![width=300](./img/vph01_delaunay.svg) -=== Direct volume rendering (přímé renderování objemu) +### 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ů. <> +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 <> -image::./img/vph01_direct_volume_rendering.jpg[width=500rem] - -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: <> -+ --- -* stem:[\kappa] je funkce absorpce, -* stem:[q] je emise. --- - -Optická hloubka / optical depth:: -Bezrozměrná veličina stem:[\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 stem:[s_1] a stem:[s_2] na paprsku je dána jako: -+ -[stem] -++++ -\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 stem:[s_1] a stem:[s_2] na paprsku je dána jako: -+ -[stem] -++++ -\theta(s_1, s_2) = e^{-\tau(s_1, s_2)} -++++ - -Volume rendering integral:: -Intenzitu světla stem:[I] v místě paprsku stem:[s] počítáme pomocí: <> -+ -[stem] -++++ -\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: -+ --- -* stem:[s_0] je místo, kde se paprsek dostal dovnitř nějakého světlo-vyzařujícího objemu, -* stem:[I(s_0)] je boundary light, tedy světlo na hranici objemu, -* stem:[q(s')] je emise v bodě stem:[s']. --- -+ -image::./img/vph01_emission_absorption_model.png[width=500] - -Back-to-front:: -Přístup k počítání stem:[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í stem:[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 stem:[T], která mapuje hodnoty voxelů na barvu a průhlednost. Klasifikuje voxely. <> - -== 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. <> 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: -+ -[stem] -++++ -F_\text{Schlick}(F_0, L, N) = F_0 + (1 - F_0) \cdot (1 - L \cdot N)^5 -++++ -+ -kde: -+ --- -* stem:[F_0] je Fresnelův odraz při úhlu 0 (dá se dohledat pro daný materiál), -* stem:[L] je vektor směru světla, -* stem:[N] je vektor normály povrchu. --- -+ -.Z určitého úhlu se povrchy, které normálně světlo odráží špatně, jeví jako zrcadla (link:https://commons.wikimedia.org/w/index.php?curid=2138545[tanakawho]) -image::./img/vph01_fresnel.jpg[width=300] - -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: -+ -[stem] -++++ -\frac{\sin \alpha_1}{\sin \alpha_2} = \frac{v_1}{v_2} = \frac{n_2}{n_1} -++++ -+ -kde: -+ -* stem:[\alpha_1] je úhel dopadu (angle of incidence), -* stem:[\alpha_2] je úhel lomu (angle of refraction), -* stem:[v_1] je rychlost šíření vlnění ve vnějším prostředí, -* stem:[v_2] je rychlost šíření vlnění v prostředí objektu, -* stem:[n_1] je index lomu vnějšího prostředí, -* stem:[n_2] je index lomu prostředí objektu. -+ -image::./img/vph01_snell.svg[width=500rem] - -Diffuse lighting:: -Když všechno (neabsorbované) světlo opustí objekt ze stejného místa, kam dopadlo. -+ -image::./img/vph01_diffuse.png[width=500rem] - -Subsurface scattering:: -Když neabsorbované světlo opustí objekt z jiného místa, než kam dopadlo. -+ -image::./img/vph01_subsurface_scattering.png[width=500rem] - -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). -+ -image::./img/vph01_microfacets.png[width=500rem] -+ -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 (stem:[\Phi]):: -"Energy per second." Bezva na popisování síly světel jako jsou žárovky, plošná světla, atd. -+ -[stem] -++++ -\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. -+ -[stem] -++++ -E = \frac{\partial \Phi}{\partial A} -++++ -+ -Jednotka: Watt per square meter (stem:[\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. -+ -[stem] -++++ -L = \frac{\partial^2 \Phi}{\partial A_\text{proj} \partial \omega} -++++ -+ -Jednotka: Watt per square meter per steradian (stem:[\frac{W}{m^2 \cdot sr}]) - -=== Bidirectional Reflectance Distribution Function (BRDF) +**The Process of Volume Rendering [gpugems](#gpugems)** + +![width=500rem](./img/vph01_direct_volume_rendering.jpg) + +- **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'$. + + ![width=500](./img/vph01_emission_absorption_model.png) + +- **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))** + + ![width=300](./img/vph01_fresnel.jpg) + +- **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. + + ![width=500rem](./img/vph01_snell.svg) + +- **Diffuse lighting**\ + Když všechno (neabsorbované) světlo opustí objekt ze stejného místa, kam dopadlo. + + ![width=500rem](./img/vph01_diffuse.png) + +- **Subsurface scattering**\ + Když neabsorbované světlo opustí objekt z jiného místa, než kam dopadlo. + + ![width=500rem](./img/vph01_subsurface_scattering.png) + +- **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). + + ![width=500rem](./img/vph01_microfacets.png) + + 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. -[stem] -++++ +```math f(\vec{l}, \vec{v}) = \frac{\partial L_o(\vec{v})}{\partial E_i(\vec{l})} -++++ +``` -_Povrch je nasvícen ze směru stem:[\vec{l}] s ozářením stem:[\partial E(\vec{l})]. stem:[\partial(L_o(\vec{v}))] je odražená zář ve směru stem:[\vec{v}]._ +_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}$._ -[TIP] --- -Udává pravděpodobnost, že světlo dopadající na povrch ze směru stem:[\vec{l}] bude odraženo ve směru stem:[\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ů +## 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. -+ -image:./img/vph01_hard_shadows.png[width=30%] -image:./img/vph01_hard_shadows_schema.png[width=69%] - -Soft shadows / "měkké" stíny:: -Rozlišují i částečně osvětlené oblasti. Týká se světel, která mají plochu. -+ -image:./img/vph01_soft_shadows.png[width=30%] -image:./img/vph01_soft_shadows_schema.png[width=69%] - -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. -+ -image::./img/vph01_shadow_maps.png[width=500rem] -+ -IMPORTANT: Shadow mapám se důkladně věnuje otázka link:../renderovani-s-vyuzitim-gpu/[Renderování s využitím 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ý. -+ -image::./img/vph01_shadow_volumes.png[width=500rem] -+ -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. - -[bibliography] -== 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]]] link:/fi/pa010/[Moje poznámky z PA010 (podzim 2020)] -* [[[manifold-wiki,5]]] link:https://en.wikipedia.org/wiki/Topological_manifold[Wikipedia: Topological manifold] -* [[[klein-bottle,6]]] link:https://plus.maths.org/content/imaging-maths-inside-klein-bottle[Konrad Polthier: Imaging maths - Inside the Klein bottle ] -* [[[genus,7]]] link:https://www.researchgate.net/publication/228393582_Notes_on_the_complex_of_curves[Saul Schleimer: Notes on the complex of curves] -* [[[gpugems,8]]] link:https://developer.nvidia.com/gpugems/gpugems/part-vi-beyond-triangles/chapter-39-volume-rendering-techniques[GPU Gems: Volume Rendering Techniques] -* [[[marching-cubes,9]]] link:https://dl.acm.org/doi/10.1145/37402.37422[Marching cubes: A high resolution 3D surface construction algorithm] -* [[[marching-tetrahedra,10]]] link:https://en.wikipedia.org/wiki/Marching_tetrahedra[Wikipedia: Marching tetrahedra] -* [[[dual-contouring,11]]] link:https://www.boristhebrave.com/2018/04/15/dual-contouring-tutorial/[Dual Contouring Tutorial] -* [[[delaunay-triangulation,12]]] link:https://en.wikipedia.org/wiki/Delaunay_triangulation[Wikipedia: Delaunay triangulation] -* [[[pv227-2022, 13]]] link:https://is.muni.cz/auth/el/fi/podzim2022/PV227/[PV227 GPU Rendering (podzim 2022)] - -== 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/ +- 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. + + ![width=30%](./img/vph01_hard_shadows.png) + ![width=69%](./img/vph01_hard_shadows_schema.png) + +- **Soft shadows / "měkké" stíny**\ + Rozlišují i částečně osvětlené oblasti. Týká se světel, která mají plochu. + + ![width=30%](./img/vph01_soft_shadows.png) + ![width=69%](./img/vph01_soft_shadows_schema.png) + +- **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. + + ![width=500rem](./img/vph01_shadow_maps.png) + + **❗ 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ý. + + ![width=500rem](./img/vph01_shadow_volumes.png) + + 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/ diff --git a/szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.md b/szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.md index e539701..8e2270c 100644 --- a/szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.md +++ b/szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.md @@ -1,95 +1,82 @@ -= Fyzikální principy ve vývoji her (2024) -:url: ./fyzikalni-principy-ve-vyvoji her/ -:page-group: vph -:page-order: VPH02 2024 +--- +title: "Fyzikální principy ve vývoji her (2024)" +description: "TODO" +--- + +
📌 NOTE
-[NOTE] -==== 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_ -==== - -== 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: <> - --- -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. +## Fyzikální simulace -Gilbert-Johnson-Keerthi (GJK):: -Algoritmus pro narrow phase. Rozhoduje zda dva konvexní tvary mají společný průnik. +- **Rigid body**\ + Aproximace reálného fyzikálního tělesa. Předpokládá uniformní hostotu a **neřeší:** -Primitivní collidery:: -Výpočty s nimi jsou rychlé. -+ -* krabice (AABB), -* koule, -* kapsle, -* válec. -+ -.Primitivní collidery v Unity -image::./img/vph02_unity_colliders.png[width=500rem] + - deformace objektu, + - aerodynamičnost tvaru. -Mesh collider:: -Neprimitivní collider objekt. Obvykle konvexní obal nějakého meshe. Vypočetně náročné. + Nicméně **řeší**: -Compound collider:: -Collider složený z vícero primitivních colliderů. Rychlejší než mesh collider. Použitelný i na nekonvexní objekty. + - dynamiku (část mechaniky, která se zabývá příčinami pohybu), + - kolize, + - klouby. -Quickhull:: -Algoritmus pro výpočet konvexního obalu. +- **Soft body**\ + Deformovatelný objekt. +- **Fyzikální enginy** + - PhysX (Nvidia) -- Unity, Unreal Engine. + - Bullet -- Blender, Paradox engine. + - Havok + - Box2D -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. +## Objekty pro detekci kolizí -Dynamické objekty:: -Působí na ně fyzika. Měly by mít jednodušší collidery. +V principu funguje detekce kolizí tak, že v každém kroku fyzikální simulace: [pa199-2022](#pa199-2022) -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é. +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). -== Zdroje -* [[[pa199-2022,9]]] link:https://is.muni.cz/auth/el/fi/podzim2022/PA199/um/[Chmelík, Trtík, PA199 Advanced Game Development] \ No newline at end of file +- **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** + + ![width=500rem](./img/vph02_unity_colliders.png) + +- **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/) diff --git a/szmgr/VPH02_graficke_a_fyzikalni_principy.md b/szmgr/VPH02_graficke_a_fyzikalni_principy.md index 7190b55..1b98c20 100644 --- a/szmgr/VPH02_graficke_a_fyzikalni_principy.md +++ b/szmgr/VPH02_graficke_a_fyzikalni_principy.md @@ -1,357 +1,327 @@ -= Grafické a fyzikální principy (2023) -:url: ./graficke-a-fyzikalni-principy/ -:page-group: vph -:page-order: VPH02 2023 +--- +title: "Grafické a fyzikální principy (2023)" +description: "TODO" +--- -WARNING: Tato je stará verze otázky. Nová verze: link:./VPH02_fyzikalni_principy_ve_vyvoji_her.ad[Fyzikální principy ve vývoji her]. +**⚠️ WARNING**\ +Tato je stará verze otázky. Nová verze: [Fyzikální principy ve vývoji her](./VPH02_fyzikalni_principy_ve_vyvoji_her.ad). + +
📌 NOTE
-[NOTE] -==== 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_ -==== - -== 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. <> - -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. <> - -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ů. <> -+ -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. -+ -image::./img/vph02_lod.png[width=500rem] -+ -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 link:https://commons.wikimedia.org/w/index.php?curid=24515584[Sirotk] -image::./img/vph02_geomorphing.png[width=500rem] - -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. <> -+ -Součástí problému je potřeba odhadnout, jak velkou plochu polygon zabere na obrazovce. - -Mipmapy:: -+ -[quote] -____ -multum in parvo -- mnoho v malém prostoru -____ -+ -V zásadě LOD na texturách. Z velikosti stem:[\delta] otexturovaného polygonu je LOD stem:[D = \log_2(\max(\delta, 1))]. Výsledek je získán interpolací mezi LODy stem:[\lfloor D \rfloor] a stem:[\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 link:https://commons.wikimedia.org/w/index.php?curid=27311755[Phorgan1] -image::./img/vph02_mipmaps.png[width=300rem] -+ -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 stem:[\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). <> - -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. -+ -image::./img/vph02_occlusion_culling.png[width=500rem] - -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. -+ -image:./img/vph02_portal_culling_1.png[width=49.5%] -image:./img/vph02_portal_culling_2.png[width=49.5%] - - -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. <> <> -+ -.Cel-shaded Utah Teapot by link:https://commons.wikimedia.org/w/index.php?curid=1788125[NicolasSourd] -image::./img/vph02_cel.png[width=500rem] - -Color grading:: -Využívá se look-up table (LUT) pro jednotnou barevnou korekci. <> <> - -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). <> <> - -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. <> -+ -image::./img/vph02_dof.png[width=500rem] -+ -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. <> - -== Ray tracing / sledování paprsků + +
+ +## 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. + + ![width=500rem](./img/vph02_lod.png) + + 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)** + + ![width=500rem](./img/vph02_geomorphing.png) + +- **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)** + + ![width=300rem](./img/vph02_mipmaps.png) + + **💡 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. + + ![width=500rem](./img/vph02_occlusion_culling.png) + +- **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. + + ![width=49.5%](./img/vph02_portal_culling_1.png) + ![width=49.5%](./img/vph02_portal_culling_2.png) + +- **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)** + + ![width=500rem](./img/vph02_cel.png) + +- **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) + + ![width=500rem](./img/vph02_dof.png) + + **💡 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 https://commons.wikimedia.org/w/index.php?curid=3869326[Henrik] -image::./img/vph02_ray_tracing.svg[width=500rem] - -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. <> -+ -image::./img/vph02_spatial_data_structure.png[width=500rem] - -Bounding volume hierarchy (BVH):: -Hierarchická reprezentace scény, díky které průchod scénou zredukován z stem:[\mathcal{O}(n)] na stem:[\mathcal{O}(\log n)] (stem:[n] je počet objektů ve scéně). Dá se stavět top-down nebo bottom-up. <> -+ -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: - -image::./img/vph02_sah.png[width=500rem] - -Pravděpodobnost, že paprsek trefí stem:[L] je stem:[\color{red} p_L = \frac{SA(L)}{SA(N)}]. Analogicky stem:[\color{green} p_R = \frac{SA(R)}{SA(N)}]. - -Cena průchodu uzlem BVH je pak: - -[stem] -++++ -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: - -* stem:[c_T] je cena průchodu vnitřním uzlem, -* stem:[c_I] je cena kontroly průniku, -* stem:[t_N] je počet trojúhelníků v listu, - -Celková cena BVH je pak: -[stem] -++++ -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 https://commons.wikimedia.org/w/index.php?curid=3879675[David Eppstein] -image::./img/vph02_morton.svg[width=300rem] - -== Fyzikální simulace - -IMPORTANT: Renderování založenému na fyzikálních principech se věnuje část otázky link:../pokrocila-pocitacova-grafika/[Pokročilá počítačová 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: <> - --- -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). --- +- 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)** + +![width=500rem](./img/vph02_ray_tracing.svg) + +- **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) + + ![width=500rem](./img/vph02_spatial_data_structure.png) + +- **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. -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. +- **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. -Sweep and prune:: -Algoritmus pro broad phase. + Mějme následující scénu: -Gilbert-Johnson-Keerthi (GJK):: -Algoritmus pro narrow phase. Rozhoduje zda dva konvexní tvary mají společný průnik. + ![width=500rem](./img/vph02_sah.png) -Primitivní collidery:: -Výpočty s nimi jsou rychlé. -+ -* krabice (AABB), -* koule, -* kapsle, -* válec. -+ -.Primitivní collidery v Unity -image::./img/vph02_unity_colliders.png[width=500rem] + 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)}$. -Mesh collider:: -Neprimitivní collider objekt. Obvykle konvexní obal nějakého meshe. Vypočetně náročné. + Cena průchodu uzlem BVH je pak: -Compound collider:: -Collider složený z vícero primitivních colliderů. Rychlejší než mesh collider. Použitelný i na nekonvexní objekty. + ```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} + ``` -Quickhull:: -Algoritmus pro výpočet konvexního obalu. + kde: -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. + - $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, -Dynamické objekty:: -Působí na ně fyzika. Měly by mít jednodušší collidery. + Celková cena BVH je pak: -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. + ```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 + ``` -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é. + 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)** + + ![width=300rem](./img/vph02_morton.svg) + +## 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). -== Fyzika hadrové panenky +- **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** + + ![width=500rem](./img/vph02_unity_colliders.png) + +- **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) <> -image::./img/vph02_ragdoll.jpg[width=500rem] - -Featherstone's algorithm:: -Algoritmus pro výpočet dynamiky stromovité struktury propojených článků. - -[bibliography] -== Zdroje - -* [[[medek,1]]]: link:++http://decibel.fi.muni.cz/pv255/2018/slides/PV255_-_06_-_Zakladni_postupy_pri_tvorbe_assetu_a_herniho_vizualu.pdf++[Lukáš Medek (CBE), Základní postupy při tvorbě assetů a herního vizuálu] -* [[[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]]] link:++http://decibel.fi.muni.cz/pv255/2018/slides/PV255_-_09_-_Graficke_efekty.pdf++[Jan Zelený, Grafické efekty] -* [[[hair,6]]] https://www.fxguide.com/fxfeatured/pixars-renderman-marschner-hair/ -* [[[color-grading,7]]] link:https://docs.unrealengine.com/5.2/en-US/using-look-up-tables-for-color-grading-in-unreal-engine/[Using Look-up Tables for Color Grading] -* [[[coc,8]]] https://en.wikipedia.org/wiki/Circle_of_confusion -* [[[pa199-2022,9]]] link:https://is.muni.cz/auth/el/fi/podzim2022/PA199/um/[Chmelík, Trtík, PA199 Advanced Game Development] -* [[[quickhull,10]]] link:https://dl.acm.org/doi/pdf/10.1145/235815.235821[Barber, Dopkin, Huhdanpaa: The Quickhull Algorithm for Convex Hulls] -* [[[ragdolls,11]]] http://www.animats.com/ -* [[[bvh-rt,12]]] link:https://is.muni.cz/auth/el/fi/jaro2022/PA213/um/slides/BoundingVolumeHierarchiesforRayTracing.pdf[Bittner: Bounding Volume Hierarchies for Ray Tracing] -* [[[path-tracing,13]]] link:https://www.techspot.com/article/2485-path-tracing-vs-ray-tracing/[Path Tracing vs. Ray Tracing, Explained] -* [[[bvh,14]]] link:https://www.pbr-book.org/3ed-2018/Primitives_and_Intersection_Acceleration/Bounding_Volume_Hierarchies[Pharr, Jakob, Humphreys; Physically Based Rendering: From Theory To Implementation; Chapter 4: Bounding Volume Hierarchies] -* [[[pv255-2022,15]]] link:https://is.muni.cz/auth/el/fi/podzim2022/PV255/um/[Chmelík, PV255 Game Development I] -* [[[pa010-2021,16]]] link:https://is.muni.cz/auth/el/fi/podzim2021/PA010/um/[Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021)] -* [[[texture-mapping, 17]]] link:https://en.wikipedia.org/wiki/Texture_mapping[Wikipedia: Texture mapping] +- 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)** + +![width=500rem](./img/vph02_ragdoll.jpg) + +- **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) diff --git a/szmgr/VPH03_herni_design_i.md b/szmgr/VPH03_herni_design_i.md index 020f854..b7f8eb0 100644 --- a/szmgr/VPH03_herni_design_i.md +++ b/szmgr/VPH03_herni_design_i.md @@ -1,226 +1,169 @@ -= Herní design I -:url: ./herni-design-i/ -:page-group: vph -:page-order: VPH03 +--- +title: "Herní design I" +description: "TODO" +--- -[NOTE] -==== +==== 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_ -==== - -[quote, ZZ] -____ -Game design is an idea. An idea is worthless. An idea is not playable.<> <> -____ - -[quote, Taky ZZ] -____ -Game design is like a recipe... -It looks fine, but you can't eat it... +> Game design is an idea. An idea is worthless. An idea is not playable.[pa215-2022](#pa215-2022) [pa215-2019](#pa215-2019) +> +> — ZZ -Well it can be eaten, but it doesn't fill you up. -____ +> 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 -[quote, Určitě ne ŽŽ] -____ -Hra... je zbytečný termín. -____ +> 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_. -[quote, Jesse Schell, Art of Game Design (2008)] -____ -A game is a problem-solving activity, approached with a playful attitude. -____ - -[quote, Salen & Zimmerman, Rules of Play (2004)] -____ -A game is a *system* in which *players* engage in an *artificial conflict* defined by *rules*, that results in a *quantifiable outcome*. -____ - -[quote, ZZ? Asi.] -____ -Every game is a mental model, a simple mental model of reality, that is easily stored, considered, and manipulated. -____ - -.Vlastnosti her <> -. Games are *entered willfully*. -. Games have *goals*. -. Games have *conflict*. -. Games have *rules*. -. Games *can be won and lost*. -. Games are *interactive*. -. Games have *challenge*. -. Games *can create their own internal value*. -. Games *engage players*. -. Games are *closed, formal systems*. +> A game is a problem-solving activity, approached with a playful attitude. +> +> — Jesse Schell -Hry se dají (poměrně hnidopišsky a rozhodně ne jednoznačně) rozdělit na: - -Hra:: -Něco, co se dá hrát. +> A game is a **system** in which **players** engage in an **artificial conflict** defined by **rules**, that results in a **quantifiable outcome**. +> +> — Salen & Zimmerman -Hračka:: -Předmět, který slouží ke hraní. +> Every game is a mental model, a simple mental model of reality, that is easily stored, considered, and manipulated. +> +> — ZZ? Asi. -Videohra:: -Něco, co se dá hrát na obrazovce. +**Vlastnosti her [schell](#schell)** -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. +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**. -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). +Hry se dají (poměrně hnidopišsky a rozhodně ne jednoznačně) rozdělit na: -Konzolová hra (console game):: -Digitální videohra určená pro herní konzoli (PlayStation, Xbox, Nintendo Switch, ...). +- **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, ...). -[NOTE] -==== 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 <>. - -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. +- **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. -+ -[quote] -What happened? I missed it, I was talking. - -Killer:: -Působí na ostatní hráče. Záleží mu na jeho skillech a reputaci. -+ -[quote] -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. -+ -[quote] -Only 4211 points to go! - -Explorer:: -Snaží se objevovat a poznávat svět. Je hrdý na hloubku svých znalostí o světě. -+ -[quote] -____ -I haven't tried that one, what's it do? -____ --- - -.Bartle's Taxonomy of Players <> -image::./img/vph03_bartle.png[width=500rem] +**Bartleho taxonomie** -=== 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. +- **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. -== Komponenty hry +- **Killer**\ + Působí na ostatní hráče. Záleží mu na jeho skillech a reputaci. -Na hru se dá dívat z mnoha různých perspektiv: <> + Die! -[%header, cols="2,3,2"] -|=== -| Component -| Type -| Example +- **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. -| Experience -| Outer layer / aesthetic -| Fear + Only 4211 points to go! -| Loops -| Gameplay / motivation / ... -| Opening doors +- **Explorer**\ + Snaží se objevovat a poznávat svět. Je hrdý na hloubku svých znalostí o světě. -| Dynamics / strategies -| Gameplay depth -| Hiding in the light + > I haven’t tried that one, what’s it do? -| Actions -| Game mechanics -| Lantern / light +**Bartle’s Taxonomy of Players [pa215-2022](#pa215-2022)** -| Goals -| Motivation -| To survive +![width=500rem](./img/vph03_bartle.png) -| Elements -| Components / aesthetic -| Castle +=== 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 -| System(s) -| Behaviour of system / rules of interaction -| SFX, enemy AI, narration, ... -|=== +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) -[quote, ZZ?] Games are only means for a greater goal - creating experience. -[quote, ZZ?] 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 link:../herni-design-ii/[Herní design II]. - -==== LeBlanc's Eight Kinds of Fun - -TIP: Taky označované jako _Taxonomy of Game Pleasures_ a _herní "pošušňáníčka"_. <> - -Game designer Marc LeBlanc rozdělil herní zážitky do osmi kategorií: <><> - -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". +**❗ 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é. @@ -234,13 +177,14 @@ 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. +- 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. + +- _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 @@ -251,37 +195,34 @@ Něco nové, co hru odlišuje od ostatních her. Taky lze nazvat unique selling 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á? +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 link:../herni-design-ii/[Herní design II]. +**❗ IMPORTANT**\ +Testováním se více zabývá otázka [Herní design II](../herni-design-ii/). == Game Designer -[quote, ZZho slidy z Herního inkubátoru] -____ -Artist = inner calling = intimate. - -To create a game is not intimate. - -[.small]#In a small team it is possible.# - -Team = too many voices. - -Team = work together. - -____ - - -Cíl:: -* [.line-through]#Cílem game designera je vytvořit hru.# -* [.line-through]#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í. <> - -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. +> 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 @@ -289,123 +230,107 @@ Nejlepším nástrojem game designera je tužka a papír. Papírový prototyp je Kromě nich ale existuje: -* link:https://twinery.org/[Twine], -* link:http://www.bitsy.org/#0,0[Bitsy], -* link:https://www.flickgame.org/[Flickgame]. - +- [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. -[quote, Ano, stále ZZ] -____ -[.underline]#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*. +> 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. -[quote, Jesse Schell, Art of Game Design (2008)] -____ -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, [.underline]#*and why*# it is or is not working. -____ +> 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. <> +Při balancování hry designer úmyslně ničí svoji hru, aby odhalil její hranice. [pa215-2022](#pa215-2022) + +**Doporučení** -.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. +- 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. +**📌 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. <> Hodí se při komunikaci s klienty, nevyvojáři a nehráči. <> +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 <> -image::./img/vph03_cgo.svg[width=100%] +**The Core Game Ontology [cgo](#cgo)** -Visuals:: -Any visual output of the game, which range from photorealistic, to caricaturize, to abstract visuals. +![width=100%](./img/vph03_cgo.svg) -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. +- **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. <> 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. - +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. -[bibliography] == 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 +- [[[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 -* link:http://www.costik.com/nowords2002.pdf[Greg Costikyan: I Have No Words & I Must Design: Toward a Critical Vocabulary for Game] +- [Greg Costikyan: I Have No Words & I Must Design: Toward a Critical Vocabulary for Game](http://www.costik.com/nowords2002.pdf) diff --git a/szmgr/VPH04_herni_design_ii.md b/szmgr/VPH04_herni_design_ii.md index a499025..5910504 100644 --- a/szmgr/VPH04_herni_design_ii.md +++ b/szmgr/VPH04_herni_design_ii.md @@ -1,345 +1,320 @@ -= Herní design II -:url: ./herni-design-ii/ -:page-group: vph -:page-order: VPH04 +--- +title: "Herní design II" +description: "TODO" +--- + +
📌 NOTE
-[NOTE] -==== 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_ -==== -== Návrh hry +
-Jednotka herního designu:: +## Návrh hry -Jednotkou herního designu se rozumí dokument, který popisuje část hry (textový popis, obrázky) z pohledu designera, artisty, programátora... +- **Jednotka herního designu** -Návrh designu hry:: +Jednotkou herního designu se rozumí dokument, který popisuje část hry (textový popis, obrázky) z pohledu designera, artisty, programátora... -Designový dokument:: +- **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 +- 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 -=== Magický kruh Johana Huizingy +## Teoretické koncepty herní analýzy -[quote, Salen & Zimmerman, Rules of Play (2003)] -____ -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. -____ +### Magický kruh Johana Huizingy -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í. <> <> +> 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 -Byť ten termín zmínil jako první Huizinga, zadefinovali a zpopularizovali ho až Salen a 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) -=== Kybertext +Byť ten termín zmínil jako první Huizinga, zadefinovali a zpopularizovali ho až Salen a Zimmerman. [zimmerman-essay](#zimmerman-essay) -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í <>. +### Kybertext -[quote, Aarseth, Cybertext—Perspectives on Ergodic Literature (1997)] +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 +### 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ů). -[quote, Josh Bycer, Darwinian Difficulty: How Throwing Players In Headfirst Can Work] -____ -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*. -____ +> 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 (stem:[\text{AD}]):: -To, co jsme nadesignovali. +- **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. -Vnímaná (perceived) obtížnost (stem:[\text{PD}]):: -To, jak obtížná hra přijde hráči. -+ -[stem] -++++ -\text{PD} = \text{AD} - \text{power provided} - \text{in-game experience} -++++ + ```math + \text{PD} = \text{AD} - \text{power provided} - \text{in-game experience} + ``` -==== Flow channel +#### Flow channel -TIP: Termín, se kterým přišel Mihaly Csikszentmihalyi _[me-high cheek-sent-me-high]_. +**💡 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. --- +- 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. -image::./img/vph04_flow.png[width=100%] +![width=100%](./img/vph04_flow.png) -== Teorie her +## Teorie her -WARNING: Game design != Game theory +**⚠️ 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ů.<> +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 +### 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). +- **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. -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í. + Příkladem symetrické hry jsou například kámen-nůžky-papír, prisoner’s dilema. -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. + 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. +- **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é. -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áčů. + 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. -Non-zero-sum:: -Celkový výsledek hry není nula. Výhra jednoho hráče neznamená nutně prohru druhého hráče. +- **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 +### Dominantní strategie -[quote, Adams (2009)] -____ -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 [.underline]#a dominant strategy#*. This lengthy and involved procedure makes it more likely that a mistake will get past the testers. -____ +> 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) -[quote, 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. -____ +> 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. +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. +- 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 -== 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) -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: <> +- text, +- video, +- audio, +- animation, +- film sequences, +- graphical user interface (GUI), +- architecture, +- system itself (procedural rhetoric), +- players themselves (fandom, other texts, ...). --- -* 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)** -.Interactivity with the narrative game <> -image::./img/vph04_narrative.png[width=500rem] +![width=500rem](./img/vph04_narrative.png) --- --- -* 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. --- +- 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. +- **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. -Svět:: -Kontext zahrnující prostředí a objekty. Všechno spojoje. +### Story vs Narrative -Postavy:: -Osobnosti, jejich prezentace a akce. Spojují svět a události. +- **Fabula (~ story)**\ + The raw material of the story. -Události:: -Jednotlivé věci, které se dějí a vytváří zápletku. Spojují formu a obsah. + Má zápletku, postavy, lore, story arc, atd. -=== Story vs Narrative +- **Syuzhet (~ narrative)**\ + The way the story is organized. -Fabula (~ story):: -The raw material of the story. -+ -Má zápletku, postavy, lore, story arc, atd. + 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. -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 -=== Struktura +- **Lineární (3-bodová struktura, Monomyth / Hero’s journey)** -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. -+ -[quote, Wikipedia: Hero's journey] -____ -[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. -____ + 1. Setup -- expozice, počáteční incident. + 2. Konfrontace -- překážky, krize. + 3. Rozuzlení -- vyvrcholení, závěr. -Nelineární:: -+ -[quote] -...will watch the other endings on YouTube. + > [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 -Smíšená:: -Lineární v některých místech, nelineární v jiných. +- **Nelineární** -=== Emergentní vyprávění + ...will watch the other endings on YouTube. -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í. <> +- **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 +- **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 +## Tutoriál a onboarding -[quote, Celia Hodent] -____ -Playing a game is a learning experience. -____ +> 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. <> -* A design of gameplay to motivate the player to achieve mastery. - -[quote, Miyamoto] -____ -[...] 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. -____ - -Limitace hráče:: -* Fyzické (např. ovladač, klávesnice, myš) -* Kognitivní (např. paměť, pozornost) -* Senzorické (např. zrak, sluch, hmat) -+ -[WARNING] -==== -Pozor na kognitivní overload! -==== -+ -[TIP] -==== -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. -==== - -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 +- **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) + +
⚠️ WARNING
+ + Pozor na kognitivní overload! +
+ +
💡 TIP
+ + 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. +
+ +- **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 +### Iterativní design Proces, kdy je game design testován na hráčích po celou dobu vývoje. A to často. -[quote, Jesse Schell, The Art of Game Design] -____ -1. Think of an Idea. -2. Try it out. -3. Keep changing it and testing it until it seems good enough. -____ - -[quote, Salen & Zimmerman, Rules of Play] -____ -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*. -____ - -[quote, Jesse Schell, The Art of Game Design] -____ -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? -____ - -=== Playtesting - -Playtest:: -+ -[quote, Oxford Dictionary] -____ -A test in which a product is played, or played with, to assess its *quality*, *safety*, or *marketability*. -____ -+ -[quote, Technopedia] -____ -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*. -____ - -Focus test:: -A playtest of a game by a particular focus group. +> 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. --- -[quote, Pozzi & Zimmerman, Don't follow these rules!] -____ -* Playtest before you think you are ready. -* Don't explain. -* Take notes. -* Shut Up. -* Notice everything. -____ - - -[bibliography] -== 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]]] link:https://www.gamedeveloper.com/design/jerked-around-by-the-magic-circle---clearing-the-air-ten-years-later[Eric Zimmerman: 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]]] link:https://static1.squarespace.com/static/579b8aa26b8f5b8f49605c96/t/5962a494bebafbc89ca001b6/1499636884792/A+Primer+for+Playtesting.pdf[Don't follow these rules!: A Primer for Playtesting, Nathalie Pozzi and Eric Zimmerman] +> - 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) diff --git a/szmgr/VPH05_vyvoj_her.md b/szmgr/VPH05_vyvoj_her.md index 5e17c81..35f474c 100644 --- a/szmgr/VPH05_vyvoj_her.md +++ b/szmgr/VPH05_vyvoj_her.md @@ -1,445 +1,405 @@ -= Vývoj her -:url: ./vyvoj-her/ -:page-group: vph -:page-order: VPH05 +--- +title: "Vývoj her" +description: "TODO" +--- + +
📌 NOTE
-[NOTE] -==== 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_ -==== -== Architektura herního enginu +
+ +## 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 - -Zvuk:: -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. <> - -=== Fyzická rozhraní +- **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. +- **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. -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. + **📌 NOTE**\ + Mechanické klávesnice, které mnohdy taky posílají spojité signály, zdá se nikdo zatím moc nepoužil. -=== Virtuální rozhraní +### 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. +- **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) -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. + **Fallout 3** -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é. <> -+ -.Fallout 3 -image::./img/vph05_diegetic_interface.png[width=400] + ![width=400](./img/vph05_diegetic_interface.png) -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 -image::./img/vph05_static_interface.jpg[width=400] +- **Nediegetická (statická) rozhraní**\ + Jsou "mimo" herní svět, přilepená k obrazovce, a jsou abstraktní, nesouvisí přímo s herním světem. -Meta rozhraní:: -Jsou sice mimo herní svět, ale alespoň s ním souvisí. Třeba telefon v GTA IV. -+ -.GTA IV -image::./img/vph05_meta_interface.jpg[width=400] -+ -TIP: link:https://about.meta.com[Meta] rozhraní != Oculus Quest + **World of Warcraft** -Spatial (prostorová) rozhraní:: -Nejsou "bežnou" součástí herního světa, ale nejsou ani mimo něj. -+ -.Forza -image::./img/vph05_spatial_interface.jpg[width=400] + ![width=400](./img/vph05_static_interface.jpg) -=== Virtuální realita (VR) +- **Meta rozhraní**\ + Jsou sice mimo herní svět, ale alespoň s ním souvisí. Třeba telefon v GTA IV. -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. + **GTA IV** -=== Brain computer interaction (BCI) + ![width=400](./img/vph05_meta_interface.jpg) -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í. + **💡 TIP**\ + [Meta](https://about.meta.com) rozhraní != Oculus Quest -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: <> -+ -* Layout -* Typografii -* Barevnou paletu -* Interaktivní prvky: tlačítka, checkboxy, radio buttony, comboboxy, selecty, dropdowny, nebo nedejbože datetimepickery. +- **Spatial (prostorová) rozhraní**\ + Nejsou "bežnou" součástí herního světa, ale nejsou ani mimo něj. -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: <> -+ -* Průzkum uživatelských očekávání a konkurence -* Wireframy a prototypování -* Testování + **Forza** -=== 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. + ![width=400](./img/vph05_spatial_interface.jpg) -== Audio ve hrách +### Virtuální realita (VR) -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:: -Objekty 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římé 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 souvislý 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. - -Zpož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 +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. -Zvuk v normálním světě je spojitá funkce času (analog). V počítačích se ale reprezentuje jako diskrétní hodnoty. +### Brain computer interaction (BCI) -Vzorkování:: -Spojitá funkce se vzorkuje v pravidelných intervalech. Vzniknou tak diskrétní body v čase. +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. -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. +### UI vs. UX -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. +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í. -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é). +- **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) -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ý (=orientovaný) acyklický graf efektů a mixérů. + - 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) -== Síťová vrstva + - Průzkum uživatelských očekávání a konkurence + - Wireframy a prototypování + - Testování -[WARNING] --- -Síťová hra nemusí být multiplayer, a multiplayer hra nemusí být síťová. --- +### Mapování -=== Krátké opakování ze sítí +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. -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, ...). +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...) -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í. +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. -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ě. +## Audio ve hrách -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. +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). -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). +### Propagace zvuku ve scéně -Latence:: -Doba, která uplyne mezi odesláním dat a doručením dat. Měří se v ms. +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). -Obousměrné zpoždění (round-trip time, RTT, lag):: -Doba, která uplyne mezi odesláním dat a doručením zpět. +- **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. -Jitter:: -Variabilita latence. Pokud je jitter vysoký, může dojít k nepředvídatelným zpožděním. + - 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. -Ztráta paketů:: -Procento ztracených paketů. +- **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". -=== Metody redukce latence + - 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. -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. +- **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. -.State inconsistency due to latency <>. -image::./img/vph05_network_delay.jpg[width=400] +### Digitální zvuk -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... +Zvuk v normálním světě je spojitá funkce času (analog). V počítačích se ale reprezentuje jako diskrétní hodnoty. -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. +- **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. -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í. + 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ů. -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. +## Síťová vrstva -Data compression:: -Méně dat = rychlejší přenos a zpracování. -+ -* Delta compression - server posílá jen věci, co se změnily. -* 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. +Síťová hra nemusí být multiplayer, a multiplayer hra nemusí být síťová. -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í. +### 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).** + +![width=400](./img/vph05_network_delay.jpg) + +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 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. +- **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. -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 -== Další věci ze staré verze otázky +## Produkční fáze -== Produkční fáze +### 1. Pre-produkce -=== 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) -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: <> - -* 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í. +- 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. +- **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. -Concept art:: -Vizuální návrhy postav, prostředí, objektů, atd. +### 2. Produkce -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. <> +_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. +- **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 -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ů. +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. -Gold master:: -Hra je ready k vypálení na CDčko, disketu nebo vinyl. +## Principy monetizace -=== 3. Post-produkce +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) -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. +- **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. -== Principy monetizace + Hry se do tohoto modelu většinou spadnou až po dostatečně dlouhé době (abandonware). -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. <> + **💡 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)? -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. +- **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í. -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 link:https://github.com/id-Software/Quake[Quake], link:https://github.com/id-Software/DOOM[DOOM] nebo link:https://github.com/id-Software/wolf3d[Wolfenstein 3D]? +## Procedurální generování assetů -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. +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í. -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í. +- **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ě. -Freemium:: -Hra je zdarma, ale je značně omezená, a snaží se hráče dotlačit k tomu, aby si ji koupil. +## Serious games -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. +_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. -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í. +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_. -== Procedurální generování assetů +- **Trénink**\ + Hra může být simulací nějakého procesu, který se v reálném světě děje. -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í. + Třeba simulace letu, řízení nějakého průmyslového procesu, nebo lékařského postupu. -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. + **📌 NOTE**\ + Chce se mi zmínit [Surgeon Simulator](https://store.steampowered.com/app/233720/surgeon_simulator/), ale to nejspíš není nejlepší příklad. -Perlin noise:: -Noise, který vymyslel Ken Perlin, když pracoval na filmu Tron (1982) v Disney. Má tu krásnou vlastnost, že není patentovaný. <> +- **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. -Simplex noise:: -Vylepšený Perlin noise, který taky vymyslel Ken Pelin. Tenhle už si patentovat nechal. <> + Třeba [_Duolingo_](https://www.duolingo.com/). -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ě. +## Gamification -== Serious games +_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. -_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. +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á. -Serious games se dají dělit podle jejich cíle: +## Zdroje -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 link:https://store.steampowered.com/app/233720/surgeon_simulator/[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 link:https://www.duolingo.com/[_Duolingo_]. - -== 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. <> Gamifikace je proto často brána jako manipulativní a opovrženihodná. - -[bibliography] -== Zdroje - -* Nové části otázky je vypracována dle prezentací z předmětu link:https://is.muni.cz/auth/el/fi/podzim2022/PV255/um/lec/[PV255]. -* [[[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/ +- 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/ diff --git a/szmgr/VPH06_ai_ve_hrach.md b/szmgr/VPH06_ai_ve_hrach.md index 5243a55..47b20a2 100644 --- a/szmgr/VPH06_ai_ve_hrach.md +++ b/szmgr/VPH06_ai_ve_hrach.md @@ -1,205 +1,178 @@ -= Umělá inteligence v počítačových hrách -:url: ./umela-inteligence-v-pocitacovych-hrach/ -:page-group: vph -:page-order: VPH06 +--- +title: "Umělá inteligence v počítačových hrách" +description: "TODO" +--- -[NOTE] -==== -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í. +
📌 NOTE
-_PA217_ -==== - -== 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 stem:[(x, z)] nebo stem:[(x, y, z)]. +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í. -Orientace:: -Obvykle v radiánech. Desetinné číslo z intervalu stem:[\lbrack 0, 2\pi )]. +_PA217_ -Rychlost / velocity:: -Změna pozice. Vektor stem:[(x, z)] nebo stem:[(x, y, z)]. +
-Úhlová rychlost / angular velocity / "rotace":: -Změna rotace. Desetinné číslo z intervalu stem:[\lbrack 0, 2\pi )]. +## Pohyb -Agent:: -Postava / objekt / entita vykonávájí pohyb a činící rozhodnutí. +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ě: -=== Kinematický pohyb +- 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: -+ -[source, 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 +- 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 +#### Ří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 <> -image::./img/vph06_seek.jpg[Seek schematic, 300] +- **Seek**\ + Přímočárý... doslova. Najde vektor mířící k cíli a aplikuje je jej jako steering. -Flee:: -Jako seek, ale *od* cíle místo k cíli. + **Seek schematic [steering](#steering)** -Align:: -Agent se snaží zarovnat svou orientaci s cílem. + ![Seek schematic](./img/vph06_seek.jpg) -Velocity matching:: -Agent se snaží mít stejnou rychlost jako cíl. +- **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 <> -image::./img/vph06_arrival.jpg[Arrival schematic, 300] +- **Arrival**\ + Jako seek, ale začne zpomalovat, když je blízko cíle, takže jej "nepřestřelí". -Departure:: -Flee, ale agent zpomalí, jakmile je dostatečně daleko od cíle. + **Arrival schematic [steering](#steering)** -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. + ![Arrival schematic](./img/vph06_arrival.jpg) -Evade:: -Agent se vyhýbá agentovi. Jako pursue, ale snaží se cíli vyhnout. -+ -Příklad: kořist se vyhýbá predátorovi. +- **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. -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. + Příklad: predátor loví kořist. -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. +- **Evade**\ + Agent se vyhýbá agentovi. Jako pursue, ale snaží se cíli vyhnout. -Path following:: -Agent směřuje ne _jen_ k pouhému bodu, ale k _nejbližšímu_ bodu na dané cestě a ten _seekuje_. + Příklad: kořist se vyhýbá predátorovi. -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ší. +- **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_. -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ů. + Má problém s úzkými překážkami a pastmi. -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ů. +- **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. +- _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. -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. +- _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 / 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í link:../../szb/grafove-problemy/[Grafových problémů] -==== - -Graf stem:[G]:: -Dvojice stem:[(V, E)], kde stem:[V] je množina uzlů a stem:[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 stem:[f] pro výběr dalšího uzlu k prozkoumání. +**Opakování [Grafových problémů](../../szb/grafove-problemy/)** -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 -- stem:[f] je nejnižší vzdálenost od počátečního uzlu. +- **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 -=== 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) -Podobný Dijkstrovu algoritmu, ale navíc se snaží odhadnout, který směr je nejlepší. Používá heuristiku stem:[h] pro výběr dalšího uzlu k prozkoumání. Kombinuje Dijsktrův algoritmus s greedy best-first hledáním. <> +**A\* algoritmus [astar](#astar)** -.A* algoritmus <> -image::./img/vph06_astar.png[width=100%] +![width=100%](./img/vph06_astar.png) -[source, csharp] ----- +```csharp record Node { Vector3 Position; List 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 @@ -239,12 +212,11 @@ float Heuristic(Node a, Node b) { // Example: Euclidean distance return Vector3.Distance(a.Position, b.Position); } ----- +``` Nejkratší cestu lze pak zrekonstruovat takto: -[source, csharp] ----- +```csharp List ReconstructPath(Node goal) { var path = new List { goal }; var current = goal; @@ -255,364 +227,329 @@ List ReconstructPath(Node goal) { 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. <> -+ -image::./img/vph06_euclidean_distance.png[width=400] - -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). -+ -image::./img/vph06_cluster_heuristic.png[width=400] -+ -image::./img/vph06_heuristic_comparison.png[width=100%] - -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í. <> - -Simplified Memory Bounded A* (SMA*):: -A* co má nižší paměťové nároky. - -=== Reprezentace herního světa +``` + +- **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) + + ![width=400](./img/vph06_euclidean_distance.png) + +- **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). + + ![width=400](./img/vph06_cluster_heuristic.png) + + ![width=100%](./img/vph06_heuristic_comparison.png) + +- **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 <> -image::./img/vph06_civilization.jpg[width=400] - -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 link:https://commons.wikimedia.org/w/index.php?curid=38534275[Balu Ertl] -image::./img/vph06_voronoi.svg[width=400] - -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 <> -image::./img/vph06_points_of_visibility.png[width=400] - -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 <> -image::./img/vph06_navmesh.png[Navigation System in Unity, 400] -+ -.Polygonal mesh graph <> -image::./img/vph06_polygonal_mesh_graph.png[width=400] - -=== Hierarchické hledání cest - -[quote] -____ -Nejdřív najde cestu mezi domy, pak teprve cestu od vchodových dveří k ledničce. -____ +- **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)** + + ![width=400](./img/vph06_civilization.jpg) + +- **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)** + + ![width=400](./img/vph06_voronoi.svg) + +- **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)** + + ![width=400](./img/vph06_points_of_visibility.png) + +- **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)** + + ![Navigation System in Unity](./img/vph06_navmesh.png) + + **Polygonal mesh graph [ai-for-games](#ai-for-games)** + + ![width=400](./img/vph06_polygonal_mesh_graph.png) + +### 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. +**❗ IMPORTANT**\ +Výhodou je, že zrychluje hledání cest. -[WARNING] --- 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. - --- +- nejkratší vzdálenost, +- nejdelší vzdálenost, +- průměrná minimální vzdálenost. -== Rozhodování +## 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 +### 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 <> -image::./img/vph06_decision_trees.png[width=500] +**Průchod rozhodovacím stromem [ai-for-games](#ai-for-games)** -=== State machines / stavové automaty +![width=500](./img/vph06_decision_trees.png) + +### 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 <> -image::./img/vph06_state_machine.png[width=500] +**State machine [ai-for-games](#ai-for-games)** + +![width=500](./img/vph06_state_machine.png) + +- **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)** + + ![width=500](./img/vph06_hierarchical_state_machine.png) -Hierarchické stavové automaty:: -Stavy mohou obsahovat celé další stavové automaty. To umožňuje rozdělit chování agenta na části. -+ -.Hierarchical state machine <> -image::./img/vph06_hierarchical_state_machine.png[width=500] +- **Stavový automat s rozhodovacími stromy v přechodech**\ + V přechodech mezi stavy jsou decision trees. Listy jsou další stavy. -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 <> -image::./img/vph06_decision_tree_state_machine.png[width=500] + **State machine with decision tree transitions [ai-for-games](#ai-for-games)** -=== Behavior trees / stromy chování + ![width=500](./img/vph06_decision_tree_state_machine.png) --- -* 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 trees / stromy chování -.Behavior tree <> -image::./img/vph06_behavior_tree.png[width=500] +- 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. -.Parallel behavior tree <> -image::./img/vph06_parallel_behavior_tree.png[width=500] +**Behavior tree [ai-for-games](#ai-for-games)** -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). --- +![width=500](./img/vph06_behavior_tree.png) -Vnitřní uzly:: --- -* _Sequences_ (sekvence) stem:[\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) stem:[?]: vykonávají své potomky po řadě, dokud _první_ není *úspěšný*. Selže, pokud neuspěje žádný. Je to takový `OR`. -* _Parallel sequence/selector_ stem:[\rightrightarrows] / stem:[???]: pouští všechny potomky najednou. Vyhodnocení zůstavá stejné. --- +**Parallel behavior tree [pa217](#pa217)** -Decorator / dekorátor:: -Obaluje nějaký uzel a mění jeho chování (např. inverze výsledku, opakování). +![width=500](./img/vph06_parallel_behavior_tree.png) -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. +- **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). -=== Cílem orientované chování +- **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. +- 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 +## Strategie a taktika Řeší rozhodování při nedostatku informací, koordinaci více agentů, plánování, atd. -=== Waypoints / navigační body +### Waypoints / navigační body Waypoint je pozice v levelu, která je něčím zajímavá. -Pathfinding nodes:: -Místa kudy se dá projít. +- **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 / 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 <> -image::./img/vph06_tactical_locations.png[width=500] + **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. + ![width=500](./img/vph06_tactical_locations.png) -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. +- **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. -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. +### Taktická analýza -Shadow points:: -Místa ve stínu. +Vyskytuje se primárně ve real-time strategických (RTS) hrách. -=== Taktická analýza +- **Influence maps** -Vyskytuje se primárně ve real-time strategických (RTS) hrách. + - 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/)** + + ![width=500](./img/vph06_influence_maps.png) + +- **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** -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 link:https://www.gamedev.net/tutorials/programming/artificial-intelligence/the-core-mechanics-of-influence-mapping-r2799/[gamedev.net] -image::./img/vph06_influence_maps.png[width=500] - -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._ +- 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í: -[stem] -++++ +```math \begin{aligned} \text{Vhodnost} &= \text{Bezpečnost} \cdot \text{Viditelnost} \cdot \text{Vzdálenost} \end{aligned} -++++ - -==== +``` -== Deskové hry +## 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. +- **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). -Imperfect information:: -Některé informace jsou skryté nebo náhodné, např. karty v ruce, hod kostkou. +### AI turn-based algoritmy -Zero-sum games:: -Hra, kde výhra jednoho hráče je prohrou druhého (např. šachy). +Algoritmy pro hledání nejlepšího tahu v tahových zero-sum deskových hrách pro dva hráče s perfektní informací. -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). +- **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. -=== AI turn-based algoritmy + - 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. -Algoritmy pro hledání nejlepšího tahu v tahových zero-sum deskových hrách pro dva hráče s perfektní informací. +#### Minimax algoritmus -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. +Projdi strom a vyber nejlepší možný tah pro nás s ohledem na to, že soupeř bude volit nejlepší tah pro sebe. -==== Minimax algoritmus +- 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_. -Projdi strom a vyber nejlepší možný tah pro nás s ohledem na to, že soupeř bude volit nejlepší tah pro sebe. +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)** + + ![width=100%](./img/vph06_mcts.svg) + +- **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 -* 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_. - -[TIP] --- -Minmax i alpha-beta pruning se chápe nejlíp s vizualizací. Můžete kouknout například na link:https://youtu.be/l-hh51ncgDI?feature=shared[Algorithms Explained – minimax and alpha-beta pruning]. --- - -==== Monte Carlo prohledávání - -[TIP] --- -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 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.<> -+ --- -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 link:https://commons.wikimedia.org/w/index.php?curid=88889583[Rmoss92] -image::./img/vph06_mcts.svg[width=100%] - -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. -+ -[stem] -++++ -\text{UCT} = \overline{X_j} + C \sqrt{\frac{\ln n}{n_j}} -++++ -+ -kde: -+ --- -* stem:[\overline{X_j}] je střední hodnota odměny z akce v uzlu stem:[j]. Může být třeba počet výher / počet her. -* stem:[C] je _exploration parameter_, který určuje, jak moc se má algoritmus zaměřovat na prozkoumávání nových uzlů. -* stem:[n] je počet her, ve kterých byl zvolen rodičovský uzel. -* stem:[n_j] je počet her, ve kterých byl zvolen uzel stem:[j]. --- - - -[bibliography] -== Zdroje - -* [[[pa217, 1]]] PA217 AI for Games -* [[[ai-for-games, 2]]] Ian Millington, John Funge: Artificial Intelligence for Games -* [[[steering, 3]]] link:https://slsdo.github.io/steering-behaviors/[Steering Behaviors] -* [[[navmesh, 4]]] link:https://docs.unity3d.com/Manual/nav-NavigationSystem.html[Navigation System in Unity] -* [[[astar, 5]]] link:https://www.redblobgames.com/pathfinding/a-star/introduction.html[Introduction to the A* Algorithm] -* [[[civ5, 6]]] link:https://store.steampowered.com/app/8930/Sid_Meiers_Civilization_V/[Sid Meier's Civilization V] -* [[[monte-carlo, 7]]] link:https://en.wikipedia.org/wiki/Monte_Carlo_method[Wikipedia: Monte Carlo method] -* [[[mcts, 8]]] link:https://en.wikipedia.org/wiki/Monte_Carlo_tree_search[Wikipedia: Monte Carlo tree search] -* [[[ida-star, 9]]] link:https://en.wikipedia.org/wiki/Iterative_deepening_A*[Wikipedia: Iterative deepening A*] +- [[[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*) diff --git a/szmgr/VPH07_gpu_rendering.md b/szmgr/VPH07_gpu_rendering.md index f599ceb..2b10236 100644 --- a/szmgr/VPH07_gpu_rendering.md +++ b/szmgr/VPH07_gpu_rendering.md @@ -1,389 +1,337 @@ -= Renderování s využitím GPU (2023) -:url: ./renderovani-s-vyuzitim-gpu/ -:page-group: vph -:page-order: VPH07 +--- +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! -WARNING: Tato otázka zatím nebyla aktualizována. Nová varze obsahuje pár termínů navíc! +
📌 NOTE
-[NOTE] -==== Principy OpenGL, souřadnicové systémy (prostor světa, prostor kamery, prostor objektů), typy shaderů a jejich použití (vertex, fragment, compute, teselační). Technika stínových map. Principy odloženého stínování a jejich použití. Efekty prostoru obrazu (anti-alias, ambientní okluze). _PV227_ -==== - -OpenGL:: -API pro (nejen) vykreslování grafiky na GPU. -+ -[quote, Khronos] -____ -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. -____ -+ -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 -image::./img/vph07_switchboard.jpg[width=500rem] - -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 link:../modelovani-a-projekce/[Modelování a projekce]. - -.Coordinate Systems <> -image::./img/vph07_coordinate_systems.png[width=100%] - -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: <> -+ -[%header, cols=5] -|=== -| Editor -| Handedness -| stem:[X] -| stem:[Y] -| stem:[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 (stem:[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 (stem:[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 (stem:[P]). Ta nám umožňuje objekt nejen posunout ale i otočit a změnit jeho měřítko. <> -+ -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í stem:[w]). -+ -V OpenGL je to kostka stem:[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 stem:[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 stem:[(0, 0)]. <> - -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 stem:[Z] použitím projekční matice (stem:[P]). <> V OpenGL tedy platí: -+ -[%header, cols="1,2,1,1,2"] -|=== -| Space -| Handedness -| stem:[X] -| stem:[Y] -| stem:[Z] - -| _Local_ -| záleží na modelu -| -- -| -- -| -- - -| _World_ -| typicky _right-handed_ -| doprava -| nahoru -| [.underline]#*dozadu*# - -| _View_ -| typicky _right-handed_ -| doprava -| nahoru -| [.underline]#*dozadu*# (*do* kamery) - -| _Clip_ -| _left-handed_ -| doprava -| nahoru -| *dopředu* - -| _NDC_ -| _left-handed_ -| doprava -| nahoru -| *dopředu* - -| _Window_ -| _left-handed_ -| doprava -| nahoru -| *dopředu* -|=== -+ -TIP: Fun-fact: ve Vulkanu je NDC stem:[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 stem:[(-1.0, -1.0, 0.0)] je vlevo *nahoře*, kdežto v OpenGL je vlevo *dole*. <> - -== Pipeline (typy shaderů) - -Při zvolání `glDraw*` se používá OpenGL pipeline, která se skládá z několika fází: <> - -.Diagram of the Rendering Pipeline <> -image::./img/vph07_pipeline.png[] - -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ě: <> -+ -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: -+ -[stem] -++++ -(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: -+ -[source, cpp] ----- -void glViewport(GLint x, GLint y, GLsizei width, GLsizei height); -void glDepthRange(GLdouble nearVal, GLdouble farVal); -void glDepthRangef(GLfloat nearVal, GLfloat farVal); ----- -+ -[stem] -++++ -\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. + +
+ +- **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** + + ![width=500rem](./img/vph07_switchboard.jpg) + +- **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)** + +![width=100%](./img/vph07_coordinate_systems.png) + +- **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)** + +![vph07_pipeline](./img/vph07_pipeline.png) + +- **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. +- **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 +## Shadow mapy -IMPORTANT: Renderování stínů se věnuje také otázka link:../pokrocila-pocitacova-grafika/[Pokročilá počítačová grafika]. +**❗ 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 -.. Transformuj aktuální pixel do light-space souřadnic. -.. Porovnej aktuální hloubku s hloubkou v shadow mapě. -.. Změň osvětlení na základě porovnání. --- - -.The Shadow Mapping Depth Comparison <> -image::./img/vph07_shadow_maps.jpg[width=500rem] - --- -* 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). -+ -image::./img/vph07_shadow_acne.png[width=500rem] - -Peter Panning:: -Když to s tím biasem přeženeme a objekty se začnou vznášet. -+ -[quote, Učitel, Vyšetřování ztráty třídní knihy (1967)] -____ -No tak, trošku jsem si zapřeháněl. -____ - -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. -+ -image::./img/vph07_cascaded_shadow_maps.png[width=500rem] - -Soft shadow maps -- Percentage-Closer Filtering (PCF):: -Rozmazává stíny uniformě fixním kernelem. <> -+ -image::./img/vph07_soft_shadows_pcf.png[width=500rem] - -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. <> -+ -[stem] -++++ -w_\text{penumbra} = \frac{p_z^s - z_\text{avg}}{z_\text{avg}} w_\text{light} -++++ -+ -image::./img/vph07_soft_shadows_pcss.png[width=500rem] - - -== 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. <> + 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)** + +![width=500rem](./img/vph07_shadow_maps.jpg) + +- 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). + + ![width=500rem](./img/vph07_shadow_acne.png) + +- **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. + + ![width=500rem](./img/vph07_cascaded_shadow_maps.png) + +- **Soft shadow maps -- Percentage-Closer Filtering (PCF)**\ + Rozmazává stíny uniformě fixním kernelem. [pa010-2021](#pa010-2021) + + ![width=500rem](./img/vph07_soft_shadows_pcf.png) + +- **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} + ``` + + ![width=500rem](./img/vph07_soft_shadows_pcss.png) + +## 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. -image::./img/vph07_deferred_shading.png[] +![vph07_deferred_shading](./img/vph07_deferred_shading.png) + +
❗ IMPORTANT
-[IMPORTANT] -==== Výhody: -* osvětlení je počítáno jen jednou pro každý pixel, -* můžeme mít více světel, -* vyhodnocujeme méně různých kombinací materiálů a světel, -* hodí se i na další post-process efekty. -==== +- osvětlení je počítáno jen jednou pro každý pixel, +- můžeme mít více světel, +- vyhodnocujeme méně různých kombinací materiálů a světel, +- hodí se i na další post-process efekty. +
+ +
⚠️ WARNING
-[WARNING] -==== Nevýhody: -* vzdáváme se multisamplingu (resp. musíme nejprve použít edge detection, aby multisampling fungoval správně), -* ztěžuje implementaci průhledných materiálů, -* vyžaduje více paměti, -* materiály nesmí být příliš komplikované kvůli omezeným možnostem paměti. -==== +- vzdáváme se multisamplingu (resp. musíme nejprve použít edge detection, aby multisampling fungoval správně), +- ztěžuje implementaci průhledných materiálů, +- vyžaduje více paměti, +- materiály nesmí být příliš komplikované kvůli omezeným možnostem paměti. +
+## Screen space effects / efekty prostoru obrazu -== Screen space effects / efekty prostoru obrazu +### Anti-aliasing -=== 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:: -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 <> -image::./img/vph07_aliasing.png[width=500rem] + **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. + ![width=500rem](./img/vph07_aliasing.png) -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ů. +- **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. -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 <> -image::./img/vph07_msaa.png[width=500rem] + **MSAA [anti-aliasing](#anti-aliasing)** -=== Ambient occlusion + ![width=500rem](./img/vph07_msaa.png) + +### 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. -.link:https://www.nvidia.com/en-gb/geforce/technologies/hbao-plus/technology/[NVidia HBAO+] -image::./img/vph07_ambient_occlusion.jpg[width=500rem] - -Screen-Space Ambient Occlusion (SSAO):: -Dívá se na okolí daného pixelu (v G-bufferu) a odhaduje tak jeho okluzi. -+ -.SSAO <> -image::./img/vph07_ssao.png[width=500rem] - -[bibliography] -== Zdroje - -* [[[pipeline,1]]] link:https://www.khronos.org/opengl/wiki/Rendering_Pipeline_Overview[Rendering Pipeline Overview] -* [[[post-process,2]]] link:https://www.khronos.org/opengl/wiki/Vertex_Post-Processing[Vertex Post-Processing] -* [[[coordinate-systems,3]]] link:https://learnopengl.com/Getting-started/Coordinate-Systems[LearnOpenGL: Coordinate Systems] -* [[[sw-coordinates,4]]] link:https://www.soft8soft.com/wiki/index.php/Coordinate_Systems[Verge3D Wiki: Coordinate Systems] -* [[[viewport,5]]] link:https://registry.khronos.org/OpenGL-Refpages/gl4/html/glViewport.xhtml[`glViewport`] -* [[[depth-range,6]]] link:https://registry.khronos.org/OpenGL-Refpages/gl4/html/glDepthRange.xhtml[`glDepthRange`] -* [[[vulkan-coords,7]]] link:http://anki3d.org/vulkan-coordinate-system/[Vulkan's coordinate system] -* [[[pv227,8]]] link:https://is.muni.cz/auth/el/fi/podzim2022/PV227/[PV227 GPU Rendering (podzim 2022)] -* [[[anti-aliasing,9]]] link:https://learnopengl.com/Advanced-OpenGL/Anti-Aliasing[LearnOpenGL: Anti-Aliasing] -* [[[ambient-occlusion,10]]] link:https://en.wikipedia.org/wiki/Ambient_occlusion[Wikipedia: Ambient occlusion] -* [[[ssao,11]]] link:https://learnopengl.com/Advanced-Lighting/SSAO[LearnOpenGL: SSAO] -* [[[shadow-maps,12]]] link:https://developer.download.nvidia.com/CgTutorial/cg_tutorial_chapter09.html[The Cg Tutorial: Shadow Mapping] -* [[[pa010-2021,13]]] Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021) - -== Další zdroje - -* link:https://stackoverflow.com/questions/4124041/is-opengl-coordinate-system-left-handed-or-right-handed[Is OpenGL coordinate system left-handed or right-handed?] -* link:https://learn.microsoft.com/en-us/windows/win32/dxtecharts/cascaded-shadow-maps[Cascaded Shadow Maps] -* link:https://learn.microsoft.com/en-us/windows/win32/dxtecharts/common-techniques-to-improve-shadow-depth-maps[Common Techniques to Improve Shadow Depth Maps] +**[NVidia HBAO+](https://www.nvidia.com/en-gb/geforce/technologies/hbao-plus/technology/)** + +![width=500rem](./img/vph07_ambient_occlusion.jpg) + +- **Screen-Space Ambient Occlusion (SSAO)**\ + Dívá se na okolí daného pixelu (v G-bufferu) a odhaduje tak jeho okluzi. + + **SSAO [ssao](#ssao)** + + ![width=500rem](./img/vph07_ssao.png) + +## 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) diff --git a/szmgr/VPH08_modelovani_3d_postav.md b/szmgr/VPH08_modelovani_3d_postav.md index 249098e..cc54f54 100644 --- a/szmgr/VPH08_modelovani_3d_postav.md +++ b/szmgr/VPH08_modelovani_3d_postav.md @@ -1,207 +1,190 @@ -= Modelování 3D postav (2023) -:url: ./modelovani-3d-postav/ -:page-group: vph -:page-order: VPH08 +--- +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! +**⚠️ WARNING**\ +Tato otázka zatím nebyla aktualizována. Nová varze obsahuje pár věcí navíc! + +
📌 NOTE
-[NOTE] -==== 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_ -==== - -Model:: -Model je komplikované slovo s mnoha významy: -+ -[quote, Mirriam-Webster] -____ -*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 +- **Model**\ + Model je komplikované slovo s mnoha významy: -5. an example for imitation or emulation + > **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 -6. one who is employed to display clothes or other merchandise + 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. -7. a person or thing that serves as a pattern for an artist + -*especially*: one who poses for an artist +- **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). -8. version + Vývojáři často zaměňují "postava" a "model". -9. a description or analogy used to help visualize something (such as an atom) that cannot be directly observed +- **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. -10. structural design +## Mnohoúhelníkové sítě -11. an organism whose appearance a mimic imitates +- **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í. -12. animal model + Bývájí výsledkem **sculptingu** v programech jako je ZBrush či Mudbox. -13. (dialectal british): copy, image + **Arachnid humanoid bust by [Alexander Tobler](https://yeaaa.artstation.com/projects/zRW1L)** -14. (obsolete): a set of plans for a building -____ -+ -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. + ![width=500rem](./img/vph08_high_poly_mesh.jpg) -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". +- **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. -Avatar:: -Grafická reprezentace uživatele či uživatelovy postavy. <> Ve hrách je typicky implementován skrze 3D mesh (obsažený v modelu) či 2D sprite obohacený o animace, collidery, apod. + **Triceratops by [Base Mesh Store](https://www.artstation.com/artwork/EVzXO4)** + ![width=500rem](./img/vph08_low_poly_mesh.jpg) -== Mnohoúhelníkové sítě +- **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. -Polygon:: -Mnohoúhelník. + **Low Poly Worlds by [Pavel Novák](https://www.behance.net/gallery/89934319/Low-Poly-Worlds/modules/521713751)** -(Polygon) mesh:: -Mnohoúhelníková síť. + ![width=500rem](./img/vph08_low_poly.png) -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 link:https://yeaaa.artstation.com/projects/zRW1L[Alexander Tobler] -image::./img/vph08_high_poly_mesh.jpg[width=500rem] +## Topologie a modifikace -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 link:https://www.artstation.com/artwork/EVzXO4[Base Mesh Store] -image::./img/vph08_low_poly_mesh.jpg[width=500rem] +**💡 TIP**\ +Pro základní topologické pojmy viz [3D modelování a datové struktury](../3d-modelovani-a-datove-struktury/). -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 link:https://www.behance.net/gallery/89934319/Low-Poly-Worlds/modules/521713751[Pavel Novák] -image::./img/vph08_low_poly.png[width=500rem] +- **Meshflow**\ + Logické uspořádání hran a polygonů v mnohoúhelníkové síti. -== Topologie a modifikace + **📌 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_. -TIP: Pro základní topologické pojmy viz link:../3d-modelovani-a-datove-struktury/[3D modelování a datové struktury]. +- **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) -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_. + 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_. -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. + **Flowing edge loops and good topology are crucial for rigging and animation [organic](#organic)** -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ů. <> -+ -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 <> -image::./img/vph08_organic_modeling.jpg[width=500rem] + ![width=500rem](./img/vph08_organic_modeling.jpg) -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í. <> +- **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) -Box modeling:: -Proces, kdy začneme od link:https://www.youtube.com/watch?v=SDeVyxtdSUk[default cube], subdividneme ji a pokračujeme odtamtaď. <> - -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. <> +## 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). -== Textury +**📌 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/). -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). +- **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. -NOTE: Typy map souvisí s _physically based rendering_ (PBR), kterému se částečně věnuje otázka link:../pokrocila-pocitacova-grafika/[Pokročilá počítačová grafika]. + **Result of unwrapping Suzanne [uv-unwrap](#uv-unwrap)** -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 <> -image::./img/vph08_uv_unwrapping.png[width=500rem] + ![width=500rem](./img/vph08_uv_unwrapping.png) -Diffuse / albedo map:: -Základní barva modelu. +- **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. -Detail map:: -Detaily, které mají být na modelu vidět zblízka. + **A normal mapped model, the mesh without the map, and the normal map alone (by [Eric Chadwick](https://ericchadwick.com/))** -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. + ![width=100%](./img/vph08_normal_map.jpg) -Bump / displacement / height map:: -Detaily na povrchu. Typicky se používá dohromady s teselací. +- **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) -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 link:https://ericchadwick.com/[Eric Chadwick]) -image::./img/vph08_normal_map.jpg[width=100%] +## Kostra modelu -Metallic / roughness map:: -"Kovové" odlesky v daném místě modelu. +- **Kostra / skeleton / rig**\ + Hierarchická struktura kostí (bones), jenž popisují, kde je možné model ohnout a animovat. -Light map:: -Zapečené statické osvětlení. Typicky se týká spíš celých scén než postav. + **Rig of Atlas from Portal 2 by Oliver Simmonet** -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. <> + ![width=500rem](./img/vph08_rigging.webp) -== Kostra modelu +- **(Skeletal) rigging**\ + Proces tvorby kostry. -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 -image::./img/vph08_rigging.webp[width=500rem] + > 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 -(Skeletal) rigging:: -Proces tvorby kostry. -+ -[quote, Josh Petty] -____ -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. -____ +- **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í. -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. <> + **T-pose by [vkstudio](https://free3d.com/3d-model/male-body-base-mesh-in-3-poses-with-detailed-head-and-limbs-3060.html)** -Inverse kinematics (IK):: -Animujeme jen koncové kosti. Pohyb rodičovských kostí je dopočítán. Klouby se hýbou po přímkách. <> + ![width=300](./img/vph08_tpose.jpg) -T-pose / reference pose:: -Defaultní póza pro charakter při riggování. -+ -.T-pose by link:https://free3d.com/3d-model/male-body-base-mesh-in-3-poses-with-detailed-head-and-limbs-3060.html[vkstudio] -image::./img/vph08_tpose.jpg[width=300] +- **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. -Skinning:: -Úprava kostry tak, aby se povrch modelu správně deformoval při animaci. <> Například v Blenderu se skinning dá provést automaticky nebo nastavením _envelopes_ -- objemů obsahujících ovlivněné vertexy -- a jejich vah. -[bibliography] -== Zdroje +## Zdroje -* [[[avatar,1]]] https://en.wikipedia.org/wiki/Avatar_(computing) -* [[[vv036-2023,2]]] link:https://is.muni.cz/auth/el/fi/jaro2023/VV036/[VV036 3D Character Modeling (jaro 2023)] -* [[[quads,3]]] link:https://computergraphics.stackexchange.com/questions/5465/why-are-quads-used-in-filmmaking-and-triangle-in-gaming[Why are quads used in filmmaking and triangle in gaming?] -* [[[organic,4]]] link:https://www.creativebloq.com/tips-and-tricks-organic-modelling-7123070[Tips and tricks for organic modelling] -* [[[texture-baking,5]]] link:http://wiki.polycount.com/wiki/Texture_Baking[Texture Baking] -* [[[fk-ik,6]]] link:https://www.youtube.com/watch?v=0a9qIj7kwiA[FK and IK Explained - Which One to Use and When?] -* [[[envelopes,7]]] link:https://docs.blender.org/manual/en/latest/animation/armatures/bones/properties/deform.html[Blender: Deform] -* [[[uv-unwrap,8]]] link:https://docs.blender.org/manual/en/2.79/editors/uv_image/uv/editing/unwrapping/mapping_types.html[Blender: Unwrapping > Mapping Types] +- [[[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 +## Další zdroje -* link:https://topologyguides.com/manipulating-edge-poles[Moving and Manipulating Edge Poles] +- [Moving and Manipulating Edge Poles](https://topologyguides.com/manipulating-edge-poles) diff --git a/szmgr/guidelines.md b/szmgr/guidelines.md index dfcf40a..ab9edd3 100644 --- a/szmgr/guidelines.md +++ b/szmgr/guidelines.md @@ -1,26 +1,23 @@ -= Guidelines +--- +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. +- **_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. diff --git a/szmgr/index.md b/szmgr/index.md index 862be0f..24d3437 100644 --- a/szmgr/index.md +++ b/szmgr/index.md @@ -1,105 +1,89 @@ -= Magisterské státnice 2024 +--- +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:: -link:https://www.fi.muni.cz/studies/fe-mgr/vizi2018.html[VIZI od 2018] - -IV003 Algoritmy a datové struktury II:: -* link:https://is.muni.cz/auth/el/fi/jaro2023/IV003/index.qwarp[Jaro 2023] -* link:https://is.muni.cz/auth/el/fi/jaro2021/IV003/index.qwarp[Jaro 2021] - -PA215 Game Design I:: -* https://is.muni.cz/auth/el/fi/podzim2022/PA215/index.qwarp[Podzim 2022] -* https://is.muni.cz/auth/el/fi/podzim2021/PA215/index.qwarp[Podzim 2021] -* https://is.muni.cz/auth/el/fi/podzim2019/PA215/um/[Podzim 2019] -+ -TIP: Odpovědi na některé podotázky jsou jen ve starších materiálech. - -PA216 Game Design II:: -* https://is.muni.cz/auth/el/fi/jaro2023/PA216/index.qwarp[Jaro 2023] -* https://is.muni.cz/auth/el/fi/jaro2020/PA216/index.qwarp[Jaro 2020] - -PV255 Game Development I:: -* https://is.muni.cz/auth/el/fi/podzim2022/PV255/um/[Podzim 2022] -* https://www.fi.muni.cz/~xchmeli1/PV255/materials.cgi[2019 a starší] - -PA010 Intermediate Computer Graphics:: -* https://is.muni.cz/auth/el/fi/podzim2020/PA010/[Podzim 2020] - -PA213 Advanced Computer Graphics:: -* https://is.muni.cz/auth/el/fi/jaro2022/PA213/[Jaro 2022] - -VV035 3D Modeling:: -* https://is.muni.cz/auth/el/fi/podzim2021/VV035/[Podzim 2021] -* https://is.muni.cz/auth/el/fi/podzim2020/VV035/[Podzim 2020] -* https://github.com/kiraacorsac/VV035-blender-study-materials[Materiály od @kiraacorsac] - -VV036 3D Character Modeling:: -* https://is.muni.cz/auth/el/fi/jaro2023/VV036/[Jaro 2023] -* https://is.muni.cz/th/nsvk0/[Tomáš Mádr: Tvorba herního charakteru] - -PV227 GPU Rendering:: -* https://is.muni.cz/auth/el/fi/podzim2022/PV227/[Podzim 2022] - -PA217 AI for Games:: -* https://is.muni.cz/auth/el/fi/jaro2021/PA217/[Jaro 2021] - -PV021 Neural Networks:: -* https://is.muni.cz/auth/el/fi/podzim2022/PV021/[Podzim 2022] - -IB000 Matematické základy informatiky:: -* https://is.muni.cz/auth/el/fi/podzim2022/IB000/[Podzim 2022] - -IB002 Algoritmy a datové struktury I:: -* https://is.muni.cz/auth/el/fi/jaro2020/IB002/[Jaro 2020] - -MA018 Numerical Methods:: -* https://is.muni.cz/auth/el/fi/podzim2019/MA018/[Podzim 2019] - -PB130 Úvod do digitálního zpracování obrazu:: -* https://is.muni.cz/auth/el/fi/podzim2022/PB130/[Podzim 2022] - -PV131 Digitální zpracování obrazu:: -* https://is.muni.cz/auth/el/fi/jaro2023/PV131/[Jaro 2023] - -Státnicové poznámky ostatních:: -* link:https://hackmd.io/@fi-muni-viz-2022[@xholubec, @megikej, @karelch, ...] -** link:https://hackmd.io/7JoUfj1rQWO_0euDkWktQQ[Algoritmy a datové struktury] -** link:https://hackmd.io/@fi-muni-viz-2022/HkaIknlhF[Numerické metody] -** link:https://hackmd.io/_7a3hiIPR6Swq8rXUrijgw[Statistika] -** link:https://hackmd.io/@fi-muni-viz-2022/H16Jenent[3D modelování a datové struktury] -** link:https://hackmd.io/@fi-muni-viz-2022/Hk94ehehF[Křivky a povrchy] -** link:https://hackmd.io/Qh0d2P9iTbqli9ZcRMKK1g[Strojové učení] -** link:https://hackmd.io/j26mWx8USFqA5Zcm9GFHCA[Grafy a grafové algoritmy] -** link:https://hackmd.io/@fi-muni-viz-2022/Bkp5fnx2t[Modelování a projekce] -** link:https://hackmd.io/@fi-muni-viz-2022/SywCznl2t[Zpracování rastrového obrazu] -** link:https://hackmd.io/@fi-muni-viz-2022/ry_Q73l3K[Analýza rastrového obrazu] - -* link:https://github.com/Darkyenus/FI-MUNI-VIZI/wiki/[Honza Polák] - -* GDSTAT (Adam Šufliarsky, Jan Breburda) -** link:https://hackmd.io/@lulz/ry4djbfYc[Pokročilá počítačová grafika] -** link:https://hackmd.io/@lulz/rJjkOSfK9[Grafické a fyzikální principy] -** link:https://hackmd.io/@lulz/SJoinimt5[Herní design I] -** link:https://hackmd.io/@lulz/ByeK7HBd5[Herní design II] -** link:https://hackmd.io/@lulz/BJlt7BB_5[Vývoj her] -** link:https://hackmd.io/@lulz/HybtXHHu9[Umělá inteligence v počítačových hrách] -** link:https://hackmd.io/@lulz/B1IjhIGtq[Renderování s využitím GPU] -** link:https://hackmd.io/@lulz/SJvttrmK5[Modelování 3D postav] - -Další moje relevantní poznámky:: -* link:/pa010/[PA010 Intermediate Computer Graphics] -* link:/mv013/[MV013 Statistics for Computer Science] -* link:/iv003/[IV003 Algoritmy a datové struktury II] -* link:/pa217/[PA217 AI for Games] -* link:/pv021/[PV021 Neural Networks] -* link:/szb/[Bakalářské státnice 2020] - -Meta:: -* link:./guidelines/[Guidelines pro psaní poznámek] +- **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/) --- -[.text-center] -**NEPROPADEJTE PANICE** +**_NEPROPADEJTE PANICE_** From cd88b763fa5089cc61f3c2e05803037cc3c554b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Fri, 6 Jun 2025 23:38:38 +0200 Subject: [PATCH 04/44] Fix tables --- szmgr/VPH07_gpu_rendering.md | 48 ++++++++++++------------------------ 1 file changed, 16 insertions(+), 32 deletions(-) diff --git a/szmgr/VPH07_gpu_rendering.md b/szmgr/VPH07_gpu_rendering.md index 2b10236..23b1f19 100644 --- a/szmgr/VPH07_gpu_rendering.md +++ b/szmgr/VPH07_gpu_rendering.md @@ -49,27 +49,11 @@ Tahle část otázky má značný překryv s otázkou [Modelování a projekce]( - **Model space / local space / prostor objektu**\ Každý vykreslený objekt má svůj lokální souřadnicový prostor daný editorem, ve kterém byl vytvořen, nastavením exportu a formátem, ve kterém byl vyexportován: [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 | + | 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í. @@ -104,17 +88,17 @@ Tahle část otázky má značný překryv s otázkou [Modelování a projekce]( - **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) + | 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_ | _left-handed_ | doprava | nahoru | **dopředu** | + + > [!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ů) From 8ed72341891edab92eb09ef83d3be611d9c463df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Sat, 7 Jun 2025 00:22:34 +0200 Subject: [PATCH 05/44] Transform callouts to GH flavor --- szmgr/PGV01_zaklady_vizualizace.md | 16 ++- szmgr/PGV02_metody_vizualizace.md | 16 ++- szmgr/PGV03_zaklady_pocitatcove_grafiky.md | 16 ++- szmgr/PGV04_geometricke_algoritmy.md | 16 ++- szmgr/PGV05_deleni_prostoru_a_sceny.md | 10 +- szmgr/PGV06_vykreslovani_objemovych_dat.md | 16 ++- szmgr/PGV07_modely_osvetleni.md | 16 ++- szmgr/PGV08_real_time_rendering.md | 14 ++- szmgr/PGV09_minimalizace_energie.md | 10 +- szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md | 10 +- szmgr/PGV_zpracovani_obrazu_intro.md | 5 +- szmgr/SZP01_algoritmy.md | 54 +++++------ szmgr/SZP02_numericke_metody.md | 22 ++--- szmgr/SZP03_statistika.md | 53 +++++----- szmgr/SZP04_3d_modelovani.md | 97 +++++++++---------- szmgr/SZP05_krivky_a_povrchy.md | 42 ++++---- szmgr/SZP06_strojove_uceni.md | 38 ++++---- szmgr/SZP07_grafy.md | 38 ++++---- szmgr/SZP09_zpracovani_obrazu.md | 61 +++++------- szmgr/SZP10_analyza_obrazu.md | 26 +++-- .../VPH01_graficke_principy_ve_vyvoji_her.md | 18 ++-- szmgr/VPH01_pokrocila_grafika.md | 22 ++--- .../VPH02_fyzikalni_principy_ve_vyvoji_her.md | 10 +- szmgr/VPH02_graficke_a_fyzikalni_principy.md | 30 +++--- szmgr/VPH03_herni_design_i.md | 16 +-- szmgr/VPH04_herni_design_ii.md | 46 ++++----- szmgr/VPH05_vyvoj_her.md | 26 +++-- szmgr/VPH06_ai_ve_hrach.md | 14 ++- szmgr/VPH07_gpu_rendering.md | 60 ++++++------ szmgr/VPH08_modelovani_3d_postav.md | 26 +++-- szmgr/index.md | 4 +- 31 files changed, 378 insertions(+), 470 deletions(-) diff --git a/szmgr/PGV01_zaklady_vizualizace.md b/szmgr/PGV01_zaklady_vizualizace.md index 21b1c89..1a742a7 100644 --- a/szmgr/PGV01_zaklady_vizualizace.md +++ b/szmgr/PGV01_zaklady_vizualizace.md @@ -3,13 +3,11 @@ title: "Základy vizualizace" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
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". @@ -89,11 +87,9 @@ Někdy se přidává k základním 7 vizuálním proměnným. Lze ho připojit k ## Základní vizualizační techniky prostorových dat -
💡 TIP
- -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í. +> [!TIP] +> 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í. -
### 0D (neprostorová) data diff --git a/szmgr/PGV02_metody_vizualizace.md b/szmgr/PGV02_metody_vizualizace.md index 1a1f115..6684f1d 100644 --- a/szmgr/PGV02_metody_vizualizace.md +++ b/szmgr/PGV02_metody_vizualizace.md @@ -3,13 +3,11 @@ title: "Metody vizualizace" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
## Vizualizace multidimenzionálních dat @@ -80,11 +78,9 @@ Node-link diagram, Tree (Klasické zobrazení), Radial Tree (Sunburst, ale strom Tyto interakce můžeme aplikovat na různé operandy. Operand interakce je prostor, na který interakci aplikujeme. -
💡 TIP
- -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)) +> [!TIP] +> 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)) -
### Techniky pro prostor obrazovky (Pixely) diff --git a/szmgr/PGV03_zaklady_pocitatcove_grafiky.md b/szmgr/PGV03_zaklady_pocitatcove_grafiky.md index f492e36..fe5505f 100644 --- a/szmgr/PGV03_zaklady_pocitatcove_grafiky.md +++ b/szmgr/PGV03_zaklady_pocitatcove_grafiky.md @@ -3,13 +3,11 @@ title: "Základy počítačové grafiky" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
## OpenGL blokový diagram @@ -370,11 +368,9 @@ Výhodami syntetizovaných textur je: - dobrá návaznost na hranách geometrie, pokud syntetizujeme 3D texturu - parametrizovatelnost -
📌 NOTE
- -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). +> [!NOTE] +> 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). -
## Zdroje diff --git a/szmgr/PGV04_geometricke_algoritmy.md b/szmgr/PGV04_geometricke_algoritmy.md index df53fc3..1ece134 100644 --- a/szmgr/PGV04_geometricke_algoritmy.md +++ b/szmgr/PGV04_geometricke_algoritmy.md @@ -3,19 +3,15 @@ title: "Geometrické algoritmy" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> 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_ -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_ +> [!TIP] +> 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. -
- -
💡 TIP
- -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. - -
## Konvexní obaly diff --git a/szmgr/PGV05_deleni_prostoru_a_sceny.md b/szmgr/PGV05_deleni_prostoru_a_sceny.md index 95aead3..fe9ae86 100644 --- a/szmgr/PGV05_deleni_prostoru_a_sceny.md +++ b/szmgr/PGV05_deleni_prostoru_a_sceny.md @@ -3,13 +3,11 @@ title: "Techniky dělení prostoru a scény" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
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šší. diff --git a/szmgr/PGV06_vykreslovani_objemovych_dat.md b/szmgr/PGV06_vykreslovani_objemovych_dat.md index 2f7a0e5..f095059 100644 --- a/szmgr/PGV06_vykreslovani_objemovych_dat.md +++ b/szmgr/PGV06_vykreslovani_objemovych_dat.md @@ -3,19 +3,15 @@ title: "Vykreslování objemových dat" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> Rekonstrukce povrchu - kontury, objem, bodový mrak. Algoritmus pochodujících kostek. Přímé vykreslování objemových dat. +>
+> _PB009, PA010, PA213_ -Rekonstrukce povrchu - kontury, objem, bodový mrak. Algoritmus pochodujících kostek. Přímé vykreslování objemových dat. -_PB009, PA010, PA213_ +> [!TIP] +> Většina obsahu převzata z původní otázky VPH01 Pokročilá počítačová grafika -
- -
💡 TIP
- -Většina obsahu převzata z původní otázky VPH01 Pokročilá počítačová grafika - -
## Bodový mrak (point cloud) diff --git a/szmgr/PGV07_modely_osvetleni.md b/szmgr/PGV07_modely_osvetleni.md index 049289b..dc33d67 100644 --- a/szmgr/PGV07_modely_osvetleni.md +++ b/szmgr/PGV07_modely_osvetleni.md @@ -3,13 +3,11 @@ title: "Lokální a globální modely osvětlení" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
- **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ů. @@ -232,11 +230,9 @@ Physically based rendering (PBR) je způsob renderování, který se snaží co ## Image-based lighting (IBL) -
📌 NOTE
- -Tahle část otázky by si možná zasloužila rozšířit, ale bohužel tomu víc nerozumím :D +> [!NOTE] +> Tahle část otázky by si možná zasloužila rozšířit, ale bohužel tomu víc nerozumím :D -
IBL využívá envitornmentálních textur (HDR CubeMap, ...) pro vyhodnocení světla z každého směru scény. diff --git a/szmgr/PGV08_real_time_rendering.md b/szmgr/PGV08_real_time_rendering.md index dd1338c..8f7560a 100644 --- a/szmgr/PGV08_real_time_rendering.md +++ b/szmgr/PGV08_real_time_rendering.md @@ -3,13 +3,11 @@ title: "Vykreslování v reálném čase" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
- **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. @@ -228,8 +226,8 @@ Stíny jsou důležité, jelikož: ![width=500rem](./img/vph01_shadow_maps.png) - **❗ IMPORTANT**\ - Shadow mapám se důkladně věnuje otázka [Renderování s využitím GPU](../renderovani-s-vyuzitim-gpu/) + > [!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. diff --git a/szmgr/PGV09_minimalizace_energie.md b/szmgr/PGV09_minimalizace_energie.md index 0829e77..c2b437e 100644 --- a/szmgr/PGV09_minimalizace_energie.md +++ b/szmgr/PGV09_minimalizace_energie.md @@ -3,13 +3,11 @@ title: "Zpracování obrazu pomocí minimalizace energie" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> Variační filtrování. Aktivní křivky a plochy (geodetický model, Chan-Vese model). Minimalizace pomocí grafových řezů. Variační optický tok. +>
+> _PA166_ -Variační filtrování. Aktivní křivky a plochy (geodetický model, Chan-Vese model). Minimalizace pomocí grafových řezů. Variační optický tok. - -_PA166_ - -
## Variační filtrování diff --git a/szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md b/szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md index 8506d5a..ce69490 100644 --- a/szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md +++ b/szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md @@ -3,13 +3,11 @@ title: "Zpracování obrazu pomocí PDE" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
- **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. diff --git a/szmgr/PGV_zpracovani_obrazu_intro.md b/szmgr/PGV_zpracovani_obrazu_intro.md index ab7e477..68f11ad 100644 --- a/szmgr/PGV_zpracovani_obrazu_intro.md +++ b/szmgr/PGV_zpracovani_obrazu_intro.md @@ -3,10 +3,9 @@ title: Zpracování obrazu - intro description: "TODO" --- -
💡 TIP
+> [!TIP] +> 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) -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) -
* **Gradient $\nabla$**\ Vektorové pole ve směru největšího nárůstu. diff --git a/szmgr/SZP01_algoritmy.md b/szmgr/SZP01_algoritmy.md index 0b21e37..bcea75a 100644 --- a/szmgr/SZP01_algoritmy.md +++ b/szmgr/SZP01_algoritmy.md @@ -3,13 +3,11 @@ title: "Algoritmy a datové struktury" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
## Pokročilé techniky návrhu algoritmů @@ -30,20 +28,18 @@ Konkrétněji, dynamické programování je vhodnou technikou, pokud: - (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ší_. -
💡 TIP
- -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. +> [!TIP] +> 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ů. -Pokud mám $l$ zanořených cyklů, vyřeším nejvíc $n^l$ podproblémů. - -
#### 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). +> [!TIP] +> V pseudokódu se označuje jako $M$ (asi memory), $A$ (asi array), nebo $C$ (asi cache). #### Bottom-up @@ -51,11 +47,9 @@ Rekurze tradičně řeší problém _zeshora_ -- začně celým problémem, kter 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ě. -
📌 NOTE
- -Zjednodušeně jde o to přetransformovat rekurzi na cykly. Pěkný vedlejším efektem je, že je jednodušší určit složitost algoritmu. +> [!NOTE] +> Zjednodušeně jde o to přetransformovat rekurzi na cykly. Pěkný vedlejším efektem je, že je jednodušší určit složitost algoritmu. -
#### Kuchařka @@ -201,8 +195,8 @@ Umožňuje přesnější analýzu časové a prostorové složitosti, protože u **Připomenutí** -**💡 TIP**\ -Viz bakalářská otázka [Korektnost a složitost algoritmu](../../szb/korektnost-a-slozitost-algoritmu/). +> [!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: @@ -260,14 +254,14 @@ 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í. +> [!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ě**! +> [!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á. +> [!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)** @@ -674,11 +668,11 @@ int KnuthMorrisPratt(string text, string pattern) } ``` -**⚠️ WARNING**\ -Nejsem si jistý, že ty indexy v kódu výše mám dobře. +> [!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) +> [!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`. diff --git a/szmgr/SZP02_numericke_metody.md b/szmgr/SZP02_numericke_metody.md index b962cf1..b551f2a 100644 --- a/szmgr/SZP02_numericke_metody.md +++ b/szmgr/SZP02_numericke_metody.md @@ -3,13 +3,11 @@ title: "Numerické metody" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
- **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) @@ -283,16 +281,16 @@ Numerická diferenciace se využívá pro aproximaci differenciálních rovnic ( - **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/). + > [!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". + > [!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) @@ -317,8 +315,8 @@ Numerická diferenciace se využívá pro aproximaci differenciálních rovnic ( 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. + > [!TIP] + > Tečna je tak napodobena sečnou. - **Richardson extrapolation**\ Způsob zlepšení rate of convergence iterativních metod. [richardson](#richardson) diff --git a/szmgr/SZP03_statistika.md b/szmgr/SZP03_statistika.md index 7223c27..cca69e5 100644 --- a/szmgr/SZP03_statistika.md +++ b/szmgr/SZP03_statistika.md @@ -3,18 +3,16 @@ title: "Statistika" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
**Opakování** -**💡 TIP**\ -Viz bakalářské otázky [Kombinatorika a pravděpodobnost](../../szb/kombinatorika-a-pravdepodobnost/) a [Statistika](../../szb/statistika/). +> [!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) @@ -143,8 +141,8 @@ Stejně jako náhodné veličiny popisují jevy, číselné charakteristiky popi - **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) + > [!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. @@ -174,8 +172,8 @@ Jak moc se od sebe prvky liší (nezávisle na konstantním posunutí)? \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) + > [!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}$. @@ -227,8 +225,8 @@ Popisuje chování _výběrového průměru_ pro velké soubory vzorků a umož - **Lévyho-Lindenbergova věta** - **💡 TIP**\ - Zobecnění Moivreovy-Laplacovy věty. + > [!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í: @@ -300,8 +298,8 @@ Popisuje chování _výběrového průměru_ pro velké soubory vzorků a umož > 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) + > [!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. @@ -358,11 +356,11 @@ Máme vzorek velikosti $n$ s výběrovým průměrem $\overline{X}$ a výběrov Ří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] + > Pravděpodobnost je funkce jevů. Likelihood je funkce parametrů modelu. - **📌 NOTE**\ - Likelihood nemusí nutně vracet čísla z intervalu $\lbrack 0, 1 \rbrack$. + > [!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) @@ -402,12 +400,11 @@ Platí presumpce nevinny. Předpokládáme, že člověk zločin nespáchal, dok - _Typ I_: zamítnutí $H_0$, i když je pravdivá -- _false positive_. - _Typ II_: nezamítnutí $H_0$, i když je nepravdivá -- _false negative_. -
📌 NOTE
- - _Positive_ = zamítnutí $H_0$, tedy potvrzení $H_1$. - - _Negative_ = nezamítnutí $H_0$, tedy o $H_1$ nevíme nic. -
+ > [!NOTE] + > _Positive_ = zamítnutí $H_0$, tedy potvrzení $H_1$. + >
+ > _Negative_ = nezamítnutí $H_0$, tedy o $H_1$ nevíme nic. + - **$p$-hodnota (hladina významnosti)**\ Nejmenší hladina významnosti $\alpha$, při které ještě zamítáme $H_0$. [p-value](#p-value) @@ -418,8 +415,8 @@ Platí presumpce nevinny. Předpokládáme, že člověk zločin nespáchal, dok 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$. + > [!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 diff --git a/szmgr/SZP04_3d_modelovani.md b/szmgr/SZP04_3d_modelovani.md index 3dc2cf5..d84e5fd 100644 --- a/szmgr/SZP04_3d_modelovani.md +++ b/szmgr/SZP04_3d_modelovani.md @@ -3,13 +3,11 @@ title: "3D modelování a datové struktury" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
## Mnohoúhelníkové a trojúhelníkové sítě @@ -80,19 +78,17 @@ _PA010_ > > — PA010 -
💡 TIP
- - Podle Wikipedie je _genus_ česky _rod plochy_. -
- -
💡 TIP
- - Je to **maximální** počet těch řezů. + > [!TIP] + > Podle Wikipedie je _genus_ česky _rod plochy_. + - 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í**. - - ![width=500rem](./img/szp04_genus.png) -
+ > [!TIP] + > 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í**. + >
+ > ![width=500rem](./img/szp04_genus.png) + - **Boundary edge loops / rings**\ Edge loops uvnitř stěn, které nejsou vnějšími hranicemi objektu. @@ -116,34 +112,31 @@ _PA010_ \chi(M) = V - E + F - R = 2 \cdot (S - G) \text{ (s děrami)} ``` -
❗ IMPORTANT
- - Pro libovolný mnohostěn (polyhedron) bez děr je $\chi = 2$. -
- -
❗ IMPORTANT
- - 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$. - -
+ > [!IMPORTANT] + > Pro libovolný mnohostěn (polyhedron) bez děr je $\chi = 2$. + + + > [!IMPORTANT] + > 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$. + - **Simplex**\ Nejjednodušší polytop (generalizace mnohoúhelníku, mnohostěnu, atd.). Generalizace trojúhelníku v libovolné dimenzi: @@ -200,8 +193,8 @@ _PA010_ ### Modelování -**❗ IMPORTANT**\ -Tahle sekce má docela průnik s otázkou [Modelování 3D postav](../modelovani-3d-postav/). +> [!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.). @@ -221,8 +214,8 @@ Tahle sekce má docela průnik s otázkou [Modelování 3D postav](../modelovani - **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. + > [!NOTE] + > Zdá se, že $H$ -- components je ekvivalentní $R$ -- rings. Ač Eulerových operátorů se dá zadefinovat mnoho, v praxi stačí: @@ -328,8 +321,8 @@ Tahle sekce má docela průnik s otázkou [Modelování 3D postav](../modelovani ### 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/) +> [!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) diff --git a/szmgr/SZP05_krivky_a_povrchy.md b/szmgr/SZP05_krivky_a_povrchy.md index f492069..4aa9d11 100644 --- a/szmgr/SZP05_krivky_a_povrchy.md +++ b/szmgr/SZP05_krivky_a_povrchy.md @@ -3,13 +3,11 @@ title: "Křivky a povrchy" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
## Druhy reprezentace @@ -47,11 +45,11 @@ 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] +> 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í_. +> [!IMPORTANT] +> Tahle sekce přesahuje do [3D modelování a datové struktury](../3d-modelovani-a-datove-struktury/) -> _Implicitní reprezentace a modelování_. ### Parametrická reprezentace @@ -228,8 +226,8 @@ Je podobná parametrické spojitosti, ale vyžaduje jen "geometrickou" spojitost 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. +> [!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 @@ -381,8 +379,8 @@ Mezi jejich vlastnosti patří: Lze ji definovat pomocí **Cox-de Boorovy** rekurzivní formule: -**💡 TIP**\ -de Boorův algoritmus je generalizací DeCasteljauova algoritmu ale pro B-splajny. +> [!TIP] +> de Boorův algoritmus je generalizací DeCasteljauova algoritmu ale pro B-splajny. ```math \begin{aligned} @@ -412,8 +410,8 @@ Jejich užitečnost spočívá v tom, že libovolný splajn stupně $n$ daný se 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. +> [!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$. @@ -447,8 +445,8 @@ Uzlů je zpravidla víc než $n+1$, protože pak teprve máme víc než jeden B- ![width=400](./img/szp05_coons_basis.png) - **📌 NOTE**\ - Něco ohledně tohohle termínu mi hrozně smrdí. Zdá se, že jediní, kdo používají "coons cubic curve" jsme my a ČVUT. + > [!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 @@ -490,8 +488,8 @@ Interpolační povrch. 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í**. +> [!WARNING] +> Coonsovy pláty jsou **interpolační**, zatímco Coonsovy křivky jsou **aproximační**. - **Bilineární Coonsovy pláty** @@ -622,8 +620,8 @@ Aproximační plochy analogické B-spline křivkám, ale se dvěma parametry. $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) +> [!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ů diff --git a/szmgr/SZP06_strojove_uceni.md b/szmgr/SZP06_strojove_uceni.md index 5a517f5..c72a837 100644 --- a/szmgr/SZP06_strojove_uceni.md +++ b/szmgr/SZP06_strojove_uceni.md @@ -3,16 +3,14 @@ title: "Strojové učení" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
- -**💡 TIP**\ -Velkou část zpracování téhle otázky jsem ukradl [sám sobě](/fi/pv021/). +> [!TIP] +> Velkou část zpracování téhle otázky jsem ukradl [sám sobě](/fi/pv021/). ## Strojové učení a rozpoznávání vzorů @@ -107,8 +105,8 @@ Velkou část zpracování téhle otázky jsem ukradl [sám sobě](/fi/pv021/). - 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$. + > [!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)** @@ -156,8 +154,8 @@ Velkou část zpracování téhle otázky jsem ukradl [sám sobě](/fi/pv021/). ### Trénink -**❗ IMPORTANT**\ -Pro likelihood viz otázka [Statistika](../statistika/). +> [!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_. @@ -243,8 +241,8 @@ w_{ji}^{(t+1)} 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í. +> [!WARNING] +> V případě, že $E$ není squared error, následující výpočet neplatí. ```math \large @@ -278,8 +276,8 @@ V případě, že $E$ není squared error, následující výpočet neplatí. 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/). +> [!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)** @@ -370,8 +368,8 @@ Neuronové sítě, jejichž architektura obsahuje cykly. Tedy výstup v jednom b \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. + > [!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})$: @@ -424,8 +422,8 @@ Neuronové sítě, jejichž architektura obsahuje cykly. Tedy výstup v jednom b \end{aligned} ``` - **💡 TIP**\ - Pokud $\textcolor{red}{\sigma' \cdot W_{k’k}} \not\approx 1$, pak gradient buď vybouchne nebo se ztratí. + > [!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: diff --git a/szmgr/SZP07_grafy.md b/szmgr/SZP07_grafy.md index 6a46913..dad1b8e 100644 --- a/szmgr/SZP07_grafy.md +++ b/szmgr/SZP07_grafy.md @@ -3,16 +3,14 @@ title: "Grafy a grafové algoritmy" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
- -**💡 TIP**\ -Tahle otázka má solidní překryv s bakalářskými otázkami [Grafy](../../szb/grafy/) a [Grafové problémy](../../szb/grafove-problemy/). +> [!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 @@ -174,11 +172,11 @@ 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. +> [!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í. +> [!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) \ @@ -208,8 +206,8 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces - 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/). + > [!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 @@ -283,8 +281,8 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces - 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ší. + > [!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ů** @@ -338,8 +336,8 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces - **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$. + > [!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$. @@ -423,8 +421,8 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces - _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$. + > [!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)$. diff --git a/szmgr/SZP09_zpracovani_obrazu.md b/szmgr/SZP09_zpracovani_obrazu.md index 50a1771..509d44e 100644 --- a/szmgr/SZP09_zpracovani_obrazu.md +++ b/szmgr/SZP09_zpracovani_obrazu.md @@ -3,13 +3,11 @@ title: "Zpracování rastrového obrazu" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
- **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) @@ -149,8 +147,8 @@ Histogram kvantifikuje množství a frekvenci barev obsažených v obraze. Ve st ![width=49%](./img/szp09_histogram_eq_after_01.jpg) ![width=49%](./img/szp09_histogram_eq_after_02.svg) - **📌 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). + > [!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) @@ -194,8 +192,8 @@ Histogram kvantifikuje množství a frekvenci barev obsažených v obraze. Ve st 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. + > [!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)$. @@ -268,8 +266,8 @@ Proces, kdy hledání _hran_ v obraze. Hrana je křivka, podél níž pixely vý - 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/). +> [!IMPORTANT] +> Numerické diferenciaci se věnuje otázka [Numerické metody](../numericke-metody/). ### Podle první derivace (gradientu) @@ -296,10 +294,9 @@ Numerické diferenciaci se věnuje otázka [Numerické metody](../numericke-meto kde $I$ je vstupní obraz. -
📌 NOTE
- - Všimni si podobnosti s Sobelovým operátorem. Jen místo Gaussovského rozmazání používá box filtr. -
+ > [!NOTE] + > Všimni si podobnosti s Sobelovým operátorem. Jen místo Gaussovského rozmazání používá box filtr. + - **Sobelův operátor**\ Aproximuje velikost gradientu pomocí **centrálních** konečných diferencí. Skládá se ze dvou konvolucí s jádry: @@ -429,11 +426,9 @@ Patří sem transformace jako: > > — Nika Kunzová -
💡 TIP
- -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...)_ +> [!TIP] +> 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...)_ -
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) @@ -540,11 +535,11 @@ Samplování je převod spojitého signálu na diskrétní. [sampling](#sampling - 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] + > 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čí. + > [!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) @@ -581,11 +576,9 @@ Patří sem operace jako: ## Vlnková transformace / wavelet transform -
💡 TIP
+> [!TIP] +> 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). -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). - -
- **Vlnka / wavelet**\ Funkce $\psi$, která je omezená v čase. Je to "brief oscillation". [wavelet](#wavelet) @@ -686,11 +679,9 @@ Matematicky vzato, k vysoké korelaci vlnky se signálem (vysokému korelačním ## Houghova transformace -
💡 TIP
- -Super [minutu a půl dlouhé video, co ti řekne úplně všechno](https://www.youtube.com/watch?v=X1DxCPS1iwA). +> [!TIP] +> Super [minutu a půl dlouhé video, co ti řekne úplně všechno](https://www.youtube.com/watch?v=X1DxCPS1iwA). -
Integrální transformace, která identifikuje přímky v obraze. V rozšířené podobě hledá libovolné tvary zadané parametricky. [hough](#hough) @@ -711,11 +702,9 @@ Integrální transformace, která identifikuje přímky v obraze. V rozšířen ## Radonova transformace -
💡 TIP
- -Jako je již tradicí, mám pro vás [video](https://www.youtube.com/watch?v=f0sxjhGHRPo)... +> [!TIP] +> Jako je již tradicí, mám pro vás [video](https://www.youtube.com/watch?v=f0sxjhGHRPo)... -
Integrální transformace, která integruje funkci přes přímky. Tedy rozkládá funkci na hromádku parametrů, které definují přímky. diff --git a/szmgr/SZP10_analyza_obrazu.md b/szmgr/SZP10_analyza_obrazu.md index 8fd9f39..c5e4121 100644 --- a/szmgr/SZP10_analyza_obrazu.md +++ b/szmgr/SZP10_analyza_obrazu.md @@ -3,13 +3,11 @@ title: "Analýza rastrového obrazu" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
- **Typické fáze analýzy obrazu** 1. Předzpracování @@ -57,8 +55,8 @@ Před samotnou segmentací je vhodné obraz předpřipravit. 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í. + > [!IMPORTANT] + > Segmentace je problém nalezení oblastí. CCL je jen jedno z možných řešení. ### Neuronové sítě @@ -164,8 +162,8 @@ Popis objektů je proces, při kterém se počítají vlastnosti segmentovaných - **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/). + > [!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. @@ -213,8 +211,8 @@ Popis objektů je proces, při kterém se počítají vlastnosti segmentovaných ![szp10_provazochodec](./img/szp10_provazochodec.jpg) -**💡 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) +> [!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. @@ -231,8 +229,8 @@ Popis objektů je proces, při kterém se počítají vlastnosti segmentovaných 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/). +> [!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. diff --git a/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md b/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md index c8abf93..aa98a57 100644 --- a/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md +++ b/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md @@ -3,18 +3,16 @@ title: "Grafické principy ve vývoji her (2024)" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
## 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) +> [!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á: @@ -217,8 +215,8 @@ BRDF je řešena pomocí ray tracingu, radiosity, nebo nějakým hybridním ře ![width=300rem](./img/vph02_mipmaps.png) - **💡 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é.) + > [!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: diff --git a/szmgr/VPH01_pokrocila_grafika.md b/szmgr/VPH01_pokrocila_grafika.md index cf8a279..35ffd9d 100644 --- a/szmgr/VPH01_pokrocila_grafika.md +++ b/szmgr/VPH01_pokrocila_grafika.md @@ -3,23 +3,21 @@ 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). +> [!WARNING] +> Tato je stará verze otázky. Nová verze: [Grafické principy ve vývoji her](./VPH01_graficke_principy_ve_vyvoji_her.ad). -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
## 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/). +> [!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ů @@ -348,8 +346,8 @@ Stíny jsou důležité, jelikož: ![width=500rem](./img/vph01_shadow_maps.png) - **❗ IMPORTANT**\ - Shadow mapám se důkladně věnuje otázka [Renderování s využitím GPU](../renderovani-s-vyuzitim-gpu/) + > [!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. diff --git a/szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.md b/szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.md index 8e2270c..246d1c3 100644 --- a/szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.md +++ b/szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.md @@ -3,13 +3,11 @@ title: "Fyzikální principy ve vývoji her (2024)" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
## Fyzikální simulace diff --git a/szmgr/VPH02_graficke_a_fyzikalni_principy.md b/szmgr/VPH02_graficke_a_fyzikalni_principy.md index 1b98c20..262cbf2 100644 --- a/szmgr/VPH02_graficke_a_fyzikalni_principy.md +++ b/szmgr/VPH02_graficke_a_fyzikalni_principy.md @@ -3,21 +3,19 @@ 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). +> [!WARNING] +> Tato je stará verze otázky. Nová verze: [Fyzikální principy ve vývoji her](./VPH02_fyzikalni_principy_ve_vyvoji_her.ad). -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
## 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) +> [!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á: @@ -87,8 +85,8 @@ Poznámky o grayboxingu, iterování, modulárním workflow, atd. jsou z předn ![width=300rem](./img/vph02_mipmaps.png) - **💡 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é.) + > [!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: @@ -141,8 +139,8 @@ Poznámky o grayboxingu, iterování, modulárním workflow, atd. jsou z předn ![width=500rem](./img/vph02_dof.png) - **💡 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) + > [!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ů @@ -223,8 +221,8 @@ Ray tracing jsou techniky, které trasují paprsky světla napříč scénou. ## 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/). +> [!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ší:** diff --git a/szmgr/VPH03_herni_design_i.md b/szmgr/VPH03_herni_design_i.md index b7f8eb0..97b540e 100644 --- a/szmgr/VPH03_herni_design_i.md +++ b/szmgr/VPH03_herni_design_i.md @@ -138,13 +138,13 @@ Games are not experiences, they are artifacts people play with while / to create 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/). +> [!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) +> [!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) @@ -197,8 +197,8 @@ 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/). +> [!IMPORTANT] +> Testováním se více zabývá otázka [Herní design II](../herni-design-ii/). == Game Designer @@ -273,8 +273,8 @@ Zjednodušit a předat informace o tom co fungeje a co ne ostatním. Musí umět == The Core Game Ontology -**📌 NOTE**\ -Ontologie -- disciplína zabývající se bytím a základními pojmy jako je realita, existence, atp. +> [!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) diff --git a/szmgr/VPH04_herni_design_ii.md b/szmgr/VPH04_herni_design_ii.md index 5910504..049458e 100644 --- a/szmgr/VPH04_herni_design_ii.md +++ b/szmgr/VPH04_herni_design_ii.md @@ -3,13 +3,11 @@ title: "Herní design II" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
## Návrh hry @@ -73,8 +71,8 @@ Hry můžou mít různou obtížnost. Ta se dá mnohdy explicitně nastavit v me #### Flow channel -**💡 TIP**\ -Termín, se kterým přišel Mihaly Csikszentmihalyi _[me-high cheek-sent-me-high]_. +> [!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í. @@ -87,8 +85,8 @@ Balanc mezi nudou a přílišnou obtížností. ## Teorie her -**⚠️ WARNING**\ -Game design != Game theory +> [!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) @@ -207,8 +205,8 @@ V emergentním vyprávění je příběh důsledkem toho, že hra je dostatečn - **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 + > [!NOTE] + > Prosumer = producer + consumer ## Tutoriál a onboarding @@ -234,19 +232,17 @@ Jak tutoriál tak onboarding učí hráče, jak hru hrát. Onboarding je širš - Kognitivní (např. paměť, pozornost) - Senzorické (např. zrak, sluch, hmat) -
⚠️ WARNING
- - Pozor na kognitivní overload! -
- -
💡 TIP
- - 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. -
+ > [!WARNING] + > Pozor na kognitivní overload! + + + > [!TIP] + > 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. + - **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. diff --git a/szmgr/VPH05_vyvoj_her.md b/szmgr/VPH05_vyvoj_her.md index 35f474c..7450a8a 100644 --- a/szmgr/VPH05_vyvoj_her.md +++ b/szmgr/VPH05_vyvoj_her.md @@ -3,13 +3,11 @@ title: "Vývoj her" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
## Architektura herního enginu @@ -59,8 +57,8 @@ _Fyzická rozhraní_ jsou všechny možné ovladače, klávesnice, myš, joystic - **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. + > [!NOTE] + > Mechanické klávesnice, které mnohdy taky posílají spojité signály, zdá se nikdo zatím moc nepoužil. ### Virtuální rozhraní @@ -91,8 +89,8 @@ Na _virtuální rozhraní_ si hráč nesáhne. Jsou to všemožná menu, invent ![width=400](./img/vph05_meta_interface.jpg) - **💡 TIP**\ - [Meta](https://about.meta.com) rozhraní != Oculus Quest + > [!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. @@ -330,8 +328,8 @@ Monetizace je proces extrakce finančních prostředků z videoherního, interak 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)? + > [!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. @@ -373,8 +371,8 @@ Serious games se dají dělit podle jejich cíle: 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. + > [!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. diff --git a/szmgr/VPH06_ai_ve_hrach.md b/szmgr/VPH06_ai_ve_hrach.md index 47b20a2..5869354 100644 --- a/szmgr/VPH06_ai_ve_hrach.md +++ b/szmgr/VPH06_ai_ve_hrach.md @@ -3,13 +3,11 @@ title: "Umělá inteligence v počítačových hrách" description: "TODO" --- -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
## Pohyb @@ -313,8 +311,8 @@ Agenti nevidí herní svět stejně jako hráči, vidí ho spíš jako graf s uz Nejprve hledá cestu na vysoké úrovni (mezi clustery), pak v rámci clusteru. -**❗ IMPORTANT**\ -Výhodou je, že zrychluje hledání cest. +> [!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: diff --git a/szmgr/VPH07_gpu_rendering.md b/szmgr/VPH07_gpu_rendering.md index 23b1f19..8a3e7ef 100644 --- a/szmgr/VPH07_gpu_rendering.md +++ b/szmgr/VPH07_gpu_rendering.md @@ -3,16 +3,14 @@ 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! +> [!WARNING] +> Tato otázka zatím nebyla aktualizována. Nová varze obsahuje pár termínů navíc! -
📌 NOTE
+> [!NOTE] +> Principy OpenGL, souřadnicové systémy (prostor světa, prostor kamery, prostor objektů), typy shaderů a jejich použití (vertex, fragment, compute, teselační). Technika stínových map. Principy odloženého stínování a jejich použití. Efekty prostoru obrazu (anti-alias, ambientní okluze). +>
+> _PV227_ -Principy OpenGL, souřadnicové systémy (prostor světa, prostor kamery, prostor objektů), typy shaderů a jejich použití (vertex, fragment, compute, teselační). Technika stínových map. Principy odloženého stínování a jejich použití. Efekty prostoru obrazu (anti-alias, ambientní okluze). - -_PV227_ - -
- **OpenGL**\ API pro (nejen) vykreslování grafiky na GPU. @@ -39,8 +37,8 @@ _PV227_ ## Souřadnicové systémy -**❗ IMPORTANT**\ -Tahle část otázky má značný překryv s otázkou [Modelování a projekce](../modelovani-a-projekce/). +> [!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)** @@ -82,8 +80,8 @@ Tahle část otázky má značný překryv s otázkou [Modelování a projekce]( 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) + > [!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í: @@ -167,8 +165,8 @@ Při zvolání `glDraw*` se používá OpenGL pipeline, která se skládá z ně - 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. + > [!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. @@ -179,8 +177,8 @@ Při zvolání `glDraw*` se používá OpenGL pipeline, která se skládá z ně ## Shadow mapy -**❗ IMPORTANT**\ -Renderování stínů se věnuje také otázka [Pokročilá počítačová grafika](../pokrocila-pocitacova-grafika/). +> [!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 @@ -241,25 +239,23 @@ Tuto techniku použijeme např. když máme ve scéně fakt hodně světel. ![vph07_deferred_shading](./img/vph07_deferred_shading.png) -
❗ IMPORTANT
- -Výhody: - -- osvětlení je počítáno jen jednou pro každý pixel, -- můžeme mít více světel, -- vyhodnocujeme méně různých kombinací materiálů a světel, -- hodí se i na další post-process efekty. -
+> [!IMPORTANT] +> Výhody: +>
+> - osvětlení je počítáno jen jednou pro každý pixel, +> - můžeme mít více světel, +> - vyhodnocujeme méně různých kombinací materiálů a světel, +> - hodí se i na další post-process efekty. -
⚠️ WARNING
-Nevýhody: +> [!WARNING] +> Nevýhody: +>
+> - vzdáváme se multisamplingu (resp. musíme nejprve použít edge detection, aby multisampling fungoval správně), +> - ztěžuje implementaci průhledných materiálů, +> - vyžaduje více paměti, +> - materiály nesmí být příliš komplikované kvůli omezeným možnostem paměti. -- vzdáváme se multisamplingu (resp. musíme nejprve použít edge detection, aby multisampling fungoval správně), -- ztěžuje implementaci průhledných materiálů, -- vyžaduje více paměti, -- materiály nesmí být příliš komplikované kvůli omezeným možnostem paměti. -
## Screen space effects / efekty prostoru obrazu diff --git a/szmgr/VPH08_modelovani_3d_postav.md b/szmgr/VPH08_modelovani_3d_postav.md index cc54f54..b567eac 100644 --- a/szmgr/VPH08_modelovani_3d_postav.md +++ b/szmgr/VPH08_modelovani_3d_postav.md @@ -3,16 +3,14 @@ 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! +> [!WARNING] +> Tato otázka zatím nebyla aktualizována. Nová varze obsahuje pár věcí navíc! -
📌 NOTE
+> [!NOTE] +> 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_ -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_ - -
- **Model**\ Model je komplikované slovo s mnoha významy: @@ -81,14 +79,14 @@ _VV035, VV036_ ## Topologie a modifikace -**💡 TIP**\ -Pro základní topologické pojmy viz [3D modelování a datové struktury](../3d-modelovani-a-datove-struktury/). +> [!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_. + > [!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. @@ -112,8 +110,8 @@ Pro základní topologické pojmy viz [3D modelování a datové struktury](../3 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/). +> [!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. diff --git a/szmgr/index.md b/szmgr/index.md index 24d3437..fc20c4d 100644 --- a/szmgr/index.md +++ b/szmgr/index.md @@ -16,8 +16,8 @@ Poznámky k magisterským státnicím oboru _Vývoj počítačových her_ v čer - [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. + > [!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) From a2b14f51f9b104ab856d81380a99eebeedcc100d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Sat, 7 Jun 2025 00:50:36 +0200 Subject: [PATCH 06/44] Fix links to other SZMGR subjects The other ones are probably still broken --- szmgr/PGV03_zaklady_pocitatcove_grafiky.md | 2 +- szmgr/PGV08_real_time_rendering.md | 2 +- szmgr/PGV09_minimalizace_energie.md | 2 +- szmgr/SZP02_numericke_metody.md | 2 +- szmgr/SZP04_3d_modelovani.md | 4 ++-- szmgr/SZP05_krivky_a_povrchy.md | 2 +- szmgr/SZP06_strojove_uceni.md | 4 ++-- szmgr/SZP07_grafy.md | 2 +- szmgr/SZP08_modelovani_a_projekce.md | 2 +- szmgr/SZP09_zpracovani_obrazu.md | 6 +++--- szmgr/SZP10_analyza_obrazu.md | 4 ++-- szmgr/VPH01_pokrocila_grafika.md | 4 ++-- szmgr/VPH02_graficke_a_fyzikalni_principy.md | 2 +- szmgr/VPH03_herni_design_i.md | 4 ++-- szmgr/VPH07_gpu_rendering.md | 4 ++-- szmgr/VPH08_modelovani_3d_postav.md | 4 ++-- 16 files changed, 25 insertions(+), 25 deletions(-) diff --git a/szmgr/PGV03_zaklady_pocitatcove_grafiky.md b/szmgr/PGV03_zaklady_pocitatcove_grafiky.md index fe5505f..7f8338d 100644 --- a/szmgr/PGV03_zaklady_pocitatcove_grafiky.md +++ b/szmgr/PGV03_zaklady_pocitatcove_grafiky.md @@ -16,7 +16,7 @@ description: "TODO" 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ů +- **_Per-vertex operations_** - operace prováděné nad každým vrcholem - transformace, projekce z [model space do camera space](../szp08_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) diff --git a/szmgr/PGV08_real_time_rendering.md b/szmgr/PGV08_real_time_rendering.md index 8f7560a..a2d6383 100644 --- a/szmgr/PGV08_real_time_rendering.md +++ b/szmgr/PGV08_real_time_rendering.md @@ -227,7 +227,7 @@ Stíny jsou důležité, jelikož: ![width=500rem](./img/vph01_shadow_maps.png) > [!IMPORTANT] - > Shadow mapám se důkladně věnuje otázka [Renderování s využitím GPU](../renderovani-s-vyuzitim-gpu/) + > Shadow mapám se důkladně věnuje otázka [Renderování s využitím GPU](../vph07_gpu_rendering/) - **Shadow volumes**\ Počítá stíny ve 3D. Shadow volume explicitně popisuje objem prostoru ve stínu nějakého polygonu. diff --git a/szmgr/PGV09_minimalizace_energie.md b/szmgr/PGV09_minimalizace_energie.md index c2b437e..341b22e 100644 --- a/szmgr/PGV09_minimalizace_energie.md +++ b/szmgr/PGV09_minimalizace_energie.md @@ -50,7 +50,7 @@ Pro řešení můžeme nyní využít Euler-Lagrangeovy rovnice. Pro funkcionál 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)): +Nyní můžeme hezky vidět vztah k difuznímu filtrování (otázka [PGV10](../pgv10_zpracovani_obrazu_pomoci_pde)): | | | | ------------------------ | ------------------------------------------------------------------------------ | diff --git a/szmgr/SZP02_numericke_metody.md b/szmgr/SZP02_numericke_metody.md index b551f2a..39d4cd5 100644 --- a/szmgr/SZP02_numericke_metody.md +++ b/szmgr/SZP02_numericke_metody.md @@ -282,7 +282,7 @@ Numerická diferenciace se využívá pro aproximaci differenciálních rovnic ( 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/). + > Lagrangeovu interpolaci řeší část otázky [Křivky a povrchy](../szp05_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) diff --git a/szmgr/SZP04_3d_modelovani.md b/szmgr/SZP04_3d_modelovani.md index d84e5fd..515d607 100644 --- a/szmgr/SZP04_3d_modelovani.md +++ b/szmgr/SZP04_3d_modelovani.md @@ -194,7 +194,7 @@ description: "TODO" ### Modelování > [!IMPORTANT] -> Tahle sekce má docela průnik s otázkou [Modelování 3D postav](../modelovani-3d-postav/). +> Tahle sekce má docela průnik s otázkou [Modelování 3D postav](../vph08_modelovani_3d_postav/). - **Boundary representation model (B-rep)**\ Modelování objektů pomocí jejich hranic -- boundaries (hrany, stěny, atd.). @@ -322,7 +322,7 @@ description: "TODO" ### 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/) +> 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](../vph01_pokrocila_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) diff --git a/szmgr/SZP05_krivky_a_povrchy.md b/szmgr/SZP05_krivky_a_povrchy.md index 4aa9d11..a87e48b 100644 --- a/szmgr/SZP05_krivky_a_povrchy.md +++ b/szmgr/SZP05_krivky_a_povrchy.md @@ -49,7 +49,7 @@ Tato rovnice udává množinu bodů, ze které se křivka nebo povrch sestává. > 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í_. +> Tahle sekce přesahuje do [3D modelování a datové struktury](../szp04_3d_modelovani/) -> _Implicitní reprezentace a modelování_. ### Parametrická reprezentace diff --git a/szmgr/SZP06_strojove_uceni.md b/szmgr/SZP06_strojove_uceni.md index c72a837..b64ccc6 100644 --- a/szmgr/SZP06_strojove_uceni.md +++ b/szmgr/SZP06_strojove_uceni.md @@ -155,7 +155,7 @@ description: "TODO" ### Trénink > [!IMPORTANT] -> Pro likelihood viz otázka [Statistika](../statistika/). +> Pro likelihood viz otázka [Statistika](../szp03_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_. @@ -277,7 +277,7 @@ Za předpokladu, že $E$ je squared error, pak: 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/). +> Pro konvoluci viz otázka [Zpracování rastrového obrazu](../szp09_zpracovani_obrazu/). **Typical CNN by [Aphex34](https://commons.wikimedia.org/w/index.php?curid=45679374)** diff --git a/szmgr/SZP07_grafy.md b/szmgr/SZP07_grafy.md index dad1b8e..1e59f90 100644 --- a/szmgr/SZP07_grafy.md +++ b/szmgr/SZP07_grafy.md @@ -207,7 +207,7 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces - 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/). + > 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](../vph06_ai_ve_hrach/). ## Kostry diff --git a/szmgr/SZP08_modelovani_a_projekce.md b/szmgr/SZP08_modelovani_a_projekce.md index 411716b..58a0518 100644 --- a/szmgr/SZP08_modelovani_a_projekce.md +++ b/szmgr/SZP08_modelovani_a_projekce.md @@ -32,7 +32,7 @@ description: A guide in my new Starlight docs site. ## MVP matice > [!IMPORTANT] -> Pro implementaci v OpenGL viz [Renderování s využitím GPU](../renderovani-s-vyuzitim-gpu/). +> Pro implementaci v OpenGL viz [Renderování s využitím GPU](../vph07_gpu_rendering/). > [!WARNING] > Při zápisu matic bacha na to, jestli jsou row-major nebo column-major. Třeba v OpenGL to znamená, že se všechny matice píší v transponované podobě, jelikož OpenGL je column-major a v takovém pořádí jsou i parametery `mat2`, `mat3` a `mat4` V GLSL. diff --git a/szmgr/SZP09_zpracovani_obrazu.md b/szmgr/SZP09_zpracovani_obrazu.md index 509d44e..da68a2a 100644 --- a/szmgr/SZP09_zpracovani_obrazu.md +++ b/szmgr/SZP09_zpracovani_obrazu.md @@ -105,7 +105,7 @@ Převod nelze vyjádřit v lineárním tvaru 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/). + Prahování se pořádně věnuje otázka [Analýza rastrového obrazu](../szp10_analyza_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í). @@ -267,7 +267,7 @@ Proces, kdy hledání _hran_ v obraze. Hrana je křivka, podél níž pixely vý - Hrany lze detekovat pomocí konvoluce. > [!IMPORTANT] -> Numerické diferenciaci se věnuje otázka [Numerické metody](../numericke-metody/). +> Numerické diferenciaci se věnuje otázka [Numerické metody](../szp02_numericke_metody/). ### Podle první derivace (gradientu) @@ -536,7 +536,7 @@ Samplování je převod spojitého signálu na diskrétní. [sampling](#sampling - 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/). + > Aliasingu se věnuje část otázky [Renderování s využitím GPU](../vph07_gpu_rendering/). > [!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čí. diff --git a/szmgr/SZP10_analyza_obrazu.md b/szmgr/SZP10_analyza_obrazu.md index c5e4121..1324771 100644 --- a/szmgr/SZP10_analyza_obrazu.md +++ b/szmgr/SZP10_analyza_obrazu.md @@ -163,7 +163,7 @@ Popis objektů je proces, při kterém se počítají vlastnosti segmentovaných 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/). + > Pro topologické vlastnosti viz otázka [3D modelování a datové struktury](../szp04_3d_modelovani/). - **Ohraničující obdélník / bounding box**\ Nejmenší obdélník ohraničující objekt. @@ -230,7 +230,7 @@ Popis objektů je proces, při kterém se počítají vlastnosti segmentovaných 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/). +> Detaily přístupů řešení klasifikace lze nalézt v otázce [Strojové učení](../szp06_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. diff --git a/szmgr/VPH01_pokrocila_grafika.md b/szmgr/VPH01_pokrocila_grafika.md index 35ffd9d..da48b41 100644 --- a/szmgr/VPH01_pokrocila_grafika.md +++ b/szmgr/VPH01_pokrocila_grafika.md @@ -17,7 +17,7 @@ description: "TODO" 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/). +> Aproximace objektů souvisí s collidery, kterým se částečně věnuje otázka [Grafické a fyzikální principy](../vph02_graficke_a_fyzikalni_principy/). ### Redukce počtu polygonů @@ -347,7 +347,7 @@ Stíny jsou důležité, jelikož: ![width=500rem](./img/vph01_shadow_maps.png) > [!IMPORTANT] - > Shadow mapám se důkladně věnuje otázka [Renderování s využitím GPU](../renderovani-s-vyuzitim-gpu/) + > Shadow mapám se důkladně věnuje otázka [Renderování s využitím GPU](../vph07_gpu_rendering/) - **Shadow volumes**\ Počítá stíny ve 3D. Shadow volume explicitně popisuje objem prostoru ve stínu nějakého polygonu. diff --git a/szmgr/VPH02_graficke_a_fyzikalni_principy.md b/szmgr/VPH02_graficke_a_fyzikalni_principy.md index 262cbf2..12b5869 100644 --- a/szmgr/VPH02_graficke_a_fyzikalni_principy.md +++ b/szmgr/VPH02_graficke_a_fyzikalni_principy.md @@ -222,7 +222,7 @@ Ray tracing jsou techniky, které trasují paprsky světla napříč scénou. ## 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/). +> Renderování založenému na fyzikálních principech se věnuje část otázky [Pokročilá počítačová grafika](../vph01_pokrocila_grafika/). - **Rigid body**\ Aproximace reálného fyzikálního tělesa. Předpokládá uniformní hostotu a **neřeší:** diff --git a/szmgr/VPH03_herni_design_i.md b/szmgr/VPH03_herni_design_i.md index 97b540e..8046f38 100644 --- a/szmgr/VPH03_herni_design_i.md +++ b/szmgr/VPH03_herni_design_i.md @@ -139,7 +139,7 @@ Games are not experiences, they are artifacts people play with while / to create 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/). +> Herní zážitky souvisí s pojmem obtížnost, kterému se věnuje část otázky [Herní design II](../vph04_herni_design_ii/). ==== LeBlanc’s Eight Kinds of Fun @@ -198,7 +198,7 @@ Něco známeho, povědomého pro hráče. 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/). +> Testováním se více zabývá otázka [Herní design II](../vph04_herni_design_ii/). == Game Designer diff --git a/szmgr/VPH07_gpu_rendering.md b/szmgr/VPH07_gpu_rendering.md index 8a3e7ef..5aa9917 100644 --- a/szmgr/VPH07_gpu_rendering.md +++ b/szmgr/VPH07_gpu_rendering.md @@ -38,7 +38,7 @@ description: "TODO" ## Souřadnicové systémy > [!IMPORTANT] -> Tahle část otázky má značný překryv s otázkou [Modelování a projekce](../modelovani-a-projekce/). +> Tahle část otázky má značný překryv s otázkou [Modelování a projekce](../szp08_modelovani_a_projekce/). **Coordinate Systems [coordinate-systems](#coordinate-systems)** @@ -178,7 +178,7 @@ Při zvolání `glDraw*` se používá OpenGL pipeline, která se skládá z ně ## Shadow mapy > [!IMPORTANT] -> Renderování stínů se věnuje také otázka [Pokročilá počítačová grafika](../pokrocila-pocitacova-grafika/). +> Renderování stínů se věnuje také otázka [Pokročilá počítačová grafika](../vph01_pokrocila_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 diff --git a/szmgr/VPH08_modelovani_3d_postav.md b/szmgr/VPH08_modelovani_3d_postav.md index b567eac..cd71b67 100644 --- a/szmgr/VPH08_modelovani_3d_postav.md +++ b/szmgr/VPH08_modelovani_3d_postav.md @@ -80,7 +80,7 @@ description: "TODO" ## Topologie a modifikace > [!TIP] -> Pro základní topologické pojmy viz [3D modelování a datové struktury](../3d-modelovani-a-datove-struktury/). +> Pro základní topologické pojmy viz [3D modelování a datové struktury](../szp04_3d_modelovani/). - **Meshflow**\ Logické uspořádání hran a polygonů v mnohoúhelníkové síti. @@ -111,7 +111,7 @@ description: "TODO" 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/). +> Typy map souvisí s _physically based rendering_ (PBR), kterému se částečně věnuje otázka [Pokročilá počítačová grafika](../vph01_pokrocila_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. From a217a6a85f31292416b7ca8666148275855bb230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Sat, 7 Jun 2025 00:58:21 +0200 Subject: [PATCH 07/44] Regex fix lt symbols Just global search and replace in vs code --- szmgr/PGV01_zaklady_vizualizace.md | 2 +- szmgr/PGV06_vykreslovani_objemovych_dat.md | 2 +- szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md | 2 +- szmgr/SZP01_algoritmy.md | 2 +- szmgr/SZP02_numericke_metody.md | 4 ++-- szmgr/SZP03_statistika.md | 6 +++--- szmgr/SZP04_3d_modelovani.md | 2 +- szmgr/SZP05_krivky_a_povrchy.md | 2 +- szmgr/SZP06_strojove_uceni.md | 8 ++++---- szmgr/SZP07_grafy.md | 4 ++-- szmgr/SZP09_zpracovani_obrazu.md | 4 ++-- 11 files changed, 19 insertions(+), 19 deletions(-) diff --git a/szmgr/PGV01_zaklady_vizualizace.md b/szmgr/PGV01_zaklady_vizualizace.md index 1a742a7..f42e068 100644 --- a/szmgr/PGV01_zaklady_vizualizace.md +++ b/szmgr/PGV01_zaklady_vizualizace.md @@ -31,7 +31,7 @@ Pokud je $M_{eff} \sim 1$, pak je čas na interpretaci a renderování krátký. $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 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é diff --git a/szmgr/PGV06_vykreslovani_objemovych_dat.md b/szmgr/PGV06_vykreslovani_objemovych_dat.md index f095059..9e2ff74 100644 --- a/szmgr/PGV06_vykreslovani_objemovych_dat.md +++ b/szmgr/PGV06_vykreslovani_objemovych_dat.md @@ -69,7 +69,7 @@ Před samotnou rekonstrukcí je často potřeba provézt ještě předzpracován ![width=600](./img/pgv06_alpha_shapes.png) - **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. + 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. diff --git a/szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md b/szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md index ce69490..ae6504a 100644 --- a/szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md +++ b/szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md @@ -10,7 +10,7 @@ description: "TODO" - **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. + 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$. diff --git a/szmgr/SZP01_algoritmy.md b/szmgr/SZP01_algoritmy.md index bcea75a..2da2477 100644 --- a/szmgr/SZP01_algoritmy.md +++ b/szmgr/SZP01_algoritmy.md @@ -70,7 +70,7 @@ Jediným háček je v tom přijít na to, které podproblémy jsou ty nejmenší Ř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í. + Nechť $p(j)$ je index takové události $i < j$, že $i$ a $j$ jsou kompatibilní. ```math \text{OPT}(j) = \begin{cases} diff --git a/szmgr/SZP02_numericke_metody.md b/szmgr/SZP02_numericke_metody.md index 39d4cd5..f7b64ad 100644 --- a/szmgr/SZP02_numericke_metody.md +++ b/szmgr/SZP02_numericke_metody.md @@ -94,7 +94,7 @@ description: "TODO" 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$. + 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 @@ -212,7 +212,7 @@ Modifikace Gauss-Seidelovy metody. Využívá parametr $\omega$, který určuje, \end{align*} ``` -- Pro $0 < \omega < 1$ se názývá metodou dolní relaxace. Je vhodná v případě, kdy Gauss-Seidel nekonverguje. +- 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. diff --git a/szmgr/SZP03_statistika.md b/szmgr/SZP03_statistika.md index cca69e5..9289197 100644 --- a/szmgr/SZP03_statistika.md +++ b/szmgr/SZP03_statistika.md @@ -124,8 +124,8 @@ Jinými slovy, NV $X : \Omega \to \R$ je _spojitá_, pokud se prvky $\Omega$ zob | 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(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 | @@ -157,7 +157,7 @@ Stejně jako náhodné veličiny popisují jevy, číselné charakteristiky popi ``` - **Percentil**\ - Výběrový kvantil ($p$-tý kvantil, kde $0 < p < 1$) $Q_p$. + Výběrový kvantil ($p$-tý kvantil, kde $0 < p < 1$) $Q_p$. - **Modus**\ Hodnota s největší četností. diff --git a/szmgr/SZP04_3d_modelovani.md b/szmgr/SZP04_3d_modelovani.md index 515d607..7c89106 100644 --- a/szmgr/SZP04_3d_modelovani.md +++ b/szmgr/SZP04_3d_modelovani.md @@ -420,7 +420,7 @@ _Když máme objekt definovaný polévkou matematických symbolů místo hromád 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) + 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)$, diff --git a/szmgr/SZP05_krivky_a_povrchy.md b/szmgr/SZP05_krivky_a_povrchy.md index a87e48b..f9dd4a0 100644 --- a/szmgr/SZP05_krivky_a_povrchy.md +++ b/szmgr/SZP05_krivky_a_povrchy.md @@ -192,7 +192,7 @@ Pro zbytek otázky je podstatné znát několik termínů: 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$. + 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šší. diff --git a/szmgr/SZP06_strojove_uceni.md b/szmgr/SZP06_strojove_uceni.md index b64ccc6..22e584a 100644 --- a/szmgr/SZP06_strojove_uceni.md +++ b/szmgr/SZP06_strojove_uceni.md @@ -106,7 +106,7 @@ description: "TODO" - $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$. + > 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)** @@ -126,9 +126,9 @@ description: "TODO" - $\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,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_{\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 @@ -213,7 +213,7 @@ Neuronka je model, kde váhy neuronů jsou parametry. Při učení neuronek je n - **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)$. + 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** diff --git a/szmgr/SZP07_grafy.md b/szmgr/SZP07_grafy.md index 1e59f90..92b379e 100644 --- a/szmgr/SZP07_grafy.md +++ b/szmgr/SZP07_grafy.md @@ -128,7 +128,7 @@ def bfs(graph: List[List[bool]], stamps: List[int], vertex: int) -> None: 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á_. + 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 @@ -324,7 +324,7 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces 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 \}$, + - $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} diff --git a/szmgr/SZP09_zpracovani_obrazu.md b/szmgr/SZP09_zpracovani_obrazu.md index da68a2a..03cf3a1 100644 --- a/szmgr/SZP09_zpracovani_obrazu.md +++ b/szmgr/SZP09_zpracovani_obrazu.md @@ -53,9 +53,9 @@ 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$ +- Snížení jasu: $k = 1, q < 0$ - Zvýšení kontrastu: $k > 1, q = 0$ -- Snížení kontrastu: $0 < 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**\ From 5628771697ccb0c7aaa731b6f2ced6eb86081f30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Sat, 7 Jun 2025 01:59:52 +0200 Subject: [PATCH 08/44] Use markdown footnotes --- szmgr/PGV03_zaklady_pocitatcove_grafiky.md | 19 ++-- szmgr/PGV04_geometricke_algoritmy.md | 5 +- szmgr/PGV05_deleni_prostoru_a_sceny.md | 5 +- szmgr/PGV06_vykreslovani_objemovych_dat.md | 39 ++++--- szmgr/PGV07_modely_osvetleni.md | 9 +- szmgr/PGV08_real_time_rendering.md | 3 +- szmgr/SZP01_algoritmy.md | 21 ++-- szmgr/SZP02_numericke_metody.md | 69 ++++++----- szmgr/SZP03_statistika.md | 63 +++++------ szmgr/SZP04_3d_modelovani.md | 69 ++++++----- szmgr/SZP05_krivky_a_povrchy.md | 55 +++++---- szmgr/SZP06_strojove_uceni.md | 51 ++++----- szmgr/SZP07_grafy.md | 15 ++- szmgr/SZP08_modelovani_a_projekce.md | 2 +- szmgr/SZP09_zpracovani_obrazu.md | 107 +++++++++--------- szmgr/SZP10_analyza_obrazu.md | 21 ++-- .../VPH01_graficke_principy_ve_vyvoji_her.md | 25 ++-- szmgr/VPH01_pokrocila_grafika.md | 53 +++++---- .../VPH02_fyzikalni_principy_ve_vyvoji_her.md | 5 +- szmgr/VPH02_graficke_a_fyzikalni_principy.md | 65 ++++++----- szmgr/VPH03_herni_design_i.md | 44 +++---- szmgr/VPH04_herni_design_ii.md | 37 +++--- szmgr/VPH05_vyvoj_her.md | 45 ++++---- szmgr/VPH06_ai_ve_hrach.md | 59 +++++----- szmgr/VPH07_gpu_rendering.md | 61 +++++----- szmgr/VPH08_modelovani_3d_postav.md | 43 ++++--- 26 files changed, 483 insertions(+), 507 deletions(-) diff --git a/szmgr/PGV03_zaklady_pocitatcove_grafiky.md b/szmgr/PGV03_zaklady_pocitatcove_grafiky.md index 7f8338d..f2f4d0c 100644 --- a/szmgr/PGV03_zaklady_pocitatcove_grafiky.md +++ b/szmgr/PGV03_zaklady_pocitatcove_grafiky.md @@ -13,7 +13,7 @@ description: "TODO" ![width=600](./img/pgv03_block_diagram.png) -Blokový diagram je abstraktní, high-level popis fungování OpenGL [pv112](#pv112). +Blokový diagram je abstraktní, high-level popis fungování OpenGL [^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](../szp08_modelovani_a_projekce), osvětlení jednotlivých vrcholů @@ -266,7 +266,7 @@ Z Primitive assembly dostáváme bod, čáru, nebo trojúhelník, který potřeb ![width=300](./img/pgv03_rast_point.png) - **Ú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. + Při rasterizaci úsečky použijeme Bresenhamův algoritmus [^pb009]. Poslední bod úsečky zůstane nevykreslený (half-open) kvůli návaznosti na další úsečky. ```cpp // From the solution of PB009 @@ -320,7 +320,7 @@ void Application::bresenham(glm::vec2 start, glm::vec2 end, Raster& raster, Colo - **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. +Při rasterizaci trojúhelníku můžeme použít Pinedaův algoritmus [^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. @@ -369,13 +369,12 @@ Výhodami syntetizovaných textur je: - parametrizovatelnost > [!NOTE] -> 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). +> 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] a [^synthesis2]. -## 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 +[^pv112]: Byška: PV112 Computer Graphics API +[^pb009]: Byška: PB009 Principles of Computer Graphics +[^glsl_tutorial]: https://cgvr.cs.uni-bremen.de/teaching/cg2_07/literatur/glsl_tutorial/index.html +[^synthesis1]: https://en.wikipedia.org/wiki/Texture_synthesis +[^synthesis2]: https://diglib.eg.org:8443/server/api/core/bitstreams/90ad4c13-45b1-4ec0-8ef2-76075b2c73ae/content diff --git a/szmgr/PGV04_geometricke_algoritmy.md b/szmgr/PGV04_geometricke_algoritmy.md index 1ece134..d83d8e5 100644 --- a/szmgr/PGV04_geometricke_algoritmy.md +++ b/szmgr/PGV04_geometricke_algoritmy.md @@ -58,7 +58,7 @@ Tento algoritmus má složitost $O(n h)$, kde n je počet bodů a h je počet bo ### 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). +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]. 1. Zvolíme trojúhelník 3 bodů - Bod s minimálními souřadnicemi $(x, y, z)$ @@ -273,6 +273,5 @@ Range trees jsou paměťově náročnější, zato jsou rychlejší. - 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 +[^so_hull_3d]: https://stackoverflow.com/a/74968910/22953817 diff --git a/szmgr/PGV05_deleni_prostoru_a_sceny.md b/szmgr/PGV05_deleni_prostoru_a_sceny.md index fe9ae86..aaa5ede 100644 --- a/szmgr/PGV05_deleni_prostoru_a_sceny.md +++ b/szmgr/PGV05_deleni_prostoru_a_sceny.md @@ -44,7 +44,7 @@ Složitost vytvoření Octree/Quadtree je $O(n \log n)$. Složitost vyhledává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. +(Převzato z 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. ![width=600](./img/pgv04_kd_build.png) @@ -153,6 +153,5 @@ Detekce kolizí je proces, kdy testujeme, zda se dva objekty v prostoru dotýkaj 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/ +[^pgv04]: ../geometricke_algoritmy/ diff --git a/szmgr/PGV06_vykreslovani_objemovych_dat.md b/szmgr/PGV06_vykreslovani_objemovych_dat.md index 9e2ff74..35af9ca 100644 --- a/szmgr/PGV06_vykreslovani_objemovych_dat.md +++ b/szmgr/PGV06_vykreslovani_objemovych_dat.md @@ -38,7 +38,7 @@ Před samotnou rekonstrukcí je často potřeba provézt ještě předzpracován - **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) + 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] 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í. @@ -51,7 +51,7 @@ Před samotnou rekonstrukcí je často potřeba provézt ještě předzpracován ### 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) + 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] ![width=300](./img/vph01_delaunay.svg) @@ -60,9 +60,9 @@ Před samotnou rekonstrukcí je často potřeba provézt ještě předzpracován - **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ů. + [^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) + 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] **Příklady meshe pro různé hodnoty Alpha** @@ -103,14 +103,14 @@ Před samotnou rekonstrukcí je často potřeba provézt ještě předzpracován ![width=500rem](./img/vph01_marching_cubes.svg) - 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) + 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] 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) + 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] - **Flying edges**\ Optimalizovaný algoritmus pro marching cubes, který prochází každou hranu pouze jednou. - **Surface nets**\ @@ -119,22 +119,22 @@ Před samotnou rekonstrukcí je často potřeba provézt ještě předzpracován ![width=500](./img/pgv06_surface_nets.png) - **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) + 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] ![width=500](./img/pgv06_dual_contouring.png) ### 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) +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] 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)** +**The Process of Volume Rendering [^gpugems]** ![width=500rem](./img/vph01_direct_volume_rendering.jpg) - **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) + 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] - $\kappa$ je funkce absorpce, - $q$ je emise. @@ -158,7 +158,7 @@ V realitě tohle chování paprsku popisujeme integrály. V počítačové grafi ``` - **Volume rendering integral**\ - Intenzitu světla $I$ v místě paprsku $s$ počítáme pomocí: [pa213](#pa213) + Intenzitu světla $I$ v místě paprsku $s$ počítáme pomocí: [^pa213] ```math \begin{aligned} @@ -189,14 +189,13 @@ V realitě tohle chování paprsku popisujeme integrály. V počítačové grafi 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) + Funkce $T$, která mapuje hodnoty voxelů na barvu a průhlednost. Klasifikuje voxely. [^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) +[^pa010]: Sochor: PA010 Intermediate Computer Graphics (podzim 2020) +[^pa213]: PA213 Advanced Computer Graphics +[^marching]: [Marching cubes: A high resolution 3D surface construction algorithm](https://dl.acm.org/doi/10.1145/37402.37422) +[^marching]: [Wikipedia: Marching tetrahedra](https://en.wikipedia.org/wiki/Marching_tetrahedra) +[^dual]: [Dual Contouring Tutorial](https://www.boristhebrave.com/2018/04/15/dual-contouring-tutorial/) +[^delaunay]: [Wikipedia: Delaunay triangulation](https://en.wikipedia.org/wiki/Delaunay_triangulation) +[^gpugems]: [GPU Gems: Volume Rendering Techniques](https://developer.nvidia.com/gpugems/gpugems/part-vi-beyond-triangles/chapter-39-volume-rendering-techniques) diff --git a/szmgr/PGV07_modely_osvetleni.md b/szmgr/PGV07_modely_osvetleni.md index dc33d67..94e6109 100644 --- a/szmgr/PGV07_modely_osvetleni.md +++ b/szmgr/PGV07_modely_osvetleni.md @@ -21,7 +21,7 @@ description: "TODO" ## 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) +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] ![width=600](./img/pgv07_phong_overview.png) @@ -127,7 +127,7 @@ Participující média jsou média, která nejsou zcela průhledná, ale nejsou ## 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ů. +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] 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). @@ -242,7 +242,6 @@ Pro výpočet spekulárního osvětlení se používá zrcadlový vektor a Fresn ![width=600](./img/pgv07_ibr.png) -## 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) +[^pv227]: [PV227 GPU Rendering (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PV227/) +[^pb009]: [Interaktivní osnova PB009 by xrosecky](https://is.muni.cz/auth/el/fi/jaro2023/PB009/index.qwarp) diff --git a/szmgr/PGV08_real_time_rendering.md b/szmgr/PGV08_real_time_rendering.md index a2d6383..58a178e 100644 --- a/szmgr/PGV08_real_time_rendering.md +++ b/szmgr/PGV08_real_time_rendering.md @@ -242,6 +242,5 @@ Stíny jsou důležité, jelikož: - **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]: Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021) diff --git a/szmgr/SZP01_algoritmy.md b/szmgr/SZP01_algoritmy.md index 2da2477..ad154c4 100644 --- a/szmgr/SZP01_algoritmy.md +++ b/szmgr/SZP01_algoritmy.md @@ -153,7 +153,7 @@ Greedy algoritmy nachází řešení globálního problému tak, že volí loká _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) +Technika hledání řešení problému postupným sestavováním _kandidátního_ řešení. [^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. @@ -432,7 +432,7 @@ _String matching_ označuje rodinu problémů obsahující třeba: 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) +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] | Algoritmus | | ----------------------------------- | @@ -518,7 +518,7 @@ int KarpRabin(string text, string pattern) - **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í + Jeden takový algoritmus lze získat použitím Hornerova schématu pro evaluaci polynomu. [^horner] Předpokládejme, že $\Sigma = \{0, 1, ..., 9\}$ (velikost může být libovolná), pak pro hash $h$ platí ```math \begin{align*} @@ -601,7 +601,7 @@ Jinými slovy na indexu druhého `D` je `abcD` nejdelší prefix $P$, který je - **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) + Složitost hledání je pak v $\Theta(n)$. [^iv003-strings] ### Knuth-Morris-Pratt (KMP) @@ -672,15 +672,14 @@ int KnuthMorrisPratt(string text, string pattern) > 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) +> "In other words we can amortize character mismatches against earlier character matches." [^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 +[^iv003]: [IV003 Algoritmy a datové struktury II (jaro 2021)](https://is.muni.cz/auth/el/fi/jaro2021/IV003/) +[^iv003]: https://is.muni.cz/auth/el/fi/jaro2021/IV003/um/slides/stringmatching.pdf +[^rabin]: https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm +[^horner]: https://en.wikipedia.org/wiki/Horner%27s_method +[^backtracking]: https://betterprogramming.pub/the-technical-interview-guide-to-backtracking-e1a03ca4abad diff --git a/szmgr/SZP02_numericke_metody.md b/szmgr/SZP02_numericke_metody.md index f7b64ad..651dccd 100644 --- a/szmgr/SZP02_numericke_metody.md +++ b/szmgr/SZP02_numericke_metody.md @@ -10,7 +10,7 @@ description: "TODO" - **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) + 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] 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. @@ -26,12 +26,12 @@ description: "TODO" - **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) + 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] - **Řá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) + 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] [^numericka-metoda] [^order-question] ```math \begin{aligned} @@ -47,16 +47,16 @@ description: "TODO" ## 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) + Problém nalezení _kořenů_ (root) funkce $f$. T.j. takových parametrů $x, ...$, kde funkce vrací 0: [^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) + 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] [^root-finding] - **Řád metody / rate of convergence**\ - Hodnota reprezentující, jak rychle metoda konverguje k výsledku. [rate](#rate) + Hodnota reprezentující, jak rychle metoda konverguje k výsledku. [^rate] - **Prostá iterační metoda / metoda pevného bodu / fixed-point iteration**\ Používá se pro rovnice typu $x = g(x)$. @@ -88,7 +88,7 @@ description: "TODO" ![width=400](./img/szp02_secant_method.png) - **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) + 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] ```math x_{k+1} = x_k - \frac{x_k - x_s}{f(x_k) - f(x_s)} f(x_k) @@ -100,7 +100,7 @@ description: "TODO" ### 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: +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] Povoleny jsou následující operace: - výměna dvou řádků, - vynásobení řádku nenulovou konstantou, @@ -108,7 +108,7 @@ Systém rovnice je přepsán do matice. Gaussova eliminace je posloupnost operac ### 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) +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] Nechť $A\mathbf{x} = \mathbf{b}$ je systém $n$ lineárních rovnic. Tedy: @@ -178,7 +178,7 @@ Jelikož $L + U = A - D$, dá to zapsat i jako: ### 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) +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] 1. Zvolíme počáteční odhad $\mathbf{x}^{(0)}$. 2. Nový odhad získáme ze vztahu: @@ -203,7 +203,7 @@ T_{gs} &= (D + L)^{-1} U = 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) +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] ```math \begin{align*} @@ -274,7 +274,7 @@ Metody podobné Gaussově eliminaci, ale s vlastnostmi, které mohou být vyhodn ## 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) +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] Numerická diferenciace se využívá pro aproximaci differenciálních rovnic (převodem na _diferenční rovnice_). @@ -285,7 +285,7 @@ Numerická diferenciace se využívá pro aproximaci differenciálních rovnic ( > Lagrangeovu interpolaci řeší část otázky [Křivky a povrchy](../szp05_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) + 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] Jednotlivým "odstínům" -- konkrétním výpočetním vzorcům -- téhle metody se říká _diferenciační schémata_. @@ -293,7 +293,7 @@ Numerická diferenciace se využívá pro aproximaci differenciálních rovnic ( > 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) + Nejjednodušší schéma numerické diferenciace. Vychází z definice derivace. [^finite-difference] - _Dopředná diference / forward (finite) difference_ @@ -319,24 +319,23 @@ Numerická diferenciace se využívá pro aproximaci differenciálních rovnic ( > 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)]() -- [[[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) + Způsob zlepšení rate of convergence iterativních metod. [^richardson] + + +[^ma018]: [MA018 Numerical Methods (podzim 2019)](https://is.muni.cz/auth/el/fi/podzim2019/MA018/) +[^numerical]: [Wikipedia: Numerical analysis](https://en.wikipedia.org/wiki/Numerical_analysis) +[^root]: [Wikipedia: Root-finding algorithms](https://en.wikipedia.org/wiki/Root-finding_algorithms) +[^rate]: [Wikipedia: Rate of convergence](https://en.wikipedia.org/wiki/Rate_of_convergence) +[^regula]: [Wikipedia: Regula falsi](https://en.wikipedia.org/wiki/Regula_falsi) +[^gauss]: [Wikipedia: Gaussian elimination](https://en.wikipedia.org/wiki/Gaussian_elimination) +[^jacobi]: [Wikipedia: Jacobi method](https://en.wikipedia.org/wiki/Jacobi_method) +[^gauss]: [Wikipedia: Gauss-Seidel method](https://en.wikipedia.org/wiki/Gauss%E2%80%93Seidel_method) +[^relaxation]: [Wikipedia: Relaxation (iterative method)]() +[^differentiation]: [Wikipedia: Numerical differentiation](https://en.wikipedia.org/wiki/Numerical_differentiation) +[^finite]: [Wikipedia: Finite difference](https://en.wikipedia.org/wiki/Finite_difference) +[^finite]: [Wikipedia: Finite difference method](https://en.wikipedia.org/wiki/Finite_difference_method) +[^richardson]: [Wikipedia: Richardson extrapolation](https://en.wikipedia.org/wiki/Richardson_extrapolation) +[^linear]: [Wikipedia: System of linear equations](https://en.wikipedia.org/wiki/System_of_linear_equations) +[^numerical]: [Wikipedia: Numerical stability](https://en.wikipedia.org/wiki/Numerical_stability) +[^numericka]: [Wikipedia: Numerická metoda](https://cs.wikipedia.org/wiki/Numerick%C3%A1_metoda) +[^order]: [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) diff --git a/szmgr/SZP03_statistika.md b/szmgr/SZP03_statistika.md index 9289197..4ade435 100644 --- a/szmgr/SZP03_statistika.md +++ b/szmgr/SZP03_statistika.md @@ -15,7 +15,7 @@ description: "TODO" > 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) + Zabývá se sbíráním, organizací, analýzou, interpretací a prezentací dat. [^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í. @@ -142,7 +142,7 @@ Stejně jako náhodné veličiny popisují jevy, číselné charakteristiky popi 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) + > Taky někdy označovaný jako _obecný moment prvního řádu / první obecný moment_. [^moment] - **$\alpha$-kvantil $Q_\alpha$**\ Dělí statický soubor na stejně velké části. @@ -173,7 +173,7 @@ Jak moc se od sebe prvky liší (nezávisle na konstantním posunutí)? ``` > [!NOTE] - > Taky někdy označovaný jako _centrální moment druhého řádu / druhý centrální moment_. [moment](#moment) + > Taky někdy označovaný jako _centrální moment druhého řádu / druhý centrální moment_. [^moment] - **Směrodatná odchylka / standard deviation**\ Míra variability NV. Značí se $\sigma$ nebo $\text{SD}(X)$. Je definovaná jako $\sqrt{\sigma^2}$. @@ -283,7 +283,7 @@ Popisuje chování _výběrového průměru_ pro velké soubory vzorků a umož - **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) + Metoda odhadu parametru $\theta$ taková, že s počtem vzorků $n$ konverguje k $\theta$ pro $n \to \infty$. [^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: @@ -299,7 +299,7 @@ Popisuje chování _výběrového průměru_ pro velké soubory vzorků a umož > ``` > [!TIP] - > _Estimator_ je funkce počítající statistiku použitá k odhadu parametru. [statistic](#statistic) + > _Estimator_ je funkce počítající statistiku použitá k odhadu parametru. [^statistic] - **Bodový odhad / point estimate / pointwise estimate**\ Odhad parametru daný **jednou hodnotou**, která hodnotu parametru aproximuje. @@ -363,9 +363,9 @@ Máme vzorek velikosti $n$ s výběrovým průměrem $\overline{X}$ a výběrov > 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) + Metoda odhadu parametru založená na maximalizaci likelihoodu, že model sedí na naměřená data. [^mle] - **Method of moments (MOM)**\ - Metoda odhadu parametru založená na rovnosti teoretického a výběrového momentu. [mom](#mom) + Metoda odhadu parametru založená na rovnosti teoretického a výběrového momentu. [^mom] ## Testování statistických hypotéz @@ -377,7 +377,7 @@ Máme vzorek velikosti $n$ s výběrovým průměrem $\overline{X}$ a výběrov - _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) + 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] > 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_). > @@ -407,7 +407,7 @@ Platí presumpce nevinny. Předpokládáme, že člověk zločin nespáchal, dok - **$p$-hodnota (hladina významnosti)**\ - Nejmenší hladina významnosti $\alpha$, při které ještě zamítáme $H_0$. [p-value](#p-value) + Nejmenší hladina významnosti $\alpha$, při které ještě zamítáme $H_0$. [^p-value] Pravděpodobnost, že došlo k chybě typu I -- zavrhnuli jsme $H_0$, ačkoli platí. @@ -423,9 +423,9 @@ Platí presumpce nevinny. Předpokládáme, že člověk zločin nespáchal, dok 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) + 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] - **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) + 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] ### Neparametrické testy @@ -436,7 +436,7 @@ Neparametrické testy nejsou založené (jen) na parametrech pravděpodobnostní - **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) + Umožňuje ověřit, že dvě kategorické NV jsou nezávislé. [^chi-squared] ### Testy (ne)závislosti náhodných veličin @@ -448,7 +448,7 @@ Neparametrické testy nejsou založené (jen) na parametrech pravděpodobnostní **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) + - 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] - **Nezávislost diskrétních NV** @@ -520,22 +520,21 @@ Neparametrické testy nejsou založené (jen) na parametrech pravděpodobnostní 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]() -- [[[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) + +[^statistics]: [Wikipedia: Statistics](https://en.wikipedia.org/wiki/Statistics) +[^nv]: [Wikipedia: Náhodná veličina](https://cs.wikipedia.org/wiki/N%C3%A1hodn%C3%A1_veli%C4%8Dina) +[^cdf]: [Wikipedia: Cumulative distribution function](https://en.wikipedia.org/wiki/Cumulative_distribution_function) +[^mean]: [Wikipedia: Mean](https://en.wikipedia.org/wiki/Mean) +[^clv]: [Wikipedia: Centrální limitní věta](https://cs.wikipedia.org/wiki/Centr%C3%A1ln%C3%AD_limitn%C3%AD_v%C4%9Bta) +[^consistent]: [Wikipedia: Consistent estimator](https://en.wikipedia.org/wiki/Consistent_estimator) +[^statistic]: [Wikipedia: Statistic](https://en.wikipedia.org/wiki/Statistic) +[^mle]: [Wikipedia: Maximum likelihood estimation](https://en.wikipedia.org/wiki/Maximum_likelihood_estimation) +[^mom]: [Wikipedia: Method of moments]() +[^null]: [Wikipedia: Null hypothesis](https://en.wikipedia.org/wiki/Null_hypothesis) +[^p]: [Wikipedia: P-hodnota](https://cs.wikipedia.org/wiki/P-hodnota) +[^mv013]: [MV013 Statistics for Computer Science (jaro 2021)](https://is.muni.cz/auth/el/fi/jaro2021/MV013/) +[^anova]: [Wikipedia: Analysis of variance](https://en.wikipedia.org/wiki/Analysis_of_variance) +[^nezavislost]: [Wikipedia: Statistická nezávislost](https://cs.wikipedia.org/wiki/Statistick%C3%A1_nez%C3%A1vislost) +[^t]: [Wikipedia: T-test](https://cs.wikipedia.org/wiki/T-test) +[^chi]: [Chi-square tests](https://www.scribbr.com/statistics/chi-square-tests/) +[^moment]: [Momenty rozdělení](http://kfe.fjfi.cvut.cz/~limpouch/sigdat/pravdh/node10.html) diff --git a/szmgr/SZP04_3d_modelovani.md b/szmgr/SZP04_3d_modelovani.md index 7c89106..10a0acc 100644 --- a/szmgr/SZP04_3d_modelovani.md +++ b/szmgr/SZP04_3d_modelovani.md @@ -16,21 +16,21 @@ description: "TODO" - **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) + - Zahrnuje zakřivení (curvature), plochu (area), vzdálenosti mezi body, atd. [^pa010-2021] - **Topologie** - Nemění ji deformace. - Např. to jak jsou body propojené. - - Sousednost (neighborhood), souvislost (connectedness), adjacency. atd. [pa010-2021](#pa010-2021) + - Sousednost (neighborhood), souvislost (connectedness), adjacency. atd. [^pa010-2021] - **Topology [topology](#topology)** + **Topology [^topology]** ![Topology](./img/szp04_topology.png) - **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) + Prostor/útvar, který lokálně _připomíná_ (je homeomorfní) $n$-dimenzionální Euklidovský prostor. [^pa010-2021] [^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) + $n$-manifold je takový topologický manifold, kde okolí každého bodu je homeomorfní s $n$-dimenzionálním Euklidovským prostorem. [^manifold-wiki] Manifoldy jsou typicky fyzikálně validní a efektivní (např. pomocí half-edge). @@ -38,7 +38,7 @@ description: "TODO" - 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) + - Každý povrch je 2-manifold až na neuzavřené hrany. [^pa010-2021] - $n$-dimenzionální koule je $n$-manifold. ![width=100%](./img/szp04_manifold.png) @@ -85,7 +85,7 @@ description: "TODO" > [!TIP] > 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í**. + > Následující povrch[^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í**. >
> ![width=500rem](./img/szp04_genus.png) @@ -207,12 +207,12 @@ description: "TODO" - 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) + Numerické chyby v geometrii (např. v pozicích vertexů) mohou způsobit konflikty mezi topologickou a geometrickou informací. [^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) + 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] [^boundaries] > [!NOTE] > Zdá se, že $H$ -- components je ekvivalentní $R$ -- rings. @@ -263,7 +263,7 @@ description: "TODO" - `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) + Regularizace vypadá tak, že nejprve je provedena booleovská operace, poté je vypočítán _interior_ a následně _closure_. [^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$. @@ -274,11 +274,11 @@ description: "TODO" _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)** + **Schéma interior and a boundary tělesa $A \cap B$ [^pa010-2021]** ![width=200](./img/szp04_interior_boundary.png) - **Příklad regularizovaného průniku [pa010-2021](#pa010-2021)** + **Příklad regularizovaného průniku [^pa010-2021]** ![width=100%](./img/szp04_rbo.png) @@ -325,29 +325,29 @@ description: "TODO" > 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](../vph01_pokrocila_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) + 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] ![width=400](./img/szp04_edge_flip.png) - **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) + 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] ![width=400](./img/szp04_edge_split.png) - **Zhroucení grany / edge collapse**\ - Lokální změna, která nahrazuje hranu vrcholem. [pa010-2021](#pa010-2021) + Lokální změna, která nahrazuje hranu vrcholem. [^pa010-2021] ![width=400](./img/szp04_edge_collapse.png) - **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) + 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] ![width=400](./img/szp04_subdivision.png) - **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) + Globální upráva s cílem zlepšit kvalitu meshe, např.: tvar trojúhelníků a četnost vertexů. [^pa010-2021] ![width=400](./img/szp04_mesh_regularization.png) @@ -359,7 +359,7 @@ description: "TODO" 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) + 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] ![width=400](./img/szp04_isotropic_remeshing.png) @@ -417,10 +417,10 @@ _Když máme objekt definovaný polévkou matematických symbolů místo hromád - _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) + kde $d(x, A)$ je nejmenší vzdálenost bodu $x$ od entity $A$. [^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) + 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] - _Sjednocení_: $\min(f, g)$, - _Průnik_: $\max(f, g)$, @@ -428,7 +428,7 @@ _Když máme objekt definovaný polévkou matematických symbolů místo hromád - _Komplement_: $-f$. - **Bloby (kapky)**\ - Součet několika Gaussových křivek. [pa010-2020](#pa010-2020) + Součet několika Gaussových křivek. [^pa010-2020] ```math \begin{align*} @@ -450,7 +450,7 @@ _Když máme objekt definovaný polévkou matematických symbolů místo hromád ![width=300](./img/szp04_blobs.png) - **Metaballs**\ - Podobné blobům, ale nepoužívá exponenciální funkci. Organicky se "slévající" koule. [pa010-2020](#pa010-2020) + Podobné blobům, ale nepoužívá exponenciální funkci. Organicky se "slévající" koule. [^pa010-2020] ```math \begin{align*} @@ -475,16 +475,15 @@ _Když máme objekt definovaný polévkou matematických symbolů místo hromád ![width=100%](./img/szp04_metaballs.png) -## 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) + +[^pa010]: Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021) +[^pa010]: Sochor: PA010 Intermediate Computer Graphics (podzim 2020) +[^notes]: [Moje poznámky z PA010 (podzim 2020)](/fi/pa010/) +[^manifold]: [Wikipedia: Topological manifold](https://en.wikipedia.org/wiki/Topological_manifold) +[^klein]: [Konrad Polthier: Imaging maths - Inside the Klein bottle ](https://plus.maths.org/content/imaging-maths-inside-klein-bottle) +[^genus]: [Saul Schleimer: Notes on the complex of curves](https://www.researchgate.net/publication/228393582_Notes_on_the_complex_of_curves) +[^topology]: [Topology vs. Geometry](https://www.austincc.edu/herbling/shape-of-space.pdf) +[^boundaries]: [Ian Stroud: Boundary Representation Modelling Techniques](https://link.springer.com/book/10.1007/978-1-84628-616-2) +[^rbo]: [Interior, Exterior and Closure](https://pages.mtu.edu/~shene/COURSES/cs3621/NOTES/model/closure.html) +[^validity]: [Representational validity of boundary representation models](https://www.sciencedirect.com/science/article/pii/S0010448500000476) +[^denoising]: [Bilateral Normal Filtering for Mesh Denoising](https://ieeexplore.ieee.org/document/5674028) diff --git a/szmgr/SZP05_krivky_a_povrchy.md b/szmgr/SZP05_krivky_a_povrchy.md index f9dd4a0..0e8a39e 100644 --- a/szmgr/SZP05_krivky_a_povrchy.md +++ b/szmgr/SZP05_krivky_a_povrchy.md @@ -218,22 +218,22 @@ Křivka $Q$ patří do třídy $C^n$, pokud má ve všech bodech $t$ spojitou de ### 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) +Je podobná parametrické spojitosti, ale vyžaduje jen "geometrickou" spojitost. Vyžaduje, aby si derivace byly **sobě úměrné**. [^mallinus] [^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) +- $G^2$ -- platí $G^1$ a navíc mají stejný **střed křivosti** (center of curvature). [^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. +> Podle slidů z PB009 musí faktor úměrnosti být různý od 0. [^pb009-2019] Podle Barskyho a DeRoseho musí v první derivaci být $> 0$ a v dalších už je to šumák. [^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) +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] ```math \ell_i(x) = \prod_{0 \le k \le n, k \neq i}^n \frac{x - x_k}{x_i - x_k} @@ -259,7 +259,7 @@ 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) + Metoda evaluace polynomů. Vychází z myšlenky, že násobení se dá nestovat: [^horner] ```math \begin{aligned} @@ -279,7 +279,7 @@ Asi nejznámnější interpolační křivky v počítačové grafice. Jsou urče 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) + Pro Hermitovskou kubiku platí: [^hermite-spline] [^ferguson] ```math \begin{aligned} @@ -365,12 +365,12 @@ Mezi jejich vlastnosti patří: ### B-spline - **Splajn / spline**\ - Splajn stupně $n$ po částech definovaná polynomiální funkce stupně $n-1$ proměnné $x$. [bspline](#bspline) + Splajn stupně $n$ po částech definovaná polynomiální funkce stupně $n-1$ proměnné $x$. [^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 jsou uzly unikátní, pak je splajn v uzlech $C^{n-2}$ spojitý. [^bspline] - Pokud je $r$ uzlů shodných, je v tomto místě pouze $C^{n-r-1}$ spojitý. --- @@ -428,7 +428,7 @@ S(x) = \sum_{i=0} c_i B_{i,n}(x) ``` - **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) + 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] ```math \begin{aligned} @@ -606,7 +606,7 @@ Aproximační plochy analogické B-spline křivkám, ale se dvěma parametry. - **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. + 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] 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} @@ -621,7 +621,7 @@ Aproximační plochy analogické B-spline křivkám, ale se dvěma parametry. $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) +> 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] ## Surface subdivision / rekurzivní dělení polygonů @@ -659,23 +659,22 @@ Polygonové povrchy dělíme v případě, kdy chceme je zjemnit, vyhladit. **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) + +[^pa010]: Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021) +[^pa010]: Sochor: PA010 Intermediate Computer Graphics (podzim 2020) +[^pb009]: Sochor: PB009 Principles of Computer Graphics (jaro 2019) +[^smoothness]: [Wikipedia: Smoothness](https://en.wikipedia.org/wiki/Smoothness) +[^mallinus]: [Jaakko Kurhila and Matti Mäkelä: Parametric Curves](https://www.cs.helsinki.fi/group/goa/mallinnus/curves/curves.html) +[^geometric]: [Geometric Continuity of Parametric Curves: Three Equivalent Characterizations](https://ieeexplore.ieee.org/document/41470) +[^lagrange]: [Wikipedia: Lagrange polynomial](https://en.wikipedia.org/wiki/Lagrange_polynomial) +[^bspline]: [Wikipedia: B-spline](https://en.wikipedia.org/wiki/B-spline) +[^hermite]: [Wikipedia: Cubic Hermite spline](https://en.wikipedia.org/wiki/Cubic_Hermite_spline) +[^ferguson]: [ČVUT: Ferguson curve](https://marian.fsik.cvut.cz/~kongo/download/pcgr/lectures/01%20crv_ferg.pdf) +[^coons]: [ČVUT: Coons curve](https://marian.fsik.cvut.cz/~kongo/download/pcgr/lectures/03%20crv_coons.pdf) +[^coons]: [Wikipedia: Coons patch](https://en.wikipedia.org/wiki/Coons_patch) +[^nurbs]: [Wikipedia: Non-uniform rational B-spline](https://en.wikipedia.org/wiki/Non-uniform_rational_B-spline) +[^sweeping]: [Wikipedia: Solid modeling](https://en.wikipedia.org/wiki/Solid_modeling#Sweeping) +[^horner]: [Wikipedia: Horner’s method](https://en.wikipedia.org/wiki/Horner%27s_method) ## Další zdroje diff --git a/szmgr/SZP06_strojove_uceni.md b/szmgr/SZP06_strojove_uceni.md index 22e584a..3d0ea05 100644 --- a/szmgr/SZP06_strojove_uceni.md +++ b/szmgr/SZP06_strojove_uceni.md @@ -16,7 +16,7 @@ description: "TODO" - **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) + 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] [^pv021] Používá se např. pro: @@ -28,23 +28,23 @@ description: "TODO" - 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) + 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] - **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) + 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] - **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) + 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] - 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) + 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] - **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) + 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] 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) + 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] - **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) + 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] ## Neuronové sítě @@ -92,7 +92,7 @@ description: "TODO" - **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) + - Binární klasifikátor -- rozlišuje jestli vstup patří nebo nepatří do nějaké jedné kategorie.[^pv021] - Linerání klasifikátor -- jeho funkce kombinuje vstupy lineárně. ![width=400](./img/szp06_perceptron.png) @@ -274,7 +274,7 @@ Za předpokladu, že $E$ je squared error, pak: ## 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) +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] > [!IMPORTANT] > Pro konvoluci viz otázka [Zpracování rastrového obrazu](../szp09_zpracovani_obrazu/). @@ -319,7 +319,7 @@ Neuronové sítě uzpůsobené ke zpracování obrazu. Místo násobení matic p ## 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) +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] - **Výhody** @@ -430,18 +430,17 @@ Neuronové sítě, jejichž architektura obsahuje cykly. Tedy výstup v jednom b ![width=100%](./img/szp06_lstm.png) -## 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) + +[^pv021]: T. Brázdil: PV021 Neural Networks +[^ml]: [Wikipedia: Machine learning](https://en.wikipedia.org/wiki/Machine_learning) +[^classification]: [Wikipedia: Statistical classification](https://en.wikipedia.org/wiki/Statistical_classification) +[^regression]: [Wikipedia: Regression analysis](https://en.wikipedia.org/wiki/Regression_analysis) +[^clustering]: [Wikipedia: Cluster analysis](https://en.wikipedia.org/wiki/Cluster_analysis) +[^pattern]: [Wikipedia: Pattern recognition](https://en.wikipedia.org/wiki/Pattern_recognition) +[^hopfield]: [Wikipedia: Hopfield network](https://en.wikipedia.org/wiki/Hopfield_network) +[^hebb]: [Wikipedia: Hebbian theory](https://en.wikipedia.org/wiki/Hebbian_theory) +[^cnn]: [Wikipedia: Convolutional neural network](https://en.wikipedia.org/wiki/Convolutional_neural_network) +[^rnn]: [Wikipedia: Recurrent neural network](https://en.wikipedia.org/wiki/Recurrent_neural_network) +[^som]: [Wikipedia: Self-organizing map](https://en.wikipedia.org/wiki/Self-organizing_map) +[^som]: [Self-Organizing Maps: Tutorial](https://sites.pitt.edu/~is2470pb/Spring05/FinalProjects/Group1a/tutorial/som.html) +[^som]: [SDL Component Suite: Kohonen Network](http://www.lohninger.com/helpcsuite/kohonen_network_-_background_information.htm) diff --git a/szmgr/SZP07_grafy.md b/szmgr/SZP07_grafy.md index 92b379e..18c8e64 100644 --- a/szmgr/SZP07_grafy.md +++ b/szmgr/SZP07_grafy.md @@ -528,7 +528,7 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces ## 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) + Množina $M \sube E$ taková, že žádné dvě hrany v $M$ nemají společný vrchol. [^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í. @@ -541,7 +541,7 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces - **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) + 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] 1. Mejmě bipartitní graf $G=(X+Y,E)$. @@ -557,13 +557,12 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces ![width=300](./img/szp07_mcm_03.png) -## 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) +[^ib000]: [IB000 Matematické základy informatiky (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/IB000/um/) +[^ib002]: [IB002 Algoritmy a datové struktury (jaro 2020)](https://is.muni.cz/auth/el/fi/jaro2020/IB002/um/) +[^ib003]: [IV003 Algoritmy a datové struktury II (jaro 2021)](https://is.muni.cz/auth/el/fi/jaro2021/IV003/um/) +[^matching]: [Wikipedia: Párování grafu](https://cs.wikipedia.org/wiki/P%C3%A1rov%C3%A1n%C3%AD_grafu) +[^mcm]: [Wikipedia: Maximum cardinality matching](https://en.wikipedia.org/wiki/Maximum_cardinality_matching) ## Další zdroje diff --git a/szmgr/SZP08_modelovani_a_projekce.md b/szmgr/SZP08_modelovani_a_projekce.md index 58a0518..04748bf 100644 --- a/szmgr/SZP08_modelovani_a_projekce.md +++ b/szmgr/SZP08_modelovani_a_projekce.md @@ -91,7 +91,7 @@ description: A guide in my new Starlight docs site. ### Ortografická projekce -Používáme především k vykreslení 2D scén. Osu Z můžeme využít, abychom jeden sprite schovali za jiný. Nicméně objekty dál od kamery jsou stejně velké jako ty blízko kamery. [camera](#camera) +Používáme především k vykreslení 2D scén. Osu Z můžeme využít, abychom jeden sprite schovali za jiný. Nicméně objekty dál od kamery jsou stejně velké jako ty blízko kamery. [^camera] ![width=500](./img/szp08_orthographic_projection.png) diff --git a/szmgr/SZP09_zpracovani_obrazu.md b/szmgr/SZP09_zpracovani_obrazu.md index 03cf3a1..dc2dfc4 100644 --- a/szmgr/SZP09_zpracovani_obrazu.md +++ b/szmgr/SZP09_zpracovani_obrazu.md @@ -10,12 +10,12 @@ description: "TODO" - **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) + 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] > 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) + Oblast informatiky zabývající se manipulací s obrazy pomocí počítače. Obsahuje třeba: [^dip] - zpracování raw dat ze senzorů ve foťácích, - odstranění šumu, @@ -133,7 +133,7 @@ Histogram kvantifikuje množství a frekvenci barev obsažených v obraze. Ve st ``` - **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) + Změna obrazu tak, aby jeho kumulativní histogram měl konkrétní tvar, obvykle aby byl lineární. [^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. @@ -151,7 +151,7 @@ Histogram kvantifikuje množství a frekvenci barev obsažených v obraze. Ve st > 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) + 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-bbc] - průměrný jas, - kontrast, @@ -162,7 +162,7 @@ Histogram kvantifikuje množství a frekvenci barev obsažených v obraze. Ve st ## 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) + 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] - **Š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: @@ -172,7 +172,7 @@ Histogram kvantifikuje množství a frekvenci barev obsažených v obraze. Ve st - _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) + 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] ```math (f * g)(t) = \int_{-\infty}^{\infty} \cdot f(\tau) g(t - \tau) d\tau @@ -340,7 +340,7 @@ Proces, kdy hledání _hran_ v obraze. Hrana je křivka, podél níž pixely vý - **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) + Algoritmus pro detekci hran. [^canny] [^canny-tds] - Má nízké procento chyb. - Přesně lokalizuje hrany. @@ -360,7 +360,7 @@ Proces, kdy hledání _hran_ v obraze. Hrana je křivka, podél níž pixely vý 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) + Divergence je operátor, který vrací skalární hodnotu. Popisuje zda gradient roste či klesá. Je definován jako: [^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} @@ -411,7 +411,7 @@ Hrany lze detekovat pomocí druhé derivace obrazu. Nacházejí se v _nulových ## 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) +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] Patří sem transformace jako: @@ -430,7 +430,7 @@ Patří sem transformace jako: > 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...)_ -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) +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] - 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. @@ -464,7 +464,7 @@ Je operace (integrální transformace) při níž je obraz převeden z _prostoro }_{\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) + **Forward** (z prostorové do frekvenční domény): [^fourier] ```math \begin{align*} @@ -487,7 +487,7 @@ Je operace (integrální transformace) při níž je obraz převeden z _prostoro ``` - **2D Fourierova transformace**\ - **Forward** (z prostorové do frekvenční domény): [fourier](#fourier) + **Forward** (z prostorové do frekvenční domény): [^fourier] ```math \begin{align*} @@ -510,9 +510,9 @@ Je operace (integrální transformace) při níž je obraz převeden z _prostoro ``` - **Fast Fourier Transform (FFT)**\ - Algoritmus pro rychlé výpočty diskrétní Fourierovy transformace (DFT). [fft](#fft) + Algoritmus pro rychlé výpočty diskrétní Fourierovy transformace (DFT). [^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) + Ří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] ```math \mathcal{F} \{ f * g \} = \mathcal{F} \{ f \} \cdot \mathcal{F} \{ g \} @@ -522,15 +522,15 @@ Je operace (integrální transformace) při níž je obraz převeden z _prostoro ## Sampling / vzorkování -Samplování je převod spojitého signálu na diskrétní. [sampling](#sampling) +Samplování je převod spojitého signálu na diskrétní. [^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) + V případě 2D obrazů to může ale nemusí znamenat změnu velikosti obrazu. [^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) + Ří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] - 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. @@ -542,7 +542,7 @@ Samplování je převod spojitého signálu na diskrétní. [sampling](#sampling > 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) + Proces, kdy z diskrétního signálu zpět získáme spojitý signál. [^reconstruction] - **Rekonstrukční filtr**\ Filtr pro rekonstrukci signálu. @@ -554,7 +554,7 @@ Samplování je převod spojitého signálu na diskrétní. [sampling](#sampling ## 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) +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] ```math J \lbrack u, v \rbrack = T(u, v) = I \lbrack x(u, v), y(u, v) \rbrack @@ -581,7 +581,7 @@ Patří sem operace jako: - **Vlnka / wavelet**\ - Funkce $\psi$, která je omezená v čase. Je to "brief oscillation". [wavelet](#wavelet) + Funkce $\psi$, která je omezená v čase. Je to "brief oscillation". [^wavelet] ![width=300](./img/szp09_wavelet.svg) @@ -607,7 +607,7 @@ Patří sem operace jako: --- -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) +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] Používá se k: @@ -675,7 +675,7 @@ Dále platí: 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) +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] ## Houghova transformace @@ -683,7 +683,7 @@ Matematicky vzato, k vysoké korelaci vlnky se signálem (vysokému korelačním > Super [minutu a půl dlouhé video, co ti řekne úplně všechno](https://www.youtube.com/watch?v=X1DxCPS1iwA). -Integrální transformace, která identifikuje přímky v obraze. V rozšířené podobě hledá libovolné tvary zadané parametricky. [hough](#hough) +Integrální transformace, která identifikuje přímky v obraze. V rozšířené podobě hledá libovolné tvary zadané parametricky. [^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. @@ -708,7 +708,7 @@ Integrální transformace, která identifikuje přímky v obraze. V rozšířen 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) +Užitečná je především inverzní Radonova transformace, která se používá v tomografii ("CTčko"). [^radon] ![width=100%](./img/szp09_radon.png) @@ -771,33 +771,32 @@ Inverzní funkce je velice užitečná, ale poměrně složitá, takže doufám, | 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)]() -- [[[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)]() -- [[[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)]() -- [[[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) + +[^pb130]: [PB130 Úvod do digitálního zpracování obrazu (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PB130/) +[^pv131]: [PV131 Digitální zpracování obrazu (jaro 2023)](https://is.muni.cz/auth/el/fi/jaro2023/PV131/) +[^raster]: [Wikipedia: Raster graphics](https://en.wikipedia.org/wiki/Raster_graphics) +[^dip]: [Wikipedia: Digital image processing](https://en.wikipedia.org/wiki/Digital_image_processing) +[^filter]: [Wikipedia: Filter (signal processing)]() +[^convolution]: [Wikipedia: Convolution](https://en.wikipedia.org/wiki/Convolution) +[^edge]: [Wikipedia: Edge detection](https://en.wikipedia.org/wiki/Edge_detection) +[^fourier]: [Wikipedia: Fourier transform](https://en.wikipedia.org/wiki/Fourier_transform) +[^fft]: [Wikipedia: Fast Fourier transform](https://en.wikipedia.org/wiki/Fast_Fourier_transform) +[^samping]: [Wikipedia: Sampling (signal processing)]() +[^scaling]: [Wikipedia: Image scaling](https://en.wikipedia.org/wiki/Image_scaling) +[^n]: [Wikipedia: Nyquist–Shannon sampling theorem](https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem) +[^geometric]: [Wikipedia: Geometric transformation](https://en.wikipedia.org/wiki/Geometric_transformation) +[^reconstruction]: [Wikipedia: Signal reconstruction](https://en.wikipedia.org/wiki/Signal_reconstruction) +[^wavelet]: [Wikipedia: Wavelet transform](https://en.wikipedia.org/wiki/Wavelet_transform) +[^hough]: [Wikipedia: Hough transform](https://en.wikipedia.org/wiki/Hough_transform) +[^radon]: [Wikipedia: Radon transform](https://en.wikipedia.org/wiki/Radon_transform) +[^integral]: [Wikipedia: Integral transform](https://en.wikipedia.org/wiki/Integral_transform) +[^histogram]: [Wikipedia: Histogram](https://en.wikipedia.org/wiki/Histogram) +[^histogram]: [Wikipedia: Histogram equalization](https://en.wikipedia.org/wiki/Histogram_equalization) +[^histogram]: [Bitesize: Histograms - Higher only](https://www.bbc.co.uk/bitesize/guides/zspfcwx/revision/3) +[^sobel]: [Wikipedia: Sobel operator](https://en.wikipedia.org/wiki/Sobel_operator) +[^canny]: [Wikipedia: Canny edge detector](https://en.wikipedia.org/wiki/Canny_edge_detector) +[^canny]: [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]: [Wikipedia: Divergence (operátor)]() +[^dog]: [Wikipedia: Difference of Gaussians](https://en.wikipedia.org/wiki/Difference_of_Gaussians) +[^others]: https://hackmd.io/@fi-muni-viz-2022/SywCznl2t +[^waveleet]: [Wikipedia: Vlnka](https://cs.wikipedia.org/wiki/Vlnka) diff --git a/szmgr/SZP10_analyza_obrazu.md b/szmgr/SZP10_analyza_obrazu.md index 1324771..c5c1ca4 100644 --- a/szmgr/SZP10_analyza_obrazu.md +++ b/szmgr/SZP10_analyza_obrazu.md @@ -205,14 +205,14 @@ Popis objektů je proces, při kterém se počítají vlastnosti segmentovaných - _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) + 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] Provazochodci využívají moment setrvačnosti při chůzi po laně. ![szp10_provazochodec](./img/szp10_provazochodec.jpg) > [!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) +> "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] - **Prostorová orientace / spatial orientation**\ Směr a velikost delší strany nejmenšího bounding boxu. Lze ji také spočítat pomocí momentů setrvačnosti. @@ -351,7 +351,7 @@ Mapování, které každému pixelu popředí přiřazuje vzdálenost k nejbliž ## 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) +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] - **Binární obraz**\ Dá se vnímat jako funkce $I: \Omega \rightarrow \{0, 1\}$, kde $\Omega \sub \mathbb{Z}^2$. @@ -363,7 +363,7 @@ Teorie a techniky pro analýzu geometrických struktur. Jsou založené na teori 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) + Množina souřadnic, pomocí které je obraz zpracováván. [^pb130] - Má definovaný _počátek_ -- $(0, 0)$. Schematicky se značí křížkem. - Aktuálně uvažovaná souřadnice do něj nemusí patřit. @@ -504,7 +504,7 @@ Pracují na každém pixelu a jeho okolí -- strukturním elementu. ![width=500](./img/szp10_top_hat.png) - **Watershed**\ - Algoritmický přístup k segmentaci skrze matematickou morfologii. Kombinuje segmentaci _narůstáním oblastí_ a _detekcí hran_. [pb130](#pb130) + Algoritmický přístup k segmentaci skrze matematickou morfologii. Kombinuje segmentaci _narůstáním oblastí_ a _detekcí hran_. [^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. @@ -525,13 +525,12 @@ Pracují na každém pixelu a jeho okolí -- strukturním elementu. ![width=600](./img/szp10_watershed.png) -## 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)]() -- [[[morphology, 5]]] [Wikipedia: Mathematical morphology](https://en.wikipedia.org/wiki/Mathematical_morphology) +[^pb130]: [PB130 Úvod do digitálního zpracování obrazu (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PB130/) +[^pv131]: [PV131 Digitální zpracování obrazu (jaro 2023)](https://is.muni.cz/auth/el/fi/jaro2023/PV131/) +[^image]: [Wikipedia: Image moment](https://en.wikipedia.org/wiki/Image_moment) +[^moment]: [Wikipedia: Moment (mathematics)]() +[^morphology]: [Wikipedia: Mathematical morphology](https://en.wikipedia.org/wiki/Mathematical_morphology) ## Další zdroje diff --git a/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md b/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md index aa98a57..3b692ff 100644 --- a/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md +++ b/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md @@ -12,7 +12,7 @@ description: "TODO" ## 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) +> Poznámky o grayboxingu, iterování, modulárním workflow, atd. jsou z přednášky Lukáše Medka v rámci PV255. [^medek] - **Iterace**\ Práce v iteracích pomáhá: @@ -35,7 +35,7 @@ description: "TODO" - 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) + Využití malého množství assetů pro vytvoření rozsáhlého prostředí. Nutná promyšlená preprodukce. [^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**\ @@ -59,7 +59,7 @@ description: "TODO" ## 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ů. +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] 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). @@ -177,7 +177,7 @@ BRDF je řešena pomocí ray tracingu, radiosity, nebo nějakým hybridním ř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) + Čím větší vzdálenost, tím méně detailů. [^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. @@ -199,7 +199,7 @@ BRDF je řešena pomocí ray tracingu, radiosity, nebo nějakým hybridním ře - **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) + Popisuje, jakým způsobem se pixely textury (texely) mapují na pixely obrazovky / daného polygonu. [^texture-mapping] Součástí problému je potřeba odhadnout, jak velkou plochu polygon zabere na obrazovce. @@ -227,7 +227,7 @@ BRDF je řešena pomocí ray tracingu, radiosity, nebo nějakým hybridním ře - _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) + 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] - **Back-face culling**\ Vykreslování pouze předních stran polygonů. - **View frustum culling**\ @@ -251,11 +251,10 @@ BRDF je řešena pomocí ray tracingu, radiosity, nebo nějakým hybridním ře - 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/) +[^medek]:: [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]:: http://wiki.polycount.com/wiki/Modular_environments +[^pv227]: [PV227 GPU Rendering (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PV227/) +[^pv255]: [Chmelík, PV255 Game Development I](https://is.muni.cz/auth/el/fi/podzim2022/PV255/um/) +[^texture]: [Wikipedia: Texture mapping](https://en.wikipedia.org/wiki/Texture_mapping) +[^pa010]: [Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021)](https://is.muni.cz/auth/el/fi/podzim2021/PA010/um/) diff --git a/szmgr/VPH01_pokrocila_grafika.md b/szmgr/VPH01_pokrocila_grafika.md index da48b41..4bdf39a 100644 --- a/szmgr/VPH01_pokrocila_grafika.md +++ b/szmgr/VPH01_pokrocila_grafika.md @@ -21,7 +21,7 @@ description: "TODO" ### Redukce počtu polygonů -Slučování polygonů (merging) či odstranění polygonů (culling), které nejsou vidět. [pa010-2021](#pa010-2021) +Slučování polygonů (merging) či odstranění polygonů (culling), které nejsou vidět. [^pa010-2021] - **Variational Shape Approximation** @@ -88,35 +88,35 @@ Množina bodů v prostoru, které nemají žádnou strukturu. Nejjednodušší p 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) + 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] [^marching-cubes] **Marching cubes by [Ryoshoru](https://commons.wikimedia.org/wiki/File:MarchingCubesEdit.svg)** ![width=500rem](./img/vph01_marching_cubes.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) + 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] - **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) + 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] - **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) + 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] - **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) + 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] ![width=300](./img/vph01_delaunay.svg) ### 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) +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] 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)** +**The Process of Volume Rendering [^gpugems]** ![width=500rem](./img/vph01_direct_volume_rendering.jpg) - **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) + 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] - $\kappa$ je funkce absorpce, - $q$ je emise. @@ -140,7 +140,7 @@ V realitě tohle chování paprsku popisujeme integrály. V počítačové grafi ``` - **Volume rendering integral**\ - Intenzitu světla $I$ v místě paprsku $s$ počítáme pomocí: [pa213](#pa213) + Intenzitu světla $I$ v místě paprsku $s$ počítáme pomocí: [^pa213] ```math \begin{aligned} @@ -171,7 +171,7 @@ V realitě tohle chování paprsku popisujeme integrály. V počítačové grafi 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) + Funkce $T$, která mapuje hodnoty voxelů na barvu a průhlednost. Klasifikuje voxely. [^pa213] ## Modely nasvícení (illumination models) @@ -191,7 +191,7 @@ V realitě tohle chování paprsku popisujeme integrály. V počítačové grafi ## 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ů. +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] 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). @@ -362,21 +362,20 @@ Stíny jsou důležité, jelikož: - **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/) + +[^pa010]: Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021) +[^pa010]: Sochor: PA010 Intermediate Computer Graphics (podzim 2020) +[^pa213]: PA213 Advanced Computer Graphics +[^notes]: [Moje poznámky z PA010 (podzim 2020)](/fi/pa010/) +[^manifold]: [Wikipedia: Topological manifold](https://en.wikipedia.org/wiki/Topological_manifold) +[^klein]: [Konrad Polthier: Imaging maths - Inside the Klein bottle ](https://plus.maths.org/content/imaging-maths-inside-klein-bottle) +[^genus]: [Saul Schleimer: Notes on the complex of curves](https://www.researchgate.net/publication/228393582_Notes_on_the_complex_of_curves) +[^gpugems]: [GPU Gems: Volume Rendering Techniques](https://developer.nvidia.com/gpugems/gpugems/part-vi-beyond-triangles/chapter-39-volume-rendering-techniques) +[^marching]: [Marching cubes: A high resolution 3D surface construction algorithm](https://dl.acm.org/doi/10.1145/37402.37422) +[^marching]: [Wikipedia: Marching tetrahedra](https://en.wikipedia.org/wiki/Marching_tetrahedra) +[^dual]: [Dual Contouring Tutorial](https://www.boristhebrave.com/2018/04/15/dual-contouring-tutorial/) +[^delaunay]: [Wikipedia: Delaunay triangulation](https://en.wikipedia.org/wiki/Delaunay_triangulation) +[^pv227]: [PV227 GPU Rendering (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PV227/) ## Další zdroje diff --git a/szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.md b/szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.md index 246d1c3..2be2365 100644 --- a/szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.md +++ b/szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.md @@ -33,7 +33,7 @@ description: "TODO" ## Objekty pro detekci kolizí -V principu funguje detekce kolizí tak, že v každém kroku fyzikální simulace: [pa199-2022](#pa199-2022) +V principu funguje detekce kolizí tak, že v každém kroku fyzikální simulace: [^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.), @@ -75,6 +75,5 @@ V principu funguje detekce kolizí tak, že v každém kroku fyzikální simulac - **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/) +[^pa199]: [Chmelík, Trtík, PA199 Advanced Game Development](https://is.muni.cz/auth/el/fi/podzim2022/PA199/um/) diff --git a/szmgr/VPH02_graficke_a_fyzikalni_principy.md b/szmgr/VPH02_graficke_a_fyzikalni_principy.md index 12b5869..9df8d54 100644 --- a/szmgr/VPH02_graficke_a_fyzikalni_principy.md +++ b/szmgr/VPH02_graficke_a_fyzikalni_principy.md @@ -15,7 +15,7 @@ description: "TODO" ## 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) +> Poznámky o grayboxingu, iterování, modulárním workflow, atd. jsou z přednášky Lukáše Medka v rámci PV255. [^medek] - **Iterace**\ Práce v iteracích pomáhá: @@ -38,7 +38,7 @@ description: "TODO" - 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) + Využití malého množství assetů pro vytvoření rozsáhlého prostředí. Nutná promyšlená preprodukce. [^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**\ @@ -47,7 +47,7 @@ description: "TODO" ## 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) + Čím větší vzdálenost, tím méně detailů. [^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. @@ -69,7 +69,7 @@ description: "TODO" - **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) + Popisuje, jakým způsobem se pixely textury (texely) mapují na pixely obrazovky / daného polygonu. [^texture-mapping] Součástí problému je potřeba odhadnout, jak velkou plochu polygon zabere na obrazovce. @@ -97,7 +97,7 @@ description: "TODO" - _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) + 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] - **Back-face culling**\ Vykreslování pouze předních stran polygonů. - **View frustum culling**\ @@ -124,23 +124,23 @@ description: "TODO" ## 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) + 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] [^cel] **Cel-shaded Utah Teapot by [NicolasSourd](https://commons.wikimedia.org/w/index.php?curid=1788125)** ![width=500rem](./img/vph02_cel.png) - **Color grading**\ - Využívá se look-up table (LUT) pro jednotnou barevnou korekci. [zeleny](#zeleny) [color-grading](#color-grading) + Využívá se look-up table (LUT) pro jednotnou barevnou korekci. [^zeleny] [^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) + 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] [^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) + 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] ![width=500rem](./img/vph02_dof.png) > [!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) + > 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] ## Ray tracing / sledování paprsků @@ -165,12 +165,12 @@ Ray tracing jsou techniky, které trasují paprsky světla napříč scénou. - 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) + 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] ![width=500rem](./img/vph02_spatial_data_structure.png) - **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) + 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] Chceme od ní dvě věci: @@ -246,7 +246,7 @@ Ray tracing jsou techniky, které trasují paprsky světla napříč scénou. ## Objekty pro detekci kolizí -V principu funguje detekce kolizí tak, že v každém kroku fyzikální simulace: [pa199-2022](#pa199-2022) +V principu funguje detekce kolizí tak, že v každém kroku fyzikální simulace: [^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.), @@ -297,29 +297,28 @@ Specifický pohyb postav bezvědomí. Kombinuje animace a fyziku. Je založená - rozdělení postavy na skupiny rigid bodies, - springs and dampers -- pružiny a tlumiče. -**The first "ragdoll falling downstairs" (1997) [ragdolls](#ragdolls)** +**The first "ragdoll falling downstairs" (1997) [^ragdolls]** ![width=500rem](./img/vph02_ragdoll.jpg) - **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) + +[^medek]:: [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]:: http://wiki.polycount.com/wiki/Modular_environments +[^pa010]: Sochor: PA010 Intermediate Computer Graphics (podzim 2020) +[^cel]: https://en.wikipedia.org/wiki/Cel_shading +[^zeleny]: [Jan Zelený, Grafické efekty](++http://decibel.fi.muni.cz/pv255/2018/slides/PV255_-_09_-_Graficke_efekty.pdf++) +[^hair]: https://www.fxguide.com/fxfeatured/pixars-renderman-marschner-hair/ +[^color]: [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]: https://en.wikipedia.org/wiki/Circle_of_confusion +[^pa199]: [Chmelík, Trtík, PA199 Advanced Game Development](https://is.muni.cz/auth/el/fi/podzim2022/PA199/um/) +[^quickhull]: [Barber, Dopkin, Huhdanpaa: The Quickhull Algorithm for Convex Hulls](https://dl.acm.org/doi/pdf/10.1145/235815.235821) +[^ragdolls]: http://www.animats.com/ +[^bvh]: [Bittner: Bounding Volume Hierarchies for Ray Tracing](https://is.muni.cz/auth/el/fi/jaro2022/PA213/um/slides/BoundingVolumeHierarchiesforRayTracing.pdf) +[^path]: [Path Tracing vs. Ray Tracing, Explained](https://www.techspot.com/article/2485-path-tracing-vs-ray-tracing/) +[^bvh]: [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]: [Chmelík, PV255 Game Development I](https://is.muni.cz/auth/el/fi/podzim2022/PV255/um/) +[^pa010]: [Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021)](https://is.muni.cz/auth/el/fi/podzim2021/PA010/um/) +[^texture]: [Wikipedia: Texture mapping](https://en.wikipedia.org/wiki/Texture_mapping) diff --git a/szmgr/VPH03_herni_design_i.md b/szmgr/VPH03_herni_design_i.md index 8046f38..e96effb 100644 --- a/szmgr/VPH03_herni_design_i.md +++ b/szmgr/VPH03_herni_design_i.md @@ -8,7 +8,7 @@ Hra, videohra, desková hra, digitální hra, počítačová hra, hračka, háda _PA215, PA216_ -> Game design is an idea. An idea is worthless. An idea is not playable.[pa215-2022](#pa215-2022) [pa215-2019](#pa215-2019) +> Game design is an idea. An idea is worthless. An idea is not playable.[^pa215-2022] [^pa215-2019] > > — ZZ @@ -40,7 +40,7 @@ Definice hry je stále aktivní proces, ale zjednodušeně je to něco, co se d > > — ZZ? Asi. -**Vlastnosti her [schell](#schell)** +**Vlastnosti her [^schell]** 1. Games are **entered willfully**. 2. Games have **goals**. @@ -77,7 +77,7 @@ Useless fun fact: _Xbox_ je zkratka pro _DirectX Box_. DirectX zastřešuje něk 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). + 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]. - **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**\ @@ -109,7 +109,7 @@ Lidi jsou různí a různí lidi hrají různé hry různě. > I haven’t tried that one, what’s it do? -**Bartle’s Taxonomy of Players [pa215-2022](#pa215-2022)** +**Bartle’s Taxonomy of Players [^pa215-2022]** ![width=500rem](./img/vph03_bartle.png) @@ -118,7 +118,7 @@ Neexistuje hra, která by se líbila všem. Cílová skupina je skupina lidí, k == Komponenty hry -Na hru se dá dívat z mnoha různých perspektiv: [pa215-2019](#pa215-2019) +Na hru se dá dívat z mnoha různých perspektiv: [^pa215-2019] | Component | | --------------------------- | ------------------- | --------------------- | @@ -144,9 +144,9 @@ Hry dovedou navodit řadu různých herních zážitků, které můžeme různý ==== 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) +> Taky označované jako _Taxonomy of Game Pleasures_ a _herní "pošušňáníčka"_. [^pa215-2019] -Game designer Marc LeBlanc rozdělil herní zážitky do osmi kategorií: [leblanc](#leblanc)[mda](#mda) +Game designer Marc LeBlanc rozdělil herní zážitky do osmi kategorií: [^leblanc][^mda] - **Sensation**\ Game as sense-pleasure: beautiful visuals, good audio, tactile pleasure. @@ -218,7 +218,7 @@ Designér iterativně vytváří hrubé verze hry, které testuje a upravuje. Pr - ~~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) + - Game designer není zodpovědný za celou hru. Je jen jednou z mnoha rolí, které se na tvorbě hry podílejí. [^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. @@ -259,7 +259,7 @@ 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) +Při balancování hry designer úmyslně ničí svoji hru, aby odhalil její hranice. [^pa215-2022] **Doporučení** @@ -276,9 +276,9 @@ Zjednodušit a předat informace o tom co fungeje a co ne ostatním. Musí umět > [!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) +Lehký slovník pro popis her. [^cgo] Hodí se při komunikaci s klienty, nevyvojáři a nehráči. [^pa216-2020] -**The Core Game Ontology [cgo](#cgo)** +**The Core Game Ontology [^cgo]** ![width=100%](./img/vph03_cgo.svg) @@ -297,7 +297,7 @@ Lehký slovník pro popis her. [cgo](#cgo) Hodí se při komunikaci s klienty, n == Žá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: +Herní žánry jsou jednoduchou, byť ne zcela přesnou, klasifikací her podle jejich herních mechanik a herních smyček. [^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. @@ -320,16 +320,16 @@ Herní žánry jsou jednoduchou, byť ne zcela přesnou, klasifikací her podle == 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 +[^pa215]: https://is.muni.cz/auth/el/fi/podzim2022/PA215/index.qwarp +[^pa215]: https://is.muni.cz/auth/el/fi/podzim2019/PA215/um/ +[^schell]: Jesse Schell, _The Art of Game Design: A Book of Lenses_ +[^hadanka]: https://cs.wikipedia.org/wiki/H%C3%A1danka +[^leblanc]: http://algorithmancy.8kindsoffun.com/ +[^mda]: https://users.cs.northwestern.edu/~hunicke/pubs/MDA.pdf +[^badges]: https://kumu.io/gamebadges/gamebadges +[^cgo]: https://autosemanticgame.institutedigitalgames.com/ontologies/core-game-ontology/ +[^pa216]: https://is.muni.cz/auth/el/fi/jaro2020/PA216/index.qwarp +[^genre]: https://en.wikipedia.org/wiki/Video_game_genre == Další zdroje diff --git a/szmgr/VPH04_herni_design_ii.md b/szmgr/VPH04_herni_design_ii.md index 049458e..6fa7c00 100644 --- a/szmgr/VPH04_herni_design_ii.md +++ b/szmgr/VPH04_herni_design_ii.md @@ -42,13 +42,13 @@ Obsahuje základní informace o hře v čitelné formě pro negamedesignery (tř > > — 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) +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] [^rules-of-play] -Byť ten termín zmínil jako první Huizinga, zadefinovali a zpopularizovali ho až Salen a Zimmerman. [zimmerman-essay](#zimmerman-essay) +Byť ten termín zmínil jako první Huizinga, zadefinovali a zpopularizovali ho až Salen a Zimmerman. [^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). +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]. 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. @@ -88,7 +88,7 @@ Balanc mezi nudou a přílišnou obtížností. > [!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) +Teorie her se na _hry_ dívá jako na matematické modely, které popisují chování nějakých racionálních agentů.[^wiki] ### Typy her @@ -135,7 +135,7 @@ V dobře vybalancované _Player-vs-Player_ (PvP) hře: ## 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) +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] - text, - video, @@ -147,7 +147,7 @@ Game desiner může využít libovolné herní elementy k tomu, aby komunikoval - system itself (procedural rhetoric), - players themselves (fandom, other texts, ...). -**Interactivity with the narrative game [zagalo](#zagalo)** +**Interactivity with the narrative game [^zagalo]** ![width=500rem](./img/vph04_narrative.png) @@ -198,7 +198,7 @@ Game desiner může využít libovolné herní elementy k tomu, aby komunikoval ### 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) +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] 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ě. @@ -219,7 +219,7 @@ Jak tutoriál tak onboarding učí hráče, jak hru hrát. Onboarding je širš - **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 an early gameplay to motivate the player to play a game. [^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. @@ -303,14 +303,13 @@ Proces, kdy je game design testován na hráčích po celou dobu vývoje. A to > > — 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) + +[^magic]: https://en.wikipedia.org/wiki/Magic_circle_(virtual_worlds) +[^rules]: Salen, Katie & Zimmerman, Eric. Rules of Play: Game Design Fundamentals. 2003. +[^zimmerman]: [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]: https://en.wikipedia.org/wiki/Ergodic_literature +[^wiki]: https://en.wikipedia.org/wiki/Game_theory +[^pa215]: https://is.muni.cz/auth/el/fi/podzim2022/PA215/index.qwarp +[^zagalo]: https://www.slideshare.net/nzagalo/videogame-narrative +[^pa215]: https://is.muni.cz/auth/el/fi/podzim2019/PA215/um/ +[^fuck]: [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) diff --git a/szmgr/VPH05_vyvoj_her.md b/szmgr/VPH05_vyvoj_her.md index 7450a8a..bf430ae 100644 --- a/szmgr/VPH05_vyvoj_her.md +++ b/szmgr/VPH05_vyvoj_her.md @@ -46,7 +46,7 @@ I přes to, že je game engine obecný, neznamená to, že v něm dokážeme (ro ## 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) +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] ### Fyzická rozhraní @@ -69,7 +69,7 @@ Na _virtuální rozhraní_ si hráč nesáhne. Jsou to všemožná menu, invent - **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) + 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] **Fallout 3** @@ -112,7 +112,7 @@ BCI je technologie, která umožňuje ovládat počítač přímo pomocí myšle 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) + 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] - Layout - Typografii @@ -120,7 +120,7 @@ Zjednodušeně, UI řeší vizuální stránku rozhraní, kdežto UX tu funkčn - 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) + 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] - Průzkum uživatelských očekávání a konkurence - Wireframy a prototypování @@ -221,7 +221,7 @@ Síťová hra nemusí být multiplayer, a multiplayer hra nemusí být síťová 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).** +**State inconsistency due to latency [^netwok-delay].** ![width=400](./img/vph05_network_delay.jpg) @@ -268,7 +268,7 @@ TCP má spoustu skvělých vlastností které ho ale zpomalují. Hry proto čast ### 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) +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] - O čem hra má být. - Kdo je její cílovka. @@ -292,7 +292,7 @@ Během pre-produkce typicky vzniká řada věcí: ### 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_ 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] Produkce prochází mnoha milníky: @@ -319,7 +319,7 @@ Jakmile hra vyjde, malý tým vývojářů se stará o opravování chyb, vydáv ## 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) +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] - **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. @@ -349,9 +349,9 @@ Procedurální generování je technika, která umožňuje generovat herní asse - **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) + Noise, který vymyslel Ken Perlin, když pracoval na filmu Tron (1982) v Disney. Má tu krásnou vlastnost, že není patentovaný. [^perlin] - **Simplex noise**\ - Vylepšený Perlin noise, který taky vymyslel Ken Pelin. Tenhle už si patentovat nechal. [perlin](#perlin) + Vylepšený Perlin noise, který taky vymyslel Ken Pelin. Tenhle už si patentovat nechal. [^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ě. @@ -385,19 +385,18 @@ Serious games se dají dělit podle jejich cíle: _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á. +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] 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/ +[^netwok]: https://is.muni.cz/auth/el/fi/podzim2022/PV255/um/lec/Networking_in_computer_games.ppsx +[^cg]: https://www.cgspectrum.com/blog/game-development-process +[^g2]: https://www.g2.com/articles/stages-of-game-development +[^monetization]: https://en.wikipedia.org/wiki/Video_game_monetization +[^pv255]: https://www.fi.muni.cz/~xchmeli1/PV255/materials.cgi +[^ui]: https://www.gamedeveloper.com/design/user-interface-design-in-video-games +[^figma]: https://www.figma.com/resource-library/difference-between-ui-and-ux/ +[^perlin]: https://en.wikipedia.org/wiki/Perlin_noise +[^serious]: https://grendelgames.com/what-are-serious-games/ +[^serious]: https://grendelgames.com/serious-games-terminology/ +[^serious]: https://grendelgames.com/what-are-the-five-types-of-serious-games/ diff --git a/szmgr/VPH06_ai_ve_hrach.md b/szmgr/VPH06_ai_ve_hrach.md index 5869354..c063ef9 100644 --- a/szmgr/VPH06_ai_ve_hrach.md +++ b/szmgr/VPH06_ai_ve_hrach.md @@ -73,7 +73,7 @@ Jednoduché algoritmy pro pohyb. Jsou škálovatelné a předvídatelné, ale ma - **Seek**\ Přímočárý... doslova. Najde vektor mířící k cíli a aplikuje je jej jako steering. - **Seek schematic [steering](#steering)** + **Seek schematic [^steering]** ![Seek schematic](./img/vph06_seek.jpg) @@ -89,7 +89,7 @@ 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)** + **Arrival schematic [^steering]** ![Arrival schematic](./img/vph06_arrival.jpg) @@ -160,9 +160,9 @@ Pathfinding vnímá scénu jako graf, ve kterém hledá (obvykle nejkratší) ce ### 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) +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] -**A\* algoritmus [astar](#astar)** +**A\* algoritmus [^astar]** ![width=100%](./img/vph06_astar.png) @@ -238,7 +238,7 @@ List ReconstructPath(Node goal) { - 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) + 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] ![width=400](./img/vph06_euclidean_distance.png) @@ -255,7 +255,7 @@ List ReconstructPath(Node goal) { - **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) + Depth-first search s heuristikou. Iterative deepening znamená, že se postupně zvyšuje maximální hloubka prohledávání. [^ida-star] - **Simplified Memory Bounded A** (SMA*)*\ A\* co má nižší paměťové nároky. @@ -274,7 +274,7 @@ Agenti nevidí herní svět stejně jako hráči, vidí ho spíš jako graf s uz - **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)** + **Sid Meier’s Civilization V [^civ5]** ![width=400](./img/vph06_civilization.jpg) @@ -290,18 +290,18 @@ Agenti nevidí herní svět stejně jako hráči, vidí ho spíš jako graf s uz 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)** + **Points of visibility [^ai-for-games]** ![width=400](./img/vph06_points_of_visibility.png) - **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)** + **Navigation System in Unity [^navmesh]** ![Navigation System in Unity](./img/vph06_navmesh.png) - **Polygonal mesh graph [ai-for-games](#ai-for-games)** + **Polygonal mesh graph [^ai-for-games]** ![width=400](./img/vph06_polygonal_mesh_graph.png) @@ -328,7 +328,7 @@ Agenti obvykle musí činit rozhodnutí ohledně toho, co budou dělat dál: za 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)** +**Průchod rozhodovacím stromem [^ai-for-games]** ![width=500](./img/vph06_decision_trees.png) @@ -336,21 +336,21 @@ Rozhodnutí jsou reprezentována jako strom. Vniřní uzly jsou podmínky, listy 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)** +**State machine [^ai-for-games]** ![width=500](./img/vph06_state_machine.png) - **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)** + **Hierarchical state machine [^ai-for-games]** ![width=500](./img/vph06_hierarchical_state_machine.png) - **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)** + **State machine with decision tree transitions [^ai-for-games]** ![width=500](./img/vph06_decision_tree_state_machine.png) @@ -362,11 +362,11 @@ Reprezentuje aktuální chování agenta pomocí stavů ve stavovém automatu. K - 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)** +**Behavior tree [^ai-for-games]** ![width=500](./img/vph06_behavior_tree.png) -**Parallel behavior tree [pa217](#pa217)** +**Parallel behavior tree [^pa217]** ![width=500](./img/vph06_parallel_behavior_tree.png) @@ -411,7 +411,7 @@ Waypoint je pozice v levelu, která je něčím zajímavá. - **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)** + **Tactical locations [^ai-for-games]** ![width=500](./img/vph06_tactical_locations.png) @@ -510,10 +510,10 @@ Minmax i alpha-beta pruning se chápe nejlíp s vizualizací. Můžete kouknout - **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) + Algoritmy a techniky spoléhající na náhodou, mega velké množiny vzorků a statistickou analýzu. [^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) + Heuristický algoritmus pro prohledávání stromových grafů. V kontextu deskových her se používá pro hledání nejlepšího tahu.[^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. @@ -540,14 +540,13 @@ Minmax i alpha-beta pruning se chápe nejlíp s vizualizací. Můžete kouknout - $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*) + +[^pa217]: PA217 AI for Games +[^ai]: Ian Millington, John Funge: Artificial Intelligence for Games +[^steering]: [Steering Behaviors](https://slsdo.github.io/steering-behaviors/) +[^navmesh]: [Navigation System in Unity](https://docs.unity3d.com/Manual/nav-NavigationSystem.html) +[^astar]: [Introduction to the A\* Algorithm](https://www.redblobgames.com/pathfinding/a-star/introduction.html) +[^civ5]: [Sid Meier’s Civilization V](https://store.steampowered.com/app/8930/Sid_Meiers_Civilization_V/) +[^monte]: [Wikipedia: Monte Carlo method](https://en.wikipedia.org/wiki/Monte_Carlo_method) +[^mcts]: [Wikipedia: Monte Carlo tree search](https://en.wikipedia.org/wiki/Monte_Carlo_tree_search) +[^ida]: [Wikipedia: Iterative deepening A\*](https://en.wikipedia.org/wiki/Iterative_deepening_A*) diff --git a/szmgr/VPH07_gpu_rendering.md b/szmgr/VPH07_gpu_rendering.md index 5aa9917..669c56c 100644 --- a/szmgr/VPH07_gpu_rendering.md +++ b/szmgr/VPH07_gpu_rendering.md @@ -40,12 +40,12 @@ description: "TODO" > [!IMPORTANT] > Tahle část otázky má značný překryv s otázkou [Modelování a projekce](../szp08_modelovani_a_projekce/). -**Coordinate Systems [coordinate-systems](#coordinate-systems)** +**Coordinate Systems [^coordinate-systems]** ![width=100%](./img/vph07_coordinate_systems.png) - **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) + 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] | Editor | Handedness | $X$ | $Y$ | $Z$ | | --------- | ------------ | ------- | ---------- | ---------- | @@ -66,7 +66,7 @@ description: "TODO" - **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) + 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] Tento prostor stále používá 4-dimenzionální homogenní souřadnice. @@ -81,10 +81,10 @@ description: "TODO" 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) + > Počátek (origin) viewport space je **vlevo dole** a má ve výchozím nastavení má souřadnice $(0, 0)$. [^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í: + 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] V OpenGL tedy platí: | Space | Handedness | $X$ | $Y$ | $Z$ | | -------- | ---------------------- | ------- | ------ | -------------------------- | @@ -96,13 +96,13 @@ description: "TODO" | _Window_ | _left-handed_ | doprava | nahoru | **dopředu** | > [!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) + > 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] ## Pipeline (typy shaderů) -Při zvolání `glDraw*` se používá OpenGL pipeline, která se skládá z několika fází: [pipeline](#pipeline) +Při zvolání `glDraw*` se používá OpenGL pipeline, která se skládá z několika fází: [^pipeline] -**Diagram of the Rendering Pipeline [pipeline](#pipeline)** +**Diagram of the Rendering Pipeline [^pipeline]** ![vph07_pipeline](./img/vph07_pipeline.png) @@ -119,7 +119,7 @@ Při zvolání `glDraw*` se používá OpenGL pipeline, která se skládá z ně - **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) + OpenGL následně: [^post-process] 1. sestaví primitives, 2. ořeže je podle **user** clip space (nastavené programátorem v VS nebo GS pomocí `gl_ClipDistance`), @@ -186,7 +186,7 @@ Při zvolání `glDraw*` se používá OpenGL pipeline, která se skládá z ně 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)** +**The Shadow Mapping Depth Comparison [^shadow-maps]** ![width=500rem](./img/vph07_shadow_maps.jpg) @@ -218,12 +218,12 @@ Při zvolání `glDraw*` se používá OpenGL pipeline, která se skládá z ně ![width=500rem](./img/vph07_cascaded_shadow_maps.png) - **Soft shadow maps -- Percentage-Closer Filtering (PCF)**\ - Rozmazává stíny uniformě fixním kernelem. [pa010-2021](#pa010-2021) + Rozmazává stíny uniformě fixním kernelem. [^pa010-2021] ![width=500rem](./img/vph07_soft_shadows_pcf.png) - **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) + 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] ```math w_\text{penumbra} = \frac{p_z^s - z_\text{avg}}{z_\text{avg}} w_\text{light} @@ -233,7 +233,7 @@ Při zvolání `glDraw*` se používá OpenGL pipeline, která se skládá z ně ## 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) +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] Tuto techniku použijeme např. když máme ve scéně fakt hodně světel. @@ -264,7 +264,7 @@ Tuto techniku použijeme např. když máme ve scéně fakt hodně světel. - **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)** + **Aliasing [^anti-aliasing]** ![width=500rem](./img/vph07_aliasing.png) @@ -275,7 +275,7 @@ Tuto techniku použijeme např. když máme ve scéně fakt hodně světel. - **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)** + **MSAA [^anti-aliasing]** ![width=500rem](./img/vph07_msaa.png) @@ -290,25 +290,24 @@ Ambient occlusion approximuje, jak moc je objekt vystaven ambientním světlu. J - **Screen-Space Ambient Occlusion (SSAO)**\ Dívá se na okolí daného pixelu (v G-bufferu) a odhaduje tak jeho okluzi. - **SSAO [ssao](#ssao)** + **SSAO [^ssao]** ![width=500rem](./img/vph07_ssao.png) -## 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) + +[^pipeline]: [Rendering Pipeline Overview](https://www.khronos.org/opengl/wiki/Rendering_Pipeline_Overview) +[^post]: [Vertex Post-Processing](https://www.khronos.org/opengl/wiki/Vertex_Post-Processing) +[^coordinate]: [LearnOpenGL: Coordinate Systems](https://learnopengl.com/Getting-started/Coordinate-Systems) +[^sw]: [Verge3D Wiki: Coordinate Systems](https://www.soft8soft.com/wiki/index.php/Coordinate_Systems) +[^viewport]: [`glViewport`](https://registry.khronos.org/OpenGL-Refpages/gl4/html/glViewport.xhtml) +[^depth]: [`glDepthRange`](https://registry.khronos.org/OpenGL-Refpages/gl4/html/glDepthRange.xhtml) +[^vulkan]: [Vulkan’s coordinate system](http://anki3d.org/vulkan-coordinate-system/) +[^pv227]: [PV227 GPU Rendering (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PV227/) +[^anti]: [LearnOpenGL: Anti-Aliasing](https://learnopengl.com/Advanced-OpenGL/Anti-Aliasing) +[^ambient]: [Wikipedia: Ambient occlusion](https://en.wikipedia.org/wiki/Ambient_occlusion) +[^ssao]: [LearnOpenGL: SSAO](https://learnopengl.com/Advanced-Lighting/SSAO) +[^shadow]: [The Cg Tutorial: Shadow Mapping](https://developer.download.nvidia.com/CgTutorial/cg_tutorial_chapter09.html) +[^pa010]: Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021) ## Další zdroje diff --git a/szmgr/VPH08_modelovani_3d_postav.md b/szmgr/VPH08_modelovani_3d_postav.md index cd71b67..8d1f13b 100644 --- a/szmgr/VPH08_modelovani_3d_postav.md +++ b/szmgr/VPH08_modelovani_3d_postav.md @@ -46,7 +46,7 @@ description: "TODO" 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. + Grafická reprezentace uživatele či uživatelovy postavy. [^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ě @@ -91,20 +91,20 @@ description: "TODO" - **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) + 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] 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)** + **Flowing edge loops and good topology are crucial for rigging and animation [^organic]** ![width=500rem](./img/vph08_organic_modeling.jpg) - **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) + 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] - **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) + Proces, kdy začneme od [default cube](https://www.youtube.com/watch?v=SDeVyxtdSUk), subdividneme ji a pokračujeme odtamtaď. [^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) + 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] ## Textury @@ -116,7 +116,7 @@ Typický 3D model se skládá nejen z meshe, ale i z materiálů, které jsou v - **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)** + **Result of unwrapping Suzanne [^uv-unwrap]** ![width=500rem](./img/vph08_uv_unwrapping.png) @@ -140,7 +140,7 @@ Typický 3D model se skládá nejen z meshe, ale i z materiálů, které jsou v - **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) + 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] ## Kostra modelu @@ -159,9 +159,9 @@ Typický 3D model se skládá nejen z meshe, ale i z materiálů, které jsou v > — 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) + 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] - **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) + Animujeme jen koncové kosti. Pohyb rodičovských kostí je dopočítán. Klouby se hýbou po přímkách. [^fk-ik] - **T-pose / reference pose**\ Defaultní póza pro charakter při riggování. @@ -170,18 +170,17 @@ Typický 3D model se skládá nejen z meshe, ale i z materiálů, které jsou v ![width=300](./img/vph08_tpose.jpg) - **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) + Úprava kostry tak, aby se povrch modelu správně deformoval při animaci. [^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. + + +[^avatar]: https://en.wikipedia.org/wiki/Avatar_(computing) +[^vv036]: [VV036 3D Character Modeling (jaro 2023)](https://is.muni.cz/auth/el/fi/jaro2023/VV036/) +[^quads]: [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]: [Tips and tricks for organic modelling](https://www.creativebloq.com/tips-and-tricks-organic-modelling-7123070) +[^texture]: [Texture Baking](http://wiki.polycount.com/wiki/Texture_Baking) +[^fk]: [FK and IK Explained - Which One to Use and When?](https://www.youtube.com/watch?v=0a9qIj7kwiA) +[^envelopes]: [Blender: Deform](https://docs.blender.org/manual/en/latest/animation/armatures/bones/properties/deform.html) +[^uv]: [Blender: Unwrapping > Mapping Types](https://docs.blender.org/manual/en/2.79/editors/uv_image/uv/editing/unwrapping/mapping_types.html) ## Další zdroje From 21e85ca4d467d63bd8a0aab1682d7c58cecb6116 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Sat, 7 Jun 2025 09:34:03 +0200 Subject: [PATCH 09/44] Fix tables manually --- szmgr/SZP01_algoritmy.md | 99 +++++--------------- szmgr/SZP03_statistika.md | 44 ++++----- szmgr/SZP07_grafy.md | 17 ++-- szmgr/SZP09_zpracovani_obrazu.md | 17 ++-- szmgr/VPH01_pokrocila_grafika.md | 2 +- szmgr/VPH02_graficke_a_fyzikalni_principy.md | 2 +- szmgr/VPH03_herni_design_i.md | 77 +++++++-------- 7 files changed, 101 insertions(+), 157 deletions(-) diff --git a/szmgr/SZP01_algoritmy.md b/szmgr/SZP01_algoritmy.md index ad154c4..2bceb4a 100644 --- a/szmgr/SZP01_algoritmy.md +++ b/szmgr/SZP01_algoritmy.md @@ -161,19 +161,13 @@ Technika hledání řešení problému postupným sestavováním _kandidátního **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. | +| 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 @@ -265,21 +259,11 @@ Pro každou operaci v posloupnosti: **Zásobník (kredity)** -| Operace | -| --------------- | -| Skutečná cena | -| Kreditová cena | -| `Push` | -| 1 | -| 2 | -| `Pop` | -| 1 | -| 0 | -| `Multi-Pop` | -| stem:[\min(k,\ | -| S\ | -| )] | -| 0 | +| Operace | Skutečná cena | Kreditová cena | +| --------------- | ----------------------- | --------------- | +| `Push` | 1 | 2 | +| `Pop` | 1 | 0 | +| `Multi-Pop` | $min(k, \vert S \vert)$ | 0 | - **Invariant**\ Počet kreditů na účtu je rovný počtu prvků na zásobníku. @@ -327,29 +311,12 @@ Hraje si s představou toho, že struktura je fyzikální systém s nějakou ene $\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\ | -| )] | -| | + +| Operace | Skutečná cena | Kreditová cena | +| --------------- | ------------- | --------------- | +| `Push` | 1 | $\hat{c_i} = 1 + (\vert S \vert + 1) - \vert S \vert = 2$ | +| `Pop` | 1 | $\hat{c_i} = 1 + \vert S \vert - (\vert S \vert + 1) = 0$ | +| `Multi-Pop` | $min(k, \vert S \vert )$ | _(následující formule)_ | ```math \hat{c_i} = @@ -434,29 +401,13 @@ Většinou je řetězec polem znaků z konečné abecedy $\Sigma$. String matchi 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] -| 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)$ | +| 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 | $\Theta(m \cdot \vert \Sigma \vert)$ | $\Theta(n)$ | +| Knuth-Morris-Pratt | $\Theta(m)$ | $\Theta(m)$ | +| Boyer-Moore | $\Theta(m + \vert \Sigma \vert)$ | $\mathcal{O}((n - m + 1) \cdot m)$ | - $T$ nebo $T\lbrack 1..n \rbrack$ -- text. - $P$ nebo $P\lbrack 1..m \rbrack$ -- pattern. diff --git a/szmgr/SZP03_statistika.md b/szmgr/SZP03_statistika.md index 4ade435..7083aa0 100644 --- a/szmgr/SZP03_statistika.md +++ b/szmgr/SZP03_statistika.md @@ -109,28 +109,28 @@ Jinými slovy, NV $X : \Omega \to \R$ je _spojitá_, pokud se prvky $\Omega$ zob 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$ | +#### 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í | $ P(k, p) = \begin{cases} \frac{1}{\vert A \vert} & x \in A \\ 0 & \text{jinak} \\ \end{cases} $ | Když jsou všechny jevy x z dané množiny A stejně pravděpodobné | Hod d20 | + +#### 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$ | $ f(x, n) = \frac{ \Gamma (\frac{n+1}{2}) }{ \sqrt{n \pi} \Gamma(\frac{n}{2}) } \left( 1 + \frac{x^2}{n} \right)^{-\frac{n+1}{2}} $ | Používá se na odhadování meanu normálně distribuované populace, jejíž rozptyl neznáš (což je skoro vždycky), ale máš z ní samply. | Odhadování průměru výšky lidí | ### Číselné charakteristiky diff --git a/szmgr/SZP07_grafy.md b/szmgr/SZP07_grafy.md index 18c8e64..a6365cc 100644 --- a/szmgr/SZP07_grafy.md +++ b/szmgr/SZP07_grafy.md @@ -5,9 +5,7 @@ description: "TODO" > [!NOTE] > 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_ - +>
> _IB000, IB002, IV003_ > [!TIP] > Tahle otázka má solidní překryv s bakalářskými otázkami [Grafy](../../szb/grafy/) a [Grafové problémy](../../szb/grafove-problemy/). @@ -286,12 +284,12 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces **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 | +| 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 | $\mathcal{O}(\lvert E \rvert \log \lvert V \rvert )$ | $\mathcal{O}( \lvert V \rvert )$ | ## Toky v sítích @@ -557,7 +555,6 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces ![width=300](./img/szp07_mcm_03.png) - [^ib000]: [IB000 Matematické základy informatiky (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/IB000/um/) [^ib002]: [IB002 Algoritmy a datové struktury (jaro 2020)](https://is.muni.cz/auth/el/fi/jaro2020/IB002/um/) [^ib003]: [IV003 Algoritmy a datové struktury II (jaro 2021)](https://is.muni.cz/auth/el/fi/jaro2021/IV003/um/) diff --git a/szmgr/SZP09_zpracovani_obrazu.md b/szmgr/SZP09_zpracovani_obrazu.md index dc2dfc4..60145fe 100644 --- a/szmgr/SZP09_zpracovani_obrazu.md +++ b/szmgr/SZP09_zpracovani_obrazu.md @@ -759,17 +759,12 @@ Inverzní funkce je velice užitečná, ale poměrně složitá, takže doufám, **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ů | +| 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ů | [^pb130]: [PB130 Úvod do digitálního zpracování obrazu (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PB130/) diff --git a/szmgr/VPH01_pokrocila_grafika.md b/szmgr/VPH01_pokrocila_grafika.md index 4bdf39a..aaf51a4 100644 --- a/szmgr/VPH01_pokrocila_grafika.md +++ b/szmgr/VPH01_pokrocila_grafika.md @@ -4,7 +4,7 @@ description: "TODO" --- > [!WARNING] -> Tato je stará verze otázky. Nová verze: [Grafické principy ve vývoji her](./VPH01_graficke_principy_ve_vyvoji_her.ad). +> Tato je stará verze otázky. Nová verze: [Grafické principy ve vývoji her](../VPH01_graficke_principy_ve_vyvoji_her). > [!NOTE] > 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ů. diff --git a/szmgr/VPH02_graficke_a_fyzikalni_principy.md b/szmgr/VPH02_graficke_a_fyzikalni_principy.md index 9df8d54..bcfafb7 100644 --- a/szmgr/VPH02_graficke_a_fyzikalni_principy.md +++ b/szmgr/VPH02_graficke_a_fyzikalni_principy.md @@ -4,7 +4,7 @@ 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). +> Tato je stará verze otázky. Nová verze: [Fyzikální principy ve vývoji her](../VPH02_fyzikalni_principy_ve_vyvoji_her). > [!NOTE] > 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. diff --git a/szmgr/VPH03_herni_design_i.md b/szmgr/VPH03_herni_design_i.md index e96effb..1d794b4 100644 --- a/szmgr/VPH03_herni_design_i.md +++ b/szmgr/VPH03_herni_design_i.md @@ -3,7 +3,7 @@ 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_ @@ -20,7 +20,7 @@ _PA215, PA216_ > > — Taky ZZ -== Hra +## Hra > Hra... je zbytečný termín. > @@ -83,7 +83,7 @@ Takže _Xbox X_ je vlastně _DirectX Box X_. Microsoft fakt neumí pojmenovávat - **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áčů +## Typy hráčů Lidi jsou různí a různí lidi hrají různé hry různě. @@ -113,24 +113,25 @@ Lidi jsou různí a různí lidi hrají různé hry různě. ![width=500rem](./img/vph03_bartle.png) -=== Cílová skupina +### 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 +## Komponenty hry Na hru se dá dívat z mnoha různých perspektiv: [^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) +| 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) | Behaviour of system / rules of interaction | SFX, enemy AI, narration, ...​ | + +### Herní zážitek (Experience) Games are only means for a greater goal - creating experience. @@ -141,7 +142,7 @@ Hry dovedou navodit řadu různých herních zážitků, které můžeme různý > [!IMPORTANT] > Herní zážitky souvisí s pojmem obtížnost, kterému se věnuje část otázky [Herní design II](../vph04_herni_design_ii/). -==== LeBlanc’s Eight Kinds of Fun +#### LeBlanc’s Eight Kinds of Fun > [!TIP] > Taky označované jako _Taxonomy of Game Pleasures_ a _herní "pošušňáníčka"_. [^pa215-2019] @@ -165,42 +166,42 @@ Game designer Marc LeBlanc rozdělil herní zážitky do osmi kategorií: [^lebl - **Submission / masochism**\ Game as mindless pastime: submission to game structures, mutual agreement to "play". -=== Herní smyčky (Loops) +### 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) +### Herní dynamika (Dynamics) Strategie, způsoby hraní. Chování hráče, které se noří z toho, jak používá mechaniky. -=== Element / Ludeme +### Element / Ludeme Základní jednotka hry. Třeba L-pohyb koně v šachu. -=== Herní mechaniky +### 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 +### 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 +## Game Design Anchor and Hook -=== Herní zaháčkování (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) +### Herní kotva (Anchor) Něco známeho, povědomého pro hráče. -== Prototypování her +## 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](../vph04_herni_design_ii/). -== Game Designer +## Game Designer > Artist = inner calling = intimate. > @@ -224,7 +225,7 @@ Designér iterativně vytváří hrubé verze hry, které testuje a upravuje. Pr - Designuje změny, modeluje následky, rozhoduje, posuzuje produkční rizika. - Komunikuje. Hájí hru před ne-designery. -=== Kreativní činnost +### Kreativní činnost Nejlepším nástrojem game designera je tužka a papír. Papírový prototyp je pro začátek dost. @@ -234,7 +235,7 @@ Kromě nich ale existuje: - [Bitsy](http://www.bitsy.org/#0,0), - [Flickgame](https://www.flickgame.org/). -=== Abstraktní činnost +### Abstraktní činnost Game designer produkuje taky hromady abstraktních teorií o herním designu. @@ -247,7 +248,7 @@ Game designer produkuje taky hromady abstraktních teorií o herním designu. > — Ano, stále ZZ -=== Analytická činnost +### Analytická činnost ...je tak trochu psychoanalýza. @@ -257,7 +258,7 @@ Game designer produkuje taky hromady abstraktních teorií o herním designu. Ale bacha na mylné závěry. Game designeři mají často zvláštní chutě. -=== Systematická činnost -- game balancing +### Systematická činnost -- game balancing Při balancování hry designer úmyslně ničí svoji hru, aby odhalil její hranice. [^pa215-2022] @@ -268,10 +269,10 @@ Při balancování hry designer úmyslně ničí svoji hru, aby odhalil její hr - **Zapisuj** si co děláš, protože pamatovat si to fakt nebudeš. - Chápej **numerické / elementální atributy** svojí hry. -=== Komunikační činnost +### 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 +## The Core Game Ontology > [!NOTE] > Ontologie -- disciplína zabývající se bytím a základními pojmy jako je realita, existence, atp. @@ -295,7 +296,7 @@ Lehký slovník pro popis her. [^cgo] Hodí se při komunikaci s klienty, nevyvo - **Gameplay**\ Consists of the players strategies whilst playing a game. -== Žánry +## Žánry Herní žánry jsou jednoduchou, byť ne zcela přesnou, klasifikací her podle jejich herních mechanik a herních smyček. [^genre] Hrá může zapadat do jednoho nebo více žánrů. Jsou jimi například: @@ -318,7 +319,11 @@ Herní žánry jsou jednoduchou, byť ne zcela přesnou, klasifikací her podle - **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 + +## Další zdroje + +- [Greg Costikyan: I Have No Words & I Must Design: Toward a Critical Vocabulary for Game](http://www.costik.com/nowords2002.pdf) + [^pa215]: https://is.muni.cz/auth/el/fi/podzim2022/PA215/index.qwarp [^pa215]: https://is.muni.cz/auth/el/fi/podzim2019/PA215/um/ @@ -330,7 +335,3 @@ Herní žánry jsou jednoduchou, byť ne zcela přesnou, klasifikací her podle [^cgo]: https://autosemanticgame.institutedigitalgames.com/ontologies/core-game-ontology/ [^pa216]: https://is.muni.cz/auth/el/fi/jaro2020/PA216/index.qwarp [^genre]: 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) From 7d2a14ccc7bc38798a7e414971c7ba12c105fa60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Sat, 7 Jun 2025 10:29:28 +0200 Subject: [PATCH 10/44] Revert "Use markdown footnotes" This reverts commit c35a357e07f89f91e071628ad94274c8d3161da9. Only the content files --- szmgr/PGV03_zaklady_pocitatcove_grafiky.md | 19 ++-- szmgr/PGV04_geometricke_algoritmy.md | 5 +- szmgr/PGV05_deleni_prostoru_a_sceny.md | 5 +- szmgr/PGV06_vykreslovani_objemovych_dat.md | 39 +++---- szmgr/PGV07_modely_osvetleni.md | 9 +- szmgr/PGV08_real_time_rendering.md | 3 +- szmgr/SZP01_algoritmy.md | 21 ++-- szmgr/SZP02_numericke_metody.md | 69 +++++------ szmgr/SZP03_statistika.md | 63 ++++++----- szmgr/SZP04_3d_modelovani.md | 69 +++++------ szmgr/SZP05_krivky_a_povrchy.md | 55 ++++----- szmgr/SZP06_strojove_uceni.md | 51 +++++---- szmgr/SZP07_grafy.md | 16 +-- szmgr/SZP08_modelovani_a_projekce.md | 2 +- szmgr/SZP09_zpracovani_obrazu.md | 107 +++++++++--------- szmgr/SZP10_analyza_obrazu.md | 21 ++-- .../VPH01_graficke_principy_ve_vyvoji_her.md | 25 ++-- szmgr/VPH01_pokrocila_grafika.md | 53 ++++----- .../VPH02_fyzikalni_principy_ve_vyvoji_her.md | 5 +- szmgr/VPH02_graficke_a_fyzikalni_principy.md | 65 +++++------ szmgr/VPH03_herni_design_i.md | 48 ++++---- szmgr/VPH04_herni_design_ii.md | 37 +++--- szmgr/VPH05_vyvoj_her.md | 45 ++++---- szmgr/VPH06_ai_ve_hrach.md | 59 +++++----- szmgr/VPH07_gpu_rendering.md | 61 +++++----- szmgr/VPH08_modelovani_3d_postav.md | 43 +++---- 26 files changed, 512 insertions(+), 483 deletions(-) diff --git a/szmgr/PGV03_zaklady_pocitatcove_grafiky.md b/szmgr/PGV03_zaklady_pocitatcove_grafiky.md index f2f4d0c..7f8338d 100644 --- a/szmgr/PGV03_zaklady_pocitatcove_grafiky.md +++ b/szmgr/PGV03_zaklady_pocitatcove_grafiky.md @@ -13,7 +13,7 @@ description: "TODO" ![width=600](./img/pgv03_block_diagram.png) -Blokový diagram je abstraktní, high-level popis fungování OpenGL [^pv112]. +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](../szp08_modelovani_a_projekce), osvětlení jednotlivých vrcholů @@ -266,7 +266,7 @@ Z Primitive assembly dostáváme bod, čáru, nebo trojúhelník, který potřeb ![width=300](./img/pgv03_rast_point.png) - **Úsečka**\ - Při rasterizaci úsečky použijeme Bresenhamův algoritmus [^pb009]. Poslední bod úsečky zůstane nevykreslený (half-open) kvůli návaznosti na další úsečky. + 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 @@ -320,7 +320,7 @@ void Application::bresenham(glm::vec2 start, glm::vec2 end, Raster& raster, Colo - **Trojúhelník** -Při rasterizaci trojúhelníku můžeme použít Pinedaův algoritmus [^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. +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. @@ -369,12 +369,13 @@ Výhodami syntetizovaných textur je: - parametrizovatelnost > [!NOTE] -> 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] a [^synthesis2]. +> 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). +## Zdroje -[^pv112]: Byška: PV112 Computer Graphics API -[^pb009]: Byška: PB009 Principles of Computer Graphics -[^glsl_tutorial]: https://cgvr.cs.uni-bremen.de/teaching/cg2_07/literatur/glsl_tutorial/index.html -[^synthesis1]: https://en.wikipedia.org/wiki/Texture_synthesis -[^synthesis2]: https://diglib.eg.org:8443/server/api/core/bitstreams/90ad4c13-45b1-4ec0-8ef2-76075b2c73ae/content +- [[[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 diff --git a/szmgr/PGV04_geometricke_algoritmy.md b/szmgr/PGV04_geometricke_algoritmy.md index d83d8e5..1ece134 100644 --- a/szmgr/PGV04_geometricke_algoritmy.md +++ b/szmgr/PGV04_geometricke_algoritmy.md @@ -58,7 +58,7 @@ Tento algoritmus má složitost $O(n h)$, kde n je počet bodů a h je počet bo ### 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]. +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)$ @@ -273,5 +273,6 @@ Range trees jsou paměťově náročnější, zato jsou rychlejší. - Konstrukce: $O(n \log^{d-1} n)$ - Vyhledávání: $O(\log^{d} n + k)$ +## Zdroje -[^so_hull_3d]: https://stackoverflow.com/a/74968910/22953817 +- [[[so_hull_3d,1]]] https://stackoverflow.com/a/74968910/22953817 diff --git a/szmgr/PGV05_deleni_prostoru_a_sceny.md b/szmgr/PGV05_deleni_prostoru_a_sceny.md index aaa5ede..fe9ae86 100644 --- a/szmgr/PGV05_deleni_prostoru_a_sceny.md +++ b/szmgr/PGV05_deleni_prostoru_a_sceny.md @@ -44,7 +44,7 @@ Složitost vytvoření Octree/Quadtree je $O(n \log n)$. Složitost vyhledáván ### k-D stromy -(Převzato z 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. +(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. ![width=600](./img/pgv04_kd_build.png) @@ -153,5 +153,6 @@ Detekce kolizí je proces, kdy testujeme, zda se dva objekty v prostoru dotýkaj 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]: ../geometricke_algoritmy/ +- [[[pgv04,1]]] ../geometricke_algoritmy/ diff --git a/szmgr/PGV06_vykreslovani_objemovych_dat.md b/szmgr/PGV06_vykreslovani_objemovych_dat.md index 35af9ca..9e2ff74 100644 --- a/szmgr/PGV06_vykreslovani_objemovych_dat.md +++ b/szmgr/PGV06_vykreslovani_objemovych_dat.md @@ -38,7 +38,7 @@ Před samotnou rekonstrukcí je často potřeba provézt ještě předzpracován - **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] + 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í. @@ -51,7 +51,7 @@ Před samotnou rekonstrukcí je často potřeba provézt ještě předzpracován ### 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] + 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) ![width=300](./img/vph01_delaunay.svg) @@ -60,9 +60,9 @@ Před samotnou rekonstrukcí je často potřeba provézt ještě předzpracován - **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] 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ů. + [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] + 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** @@ -103,14 +103,14 @@ Před samotnou rekonstrukcí je často potřeba provézt ještě předzpracován ![width=500rem](./img/vph01_marching_cubes.svg) - 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] + 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] + 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**\ @@ -119,22 +119,22 @@ Před samotnou rekonstrukcí je často potřeba provézt ještě předzpracován ![width=500](./img/pgv06_surface_nets.png) - **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] + 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) ![width=500](./img/pgv06_dual_contouring.png) ### 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] +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]** +**The Process of Volume Rendering [gpugems](#gpugems)** ![width=500rem](./img/vph01_direct_volume_rendering.jpg) - **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] + 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. @@ -158,7 +158,7 @@ V realitě tohle chování paprsku popisujeme integrály. V počítačové grafi ``` - **Volume rendering integral**\ - Intenzitu světla $I$ v místě paprsku $s$ počítáme pomocí: [^pa213] + Intenzitu světla $I$ v místě paprsku $s$ počítáme pomocí: [pa213](#pa213) ```math \begin{aligned} @@ -189,13 +189,14 @@ V realitě tohle chování paprsku popisujeme integrály. V počítačové grafi 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] + Funkce $T$, která mapuje hodnoty voxelů na barvu a průhlednost. Klasifikuje voxely. [pa213](#pa213) +## Zdroje -[^pa010]: Sochor: PA010 Intermediate Computer Graphics (podzim 2020) -[^pa213]: PA213 Advanced Computer Graphics -[^marching]: [Marching cubes: A high resolution 3D surface construction algorithm](https://dl.acm.org/doi/10.1145/37402.37422) -[^marching]: [Wikipedia: Marching tetrahedra](https://en.wikipedia.org/wiki/Marching_tetrahedra) -[^dual]: [Dual Contouring Tutorial](https://www.boristhebrave.com/2018/04/15/dual-contouring-tutorial/) -[^delaunay]: [Wikipedia: Delaunay triangulation](https://en.wikipedia.org/wiki/Delaunay_triangulation) -[^gpugems]: [GPU Gems: Volume Rendering Techniques](https://developer.nvidia.com/gpugems/gpugems/part-vi-beyond-triangles/chapter-39-volume-rendering-techniques) +- [[[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) diff --git a/szmgr/PGV07_modely_osvetleni.md b/szmgr/PGV07_modely_osvetleni.md index 94e6109..dc33d67 100644 --- a/szmgr/PGV07_modely_osvetleni.md +++ b/szmgr/PGV07_modely_osvetleni.md @@ -21,7 +21,7 @@ description: "TODO" ## 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] +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) ![width=600](./img/pgv07_phong_overview.png) @@ -127,7 +127,7 @@ Participující média jsou média, která nejsou zcela průhledná, ale nejsou ## 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] Aproximuje efekty jako absorpci světla nebo jeho rozptyl pod povrchem objektů. +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). @@ -242,6 +242,7 @@ Pro výpočet spekulárního osvětlení se používá zrcadlový vektor a Fresn ![width=600](./img/pgv07_ibr.png) +## Zdroje -[^pv227]: [PV227 GPU Rendering (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PV227/) -[^pb009]: [Interaktivní osnova PB009 by xrosecky](https://is.muni.cz/auth/el/fi/jaro2023/PB009/index.qwarp) +- [[[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) diff --git a/szmgr/PGV08_real_time_rendering.md b/szmgr/PGV08_real_time_rendering.md index 58a178e..a2d6383 100644 --- a/szmgr/PGV08_real_time_rendering.md +++ b/szmgr/PGV08_real_time_rendering.md @@ -242,5 +242,6 @@ Stíny jsou důležité, jelikož: - **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]: Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021) +- [[[pa010-2021,1]]] Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021) diff --git a/szmgr/SZP01_algoritmy.md b/szmgr/SZP01_algoritmy.md index 2bceb4a..463c6e2 100644 --- a/szmgr/SZP01_algoritmy.md +++ b/szmgr/SZP01_algoritmy.md @@ -153,7 +153,7 @@ Greedy algoritmy nachází řešení globálního problému tak, že volí loká _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] +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. @@ -399,7 +399,7 @@ _String matching_ označuje rodinu problémů obsahující třeba: 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] +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 | | ----------------------------------- | ------------------------------------ | ----------------------------------- | @@ -469,7 +469,7 @@ int KarpRabin(string text, string pattern) - **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] Předpokládejme, že $\Sigma = \{0, 1, ..., 9\}$ (velikost může být libovolná), pak pro hash $h$ platí + 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*} @@ -552,7 +552,7 @@ Jinými slovy na indexu druhého `D` je `abcD` nejdelší prefix $P$, který je - **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] + Složitost hledání je pak v $\Theta(n)$. [iv003-strings](#iv003-strings) ### Knuth-Morris-Pratt (KMP) @@ -623,14 +623,15 @@ int KnuthMorrisPratt(string text, string pattern) > 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] +> "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]: [IV003 Algoritmy a datové struktury II (jaro 2021)](https://is.muni.cz/auth/el/fi/jaro2021/IV003/) -[^iv003]: https://is.muni.cz/auth/el/fi/jaro2021/IV003/um/slides/stringmatching.pdf -[^rabin]: https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm -[^horner]: https://en.wikipedia.org/wiki/Horner%27s_method -[^backtracking]: https://betterprogramming.pub/the-technical-interview-guide-to-backtracking-e1a03ca4abad +- [[[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 diff --git a/szmgr/SZP02_numericke_metody.md b/szmgr/SZP02_numericke_metody.md index 651dccd..f7b64ad 100644 --- a/szmgr/SZP02_numericke_metody.md +++ b/szmgr/SZP02_numericke_metody.md @@ -10,7 +10,7 @@ description: "TODO" - **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] + 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. @@ -26,12 +26,12 @@ description: "TODO" - **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] + 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] [^numericka-metoda] [^order-question] + 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} @@ -47,16 +47,16 @@ description: "TODO" ## 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] + 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] [^root-finding] + 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] + 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)$. @@ -88,7 +88,7 @@ description: "TODO" ![width=400](./img/szp02_secant_method.png) - **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] + 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) @@ -100,7 +100,7 @@ description: "TODO" ### 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] Povoleny jsou následující operace: +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, @@ -108,7 +108,7 @@ Systém rovnice je přepsán do matice. Gaussova eliminace je posloupnost operac ### 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] +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: @@ -178,7 +178,7 @@ Jelikož $L + U = A - D$, dá to zapsat i jako: ### 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] +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: @@ -203,7 +203,7 @@ T_{gs} &= (D + L)^{-1} U = 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] +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*} @@ -274,7 +274,7 @@ Metody podobné Gaussově eliminaci, ale s vlastnostmi, které mohou být vyhodn ## 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] +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_). @@ -285,7 +285,7 @@ Numerická diferenciace se využívá pro aproximaci differenciálních rovnic ( > Lagrangeovu interpolaci řeší část otázky [Křivky a povrchy](../szp05_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] + 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_. @@ -293,7 +293,7 @@ Numerická diferenciace se využívá pro aproximaci differenciálních rovnic ( > 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] + Nejjednodušší schéma numerické diferenciace. Vychází z definice derivace. [finite-difference](#finite-difference) - _Dopředná diference / forward (finite) difference_ @@ -319,23 +319,24 @@ Numerická diferenciace se využívá pro aproximaci differenciálních rovnic ( > Tečna je tak napodobena sečnou. - **Richardson extrapolation**\ - Způsob zlepšení rate of convergence iterativních metod. [^richardson] - - -[^ma018]: [MA018 Numerical Methods (podzim 2019)](https://is.muni.cz/auth/el/fi/podzim2019/MA018/) -[^numerical]: [Wikipedia: Numerical analysis](https://en.wikipedia.org/wiki/Numerical_analysis) -[^root]: [Wikipedia: Root-finding algorithms](https://en.wikipedia.org/wiki/Root-finding_algorithms) -[^rate]: [Wikipedia: Rate of convergence](https://en.wikipedia.org/wiki/Rate_of_convergence) -[^regula]: [Wikipedia: Regula falsi](https://en.wikipedia.org/wiki/Regula_falsi) -[^gauss]: [Wikipedia: Gaussian elimination](https://en.wikipedia.org/wiki/Gaussian_elimination) -[^jacobi]: [Wikipedia: Jacobi method](https://en.wikipedia.org/wiki/Jacobi_method) -[^gauss]: [Wikipedia: Gauss-Seidel method](https://en.wikipedia.org/wiki/Gauss%E2%80%93Seidel_method) -[^relaxation]: [Wikipedia: Relaxation (iterative method)]() -[^differentiation]: [Wikipedia: Numerical differentiation](https://en.wikipedia.org/wiki/Numerical_differentiation) -[^finite]: [Wikipedia: Finite difference](https://en.wikipedia.org/wiki/Finite_difference) -[^finite]: [Wikipedia: Finite difference method](https://en.wikipedia.org/wiki/Finite_difference_method) -[^richardson]: [Wikipedia: Richardson extrapolation](https://en.wikipedia.org/wiki/Richardson_extrapolation) -[^linear]: [Wikipedia: System of linear equations](https://en.wikipedia.org/wiki/System_of_linear_equations) -[^numerical]: [Wikipedia: Numerical stability](https://en.wikipedia.org/wiki/Numerical_stability) -[^numericka]: [Wikipedia: Numerická metoda](https://cs.wikipedia.org/wiki/Numerick%C3%A1_metoda) -[^order]: [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) + 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)]() +- [[[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) diff --git a/szmgr/SZP03_statistika.md b/szmgr/SZP03_statistika.md index 7083aa0..266af06 100644 --- a/szmgr/SZP03_statistika.md +++ b/szmgr/SZP03_statistika.md @@ -15,7 +15,7 @@ description: "TODO" > 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] + 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í. @@ -142,7 +142,7 @@ Stejně jako náhodné veličiny popisují jevy, číselné charakteristiky popi 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] + > 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. @@ -173,7 +173,7 @@ Jak moc se od sebe prvky liší (nezávisle na konstantním posunutí)? ``` > [!NOTE] - > Taky někdy označovaný jako _centrální moment druhého řádu / druhý centrální moment_. [^moment] + > 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}$. @@ -283,7 +283,7 @@ Popisuje chování _výběrového průměru_ pro velké soubory vzorků a umož - **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] + 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: @@ -299,7 +299,7 @@ Popisuje chování _výběrového průměru_ pro velké soubory vzorků a umož > ``` > [!TIP] - > _Estimator_ je funkce počítající statistiku použitá k odhadu parametru. [^statistic] + > _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. @@ -363,9 +363,9 @@ Máme vzorek velikosti $n$ s výběrovým průměrem $\overline{X}$ a výběrov > 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] + 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] + Metoda odhadu parametru založená na rovnosti teoretického a výběrového momentu. [mom](#mom) ## Testování statistických hypotéz @@ -377,7 +377,7 @@ Máme vzorek velikosti $n$ s výběrovým průměrem $\overline{X}$ a výběrov - _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] + 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_). > @@ -407,7 +407,7 @@ Platí presumpce nevinny. Předpokládáme, že člověk zločin nespáchal, dok - **$p$-hodnota (hladina významnosti)**\ - Nejmenší hladina významnosti $\alpha$, při které ještě zamítáme $H_0$. [^p-value] + 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í. @@ -423,9 +423,9 @@ Platí presumpce nevinny. Předpokládáme, že člověk zločin nespáchal, dok 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] + 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] + 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 @@ -436,7 +436,7 @@ Neparametrické testy nejsou založené (jen) na parametrech pravděpodobnostní - **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] + Umožňuje ověřit, že dvě kategorické NV jsou nezávislé. [chi-squared](#chi-squared) ### Testy (ne)závislosti náhodných veličin @@ -448,7 +448,7 @@ Neparametrické testy nejsou založené (jen) na parametrech pravděpodobnostní **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] + - 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** @@ -520,21 +520,22 @@ Neparametrické testy nejsou založené (jen) na parametrech pravděpodobnostní Testová statistika má Studentovo t-rozdělení. - -[^statistics]: [Wikipedia: Statistics](https://en.wikipedia.org/wiki/Statistics) -[^nv]: [Wikipedia: Náhodná veličina](https://cs.wikipedia.org/wiki/N%C3%A1hodn%C3%A1_veli%C4%8Dina) -[^cdf]: [Wikipedia: Cumulative distribution function](https://en.wikipedia.org/wiki/Cumulative_distribution_function) -[^mean]: [Wikipedia: Mean](https://en.wikipedia.org/wiki/Mean) -[^clv]: [Wikipedia: Centrální limitní věta](https://cs.wikipedia.org/wiki/Centr%C3%A1ln%C3%AD_limitn%C3%AD_v%C4%9Bta) -[^consistent]: [Wikipedia: Consistent estimator](https://en.wikipedia.org/wiki/Consistent_estimator) -[^statistic]: [Wikipedia: Statistic](https://en.wikipedia.org/wiki/Statistic) -[^mle]: [Wikipedia: Maximum likelihood estimation](https://en.wikipedia.org/wiki/Maximum_likelihood_estimation) -[^mom]: [Wikipedia: Method of moments]() -[^null]: [Wikipedia: Null hypothesis](https://en.wikipedia.org/wiki/Null_hypothesis) -[^p]: [Wikipedia: P-hodnota](https://cs.wikipedia.org/wiki/P-hodnota) -[^mv013]: [MV013 Statistics for Computer Science (jaro 2021)](https://is.muni.cz/auth/el/fi/jaro2021/MV013/) -[^anova]: [Wikipedia: Analysis of variance](https://en.wikipedia.org/wiki/Analysis_of_variance) -[^nezavislost]: [Wikipedia: Statistická nezávislost](https://cs.wikipedia.org/wiki/Statistick%C3%A1_nez%C3%A1vislost) -[^t]: [Wikipedia: T-test](https://cs.wikipedia.org/wiki/T-test) -[^chi]: [Chi-square tests](https://www.scribbr.com/statistics/chi-square-tests/) -[^moment]: [Momenty rozdělení](http://kfe.fjfi.cvut.cz/~limpouch/sigdat/pravdh/node10.html) +## 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]() +- [[[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) diff --git a/szmgr/SZP04_3d_modelovani.md b/szmgr/SZP04_3d_modelovani.md index 10a0acc..7c89106 100644 --- a/szmgr/SZP04_3d_modelovani.md +++ b/szmgr/SZP04_3d_modelovani.md @@ -16,21 +16,21 @@ description: "TODO" - **Geometrie** - Mění jí deformace. - Např. to, kde jsou body. - - Zahrnuje zakřivení (curvature), plochu (area), vzdálenosti mezi body, atd. [^pa010-2021] + - 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] + - Sousednost (neighborhood), souvislost (connectedness), adjacency. atd. [pa010-2021](#pa010-2021) - **Topology [^topology]** + **Topology [topology](#topology)** ![Topology](./img/szp04_topology.png) - **Topological manifold**\ - Prostor/útvar, který lokálně _připomíná_ (je homeomorfní) $n$-dimenzionální Euklidovský prostor. [^pa010-2021] [^manifold-wiki] + 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] + $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). @@ -38,7 +38,7 @@ description: "TODO" - 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] + - Každý povrch je 2-manifold až na neuzavřené hrany. [pa010-2021](#pa010-2021) - $n$-dimenzionální koule je $n$-manifold. ![width=100%](./img/szp04_manifold.png) @@ -85,7 +85,7 @@ description: "TODO" > [!TIP] > Je to **maximální** počet těch řezů. >
- > Následující povrch[^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í**. + > 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í**. >
> ![width=500rem](./img/szp04_genus.png) @@ -207,12 +207,12 @@ description: "TODO" - 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] + 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] [^boundaries] + 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. @@ -263,7 +263,7 @@ description: "TODO" - `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] + 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$. @@ -274,11 +274,11 @@ description: "TODO" _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]** + **Schéma interior and a boundary tělesa $A \cap B$ [pa010-2021](#pa010-2021)** ![width=200](./img/szp04_interior_boundary.png) - **Příklad regularizovaného průniku [^pa010-2021]** + **Příklad regularizovaného průniku [pa010-2021](#pa010-2021)** ![width=100%](./img/szp04_rbo.png) @@ -325,29 +325,29 @@ description: "TODO" > 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](../vph01_pokrocila_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] + 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) ![width=400](./img/szp04_edge_flip.png) - **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] + 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) ![width=400](./img/szp04_edge_split.png) - **Zhroucení grany / edge collapse**\ - Lokální změna, která nahrazuje hranu vrcholem. [^pa010-2021] + Lokální změna, která nahrazuje hranu vrcholem. [pa010-2021](#pa010-2021) ![width=400](./img/szp04_edge_collapse.png) - **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] + 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) ![width=400](./img/szp04_subdivision.png) - **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] + Globální upráva s cílem zlepšit kvalitu meshe, např.: tvar trojúhelníků a četnost vertexů. [pa010-2021](#pa010-2021) ![width=400](./img/szp04_mesh_regularization.png) @@ -359,7 +359,7 @@ description: "TODO" 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] + 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) ![width=400](./img/szp04_isotropic_remeshing.png) @@ -417,10 +417,10 @@ _Když máme objekt definovaný polévkou matematických symbolů místo hromád - _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] + 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] + 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)$, @@ -428,7 +428,7 @@ _Když máme objekt definovaný polévkou matematických symbolů místo hromád - _Komplement_: $-f$. - **Bloby (kapky)**\ - Součet několika Gaussových křivek. [^pa010-2020] + Součet několika Gaussových křivek. [pa010-2020](#pa010-2020) ```math \begin{align*} @@ -450,7 +450,7 @@ _Když máme objekt definovaný polévkou matematických symbolů místo hromád ![width=300](./img/szp04_blobs.png) - **Metaballs**\ - Podobné blobům, ale nepoužívá exponenciální funkci. Organicky se "slévající" koule. [^pa010-2020] + Podobné blobům, ale nepoužívá exponenciální funkci. Organicky se "slévající" koule. [pa010-2020](#pa010-2020) ```math \begin{align*} @@ -475,15 +475,16 @@ _Když máme objekt definovaný polévkou matematických symbolů místo hromád ![width=100%](./img/szp04_metaballs.png) - -[^pa010]: Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021) -[^pa010]: Sochor: PA010 Intermediate Computer Graphics (podzim 2020) -[^notes]: [Moje poznámky z PA010 (podzim 2020)](/fi/pa010/) -[^manifold]: [Wikipedia: Topological manifold](https://en.wikipedia.org/wiki/Topological_manifold) -[^klein]: [Konrad Polthier: Imaging maths - Inside the Klein bottle ](https://plus.maths.org/content/imaging-maths-inside-klein-bottle) -[^genus]: [Saul Schleimer: Notes on the complex of curves](https://www.researchgate.net/publication/228393582_Notes_on_the_complex_of_curves) -[^topology]: [Topology vs. Geometry](https://www.austincc.edu/herbling/shape-of-space.pdf) -[^boundaries]: [Ian Stroud: Boundary Representation Modelling Techniques](https://link.springer.com/book/10.1007/978-1-84628-616-2) -[^rbo]: [Interior, Exterior and Closure](https://pages.mtu.edu/~shene/COURSES/cs3621/NOTES/model/closure.html) -[^validity]: [Representational validity of boundary representation models](https://www.sciencedirect.com/science/article/pii/S0010448500000476) -[^denoising]: [Bilateral Normal Filtering for Mesh Denoising](https://ieeexplore.ieee.org/document/5674028) +## 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) diff --git a/szmgr/SZP05_krivky_a_povrchy.md b/szmgr/SZP05_krivky_a_povrchy.md index 0e8a39e..f9dd4a0 100644 --- a/szmgr/SZP05_krivky_a_povrchy.md +++ b/szmgr/SZP05_krivky_a_povrchy.md @@ -218,22 +218,22 @@ Křivka $Q$ patří do třídy $C^n$, pokud má ve všech bodech $t$ spojitou de ### 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] [^geometric-continuity] +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] +- $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] Podle Barskyho a DeRoseho musí v první derivaci být $> 0$ a v dalších už je to šumák. [^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. +> 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] +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} @@ -259,7 +259,7 @@ 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] + Metoda evaluace polynomů. Vychází z myšlenky, že násobení se dá nestovat: [horner](#horner) ```math \begin{aligned} @@ -279,7 +279,7 @@ Asi nejznámnější interpolační křivky v počítačové grafice. Jsou urče 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] [^ferguson] + Pro Hermitovskou kubiku platí: [hermite-spline](#hermite-spline) [ferguson](#ferguson) ```math \begin{aligned} @@ -365,12 +365,12 @@ Mezi jejich vlastnosti patří: ### B-spline - **Splajn / spline**\ - Splajn stupně $n$ po částech definovaná polynomiální funkce stupně $n-1$ proměnné $x$. [^bspline] + 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] + - 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ý. --- @@ -428,7 +428,7 @@ S(x) = \sum_{i=0} c_i B_{i,n}(x) ``` - **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] + 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} @@ -606,7 +606,7 @@ Aproximační plochy analogické B-spline křivkám, ale se dvěma parametry. - **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] Jsou invariantní k lineárním transformacím i k perspektivní projekci. + 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} @@ -621,7 +621,7 @@ Aproximační plochy analogické B-spline křivkám, ale se dvěma parametry. $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] +> 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ů @@ -659,22 +659,23 @@ Polygonové povrchy dělíme v případě, kdy chceme je zjemnit, vyhladit. **Interpoluje** původní mesh. Funguje jen na trojúhelníkové síti. - -[^pa010]: Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021) -[^pa010]: Sochor: PA010 Intermediate Computer Graphics (podzim 2020) -[^pb009]: Sochor: PB009 Principles of Computer Graphics (jaro 2019) -[^smoothness]: [Wikipedia: Smoothness](https://en.wikipedia.org/wiki/Smoothness) -[^mallinus]: [Jaakko Kurhila and Matti Mäkelä: Parametric Curves](https://www.cs.helsinki.fi/group/goa/mallinnus/curves/curves.html) -[^geometric]: [Geometric Continuity of Parametric Curves: Three Equivalent Characterizations](https://ieeexplore.ieee.org/document/41470) -[^lagrange]: [Wikipedia: Lagrange polynomial](https://en.wikipedia.org/wiki/Lagrange_polynomial) -[^bspline]: [Wikipedia: B-spline](https://en.wikipedia.org/wiki/B-spline) -[^hermite]: [Wikipedia: Cubic Hermite spline](https://en.wikipedia.org/wiki/Cubic_Hermite_spline) -[^ferguson]: [ČVUT: Ferguson curve](https://marian.fsik.cvut.cz/~kongo/download/pcgr/lectures/01%20crv_ferg.pdf) -[^coons]: [ČVUT: Coons curve](https://marian.fsik.cvut.cz/~kongo/download/pcgr/lectures/03%20crv_coons.pdf) -[^coons]: [Wikipedia: Coons patch](https://en.wikipedia.org/wiki/Coons_patch) -[^nurbs]: [Wikipedia: Non-uniform rational B-spline](https://en.wikipedia.org/wiki/Non-uniform_rational_B-spline) -[^sweeping]: [Wikipedia: Solid modeling](https://en.wikipedia.org/wiki/Solid_modeling#Sweeping) -[^horner]: [Wikipedia: Horner’s method](https://en.wikipedia.org/wiki/Horner%27s_method) +## 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 diff --git a/szmgr/SZP06_strojove_uceni.md b/szmgr/SZP06_strojove_uceni.md index 3d0ea05..22e584a 100644 --- a/szmgr/SZP06_strojove_uceni.md +++ b/szmgr/SZP06_strojove_uceni.md @@ -16,7 +16,7 @@ description: "TODO" - **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] [^pv021] + 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: @@ -28,23 +28,23 @@ description: "TODO" - 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] + 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] + 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] + 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] + 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] + 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] + 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] + 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ě @@ -92,7 +92,7 @@ description: "TODO" - **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] + - 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ě. ![width=400](./img/szp06_perceptron.png) @@ -274,7 +274,7 @@ Za předpokladu, že $E$ je squared error, pak: ## 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] +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](../szp09_zpracovani_obrazu/). @@ -319,7 +319,7 @@ Neuronové sítě uzpůsobené ke zpracování obrazu. Místo násobení matic p ## 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] +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** @@ -430,17 +430,18 @@ Neuronové sítě, jejichž architektura obsahuje cykly. Tedy výstup v jednom b ![width=100%](./img/szp06_lstm.png) - -[^pv021]: T. Brázdil: PV021 Neural Networks -[^ml]: [Wikipedia: Machine learning](https://en.wikipedia.org/wiki/Machine_learning) -[^classification]: [Wikipedia: Statistical classification](https://en.wikipedia.org/wiki/Statistical_classification) -[^regression]: [Wikipedia: Regression analysis](https://en.wikipedia.org/wiki/Regression_analysis) -[^clustering]: [Wikipedia: Cluster analysis](https://en.wikipedia.org/wiki/Cluster_analysis) -[^pattern]: [Wikipedia: Pattern recognition](https://en.wikipedia.org/wiki/Pattern_recognition) -[^hopfield]: [Wikipedia: Hopfield network](https://en.wikipedia.org/wiki/Hopfield_network) -[^hebb]: [Wikipedia: Hebbian theory](https://en.wikipedia.org/wiki/Hebbian_theory) -[^cnn]: [Wikipedia: Convolutional neural network](https://en.wikipedia.org/wiki/Convolutional_neural_network) -[^rnn]: [Wikipedia: Recurrent neural network](https://en.wikipedia.org/wiki/Recurrent_neural_network) -[^som]: [Wikipedia: Self-organizing map](https://en.wikipedia.org/wiki/Self-organizing_map) -[^som]: [Self-Organizing Maps: Tutorial](https://sites.pitt.edu/~is2470pb/Spring05/FinalProjects/Group1a/tutorial/som.html) -[^som]: [SDL Component Suite: Kohonen Network](http://www.lohninger.com/helpcsuite/kohonen_network_-_background_information.htm) +## 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) diff --git a/szmgr/SZP07_grafy.md b/szmgr/SZP07_grafy.md index a6365cc..1b290d8 100644 --- a/szmgr/SZP07_grafy.md +++ b/szmgr/SZP07_grafy.md @@ -526,7 +526,7 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces ## 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] + 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í. @@ -539,7 +539,7 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces - **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] + 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)$. @@ -555,11 +555,13 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces ![width=300](./img/szp07_mcm_03.png) -[^ib000]: [IB000 Matematické základy informatiky (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/IB000/um/) -[^ib002]: [IB002 Algoritmy a datové struktury (jaro 2020)](https://is.muni.cz/auth/el/fi/jaro2020/IB002/um/) -[^ib003]: [IV003 Algoritmy a datové struktury II (jaro 2021)](https://is.muni.cz/auth/el/fi/jaro2021/IV003/um/) -[^matching]: [Wikipedia: Párování grafu](https://cs.wikipedia.org/wiki/P%C3%A1rov%C3%A1n%C3%AD_grafu) -[^mcm]: [Wikipedia: Maximum cardinality matching](https://en.wikipedia.org/wiki/Maximum_cardinality_matching) +## 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 diff --git a/szmgr/SZP08_modelovani_a_projekce.md b/szmgr/SZP08_modelovani_a_projekce.md index 04748bf..58a0518 100644 --- a/szmgr/SZP08_modelovani_a_projekce.md +++ b/szmgr/SZP08_modelovani_a_projekce.md @@ -91,7 +91,7 @@ description: A guide in my new Starlight docs site. ### Ortografická projekce -Používáme především k vykreslení 2D scén. Osu Z můžeme využít, abychom jeden sprite schovali za jiný. Nicméně objekty dál od kamery jsou stejně velké jako ty blízko kamery. [^camera] +Používáme především k vykreslení 2D scén. Osu Z můžeme využít, abychom jeden sprite schovali za jiný. Nicméně objekty dál od kamery jsou stejně velké jako ty blízko kamery. [camera](#camera) ![width=500](./img/szp08_orthographic_projection.png) diff --git a/szmgr/SZP09_zpracovani_obrazu.md b/szmgr/SZP09_zpracovani_obrazu.md index 60145fe..0379dd3 100644 --- a/szmgr/SZP09_zpracovani_obrazu.md +++ b/szmgr/SZP09_zpracovani_obrazu.md @@ -10,12 +10,12 @@ description: "TODO" - **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] + 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] + 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, @@ -133,7 +133,7 @@ Histogram kvantifikuje množství a frekvenci barev obsažených v obraze. Ve st ``` - **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] + 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. @@ -151,7 +151,7 @@ Histogram kvantifikuje množství a frekvenci barev obsažených v obraze. Ve st > 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-bbc] + 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, @@ -162,7 +162,7 @@ Histogram kvantifikuje množství a frekvenci barev obsažených v obraze. Ve st ## 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] + 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: @@ -172,7 +172,7 @@ Histogram kvantifikuje množství a frekvenci barev obsažených v obraze. Ve st - _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] + 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 @@ -340,7 +340,7 @@ Proces, kdy hledání _hran_ v obraze. Hrana je křivka, podél níž pixely vý - **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-tds] + Algoritmus pro detekci hran. [canny](#canny) [canny-tds](#canny-tds) - Má nízké procento chyb. - Přesně lokalizuje hrany. @@ -360,7 +360,7 @@ Proces, kdy hledání _hran_ v obraze. Hrana je křivka, podél níž pixely vý 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 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} @@ -411,7 +411,7 @@ Hrany lze detekovat pomocí druhé derivace obrazu. Nacházejí se v _nulových ## 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] +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: @@ -430,7 +430,7 @@ Patří sem transformace jako: > 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...)_ -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] +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. @@ -464,7 +464,7 @@ Je operace (integrální transformace) při níž je obraz převeden z _prostoro }_{\text{pro všechna } x \text{ v celém definičním oboru funkce} f} ``` - **Forward** (z prostorové do frekvenční domény): [^fourier] + **Forward** (z prostorové do frekvenční domény): [fourier](#fourier) ```math \begin{align*} @@ -487,7 +487,7 @@ Je operace (integrální transformace) při níž je obraz převeden z _prostoro ``` - **2D Fourierova transformace**\ - **Forward** (z prostorové do frekvenční domény): [^fourier] + **Forward** (z prostorové do frekvenční domény): [fourier](#fourier) ```math \begin{align*} @@ -510,9 +510,9 @@ Je operace (integrální transformace) při níž je obraz převeden z _prostoro ``` - **Fast Fourier Transform (FFT)**\ - Algoritmus pro rychlé výpočty diskrétní Fourierovy transformace (DFT). [^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] + Ří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 \} @@ -522,15 +522,15 @@ Je operace (integrální transformace) při níž je obraz převeden z _prostoro ## Sampling / vzorkování -Samplování je převod spojitého signálu na diskrétní. [^sampling] +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] + 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] + Ří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. @@ -542,7 +542,7 @@ Samplování je převod spojitého signálu na diskrétní. [^sampling] > 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] + 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. @@ -554,7 +554,7 @@ Samplování je převod spojitého signálu na diskrétní. [^sampling] ## 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] +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 @@ -581,7 +581,7 @@ Patří sem operace jako: - **Vlnka / wavelet**\ - Funkce $\psi$, která je omezená v čase. Je to "brief oscillation". [^wavelet] + Funkce $\psi$, která je omezená v čase. Je to "brief oscillation". [wavelet](#wavelet) ![width=300](./img/szp09_wavelet.svg) @@ -607,7 +607,7 @@ Patří sem operace jako: --- -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] +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: @@ -675,7 +675,7 @@ Dále platí: 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] +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 @@ -683,7 +683,7 @@ Matematicky vzato, k vysoké korelaci vlnky se signálem (vysokému korelačním > Super [minutu a půl dlouhé video, co ti řekne úplně všechno](https://www.youtube.com/watch?v=X1DxCPS1iwA). -Integrální transformace, která identifikuje přímky v obraze. V rozšířené podobě hledá libovolné tvary zadané parametricky. [^hough] +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. @@ -708,7 +708,7 @@ Integrální transformace, která identifikuje přímky v obraze. V rozšířen 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] +Užitečná je především inverzní Radonova transformace, která se používá v tomografii ("CTčko"). [radon](#radon) ![width=100%](./img/szp09_radon.png) @@ -766,32 +766,33 @@ Inverzní funkce je velice užitečná, ale poměrně složitá, takže doufám, | 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ů | - -[^pb130]: [PB130 Úvod do digitálního zpracování obrazu (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PB130/) -[^pv131]: [PV131 Digitální zpracování obrazu (jaro 2023)](https://is.muni.cz/auth/el/fi/jaro2023/PV131/) -[^raster]: [Wikipedia: Raster graphics](https://en.wikipedia.org/wiki/Raster_graphics) -[^dip]: [Wikipedia: Digital image processing](https://en.wikipedia.org/wiki/Digital_image_processing) -[^filter]: [Wikipedia: Filter (signal processing)]() -[^convolution]: [Wikipedia: Convolution](https://en.wikipedia.org/wiki/Convolution) -[^edge]: [Wikipedia: Edge detection](https://en.wikipedia.org/wiki/Edge_detection) -[^fourier]: [Wikipedia: Fourier transform](https://en.wikipedia.org/wiki/Fourier_transform) -[^fft]: [Wikipedia: Fast Fourier transform](https://en.wikipedia.org/wiki/Fast_Fourier_transform) -[^samping]: [Wikipedia: Sampling (signal processing)]() -[^scaling]: [Wikipedia: Image scaling](https://en.wikipedia.org/wiki/Image_scaling) -[^n]: [Wikipedia: Nyquist–Shannon sampling theorem](https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem) -[^geometric]: [Wikipedia: Geometric transformation](https://en.wikipedia.org/wiki/Geometric_transformation) -[^reconstruction]: [Wikipedia: Signal reconstruction](https://en.wikipedia.org/wiki/Signal_reconstruction) -[^wavelet]: [Wikipedia: Wavelet transform](https://en.wikipedia.org/wiki/Wavelet_transform) -[^hough]: [Wikipedia: Hough transform](https://en.wikipedia.org/wiki/Hough_transform) -[^radon]: [Wikipedia: Radon transform](https://en.wikipedia.org/wiki/Radon_transform) -[^integral]: [Wikipedia: Integral transform](https://en.wikipedia.org/wiki/Integral_transform) -[^histogram]: [Wikipedia: Histogram](https://en.wikipedia.org/wiki/Histogram) -[^histogram]: [Wikipedia: Histogram equalization](https://en.wikipedia.org/wiki/Histogram_equalization) -[^histogram]: [Bitesize: Histograms - Higher only](https://www.bbc.co.uk/bitesize/guides/zspfcwx/revision/3) -[^sobel]: [Wikipedia: Sobel operator](https://en.wikipedia.org/wiki/Sobel_operator) -[^canny]: [Wikipedia: Canny edge detector](https://en.wikipedia.org/wiki/Canny_edge_detector) -[^canny]: [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]: [Wikipedia: Divergence (operátor)]() -[^dog]: [Wikipedia: Difference of Gaussians](https://en.wikipedia.org/wiki/Difference_of_Gaussians) -[^others]: https://hackmd.io/@fi-muni-viz-2022/SywCznl2t -[^waveleet]: [Wikipedia: Vlnka](https://cs.wikipedia.org/wiki/Vlnka) +## 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)]() +- [[[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)]() +- [[[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)]() +- [[[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) diff --git a/szmgr/SZP10_analyza_obrazu.md b/szmgr/SZP10_analyza_obrazu.md index c5c1ca4..1324771 100644 --- a/szmgr/SZP10_analyza_obrazu.md +++ b/szmgr/SZP10_analyza_obrazu.md @@ -205,14 +205,14 @@ Popis objektů je proces, při kterém se počítají vlastnosti segmentovaných - _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] + 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ě. ![szp10_provazochodec](./img/szp10_provazochodec.jpg) > [!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" 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. @@ -351,7 +351,7 @@ Mapování, které každému pixelu popředí přiřazuje vzdálenost k nejbliž ## 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] +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$. @@ -363,7 +363,7 @@ Teorie a techniky pro analýzu geometrických struktur. Jsou založené na teori 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] + 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. @@ -504,7 +504,7 @@ Pracují na každém pixelu a jeho okolí -- strukturním elementu. ![width=500](./img/szp10_top_hat.png) - **Watershed**\ - Algoritmický přístup k segmentaci skrze matematickou morfologii. Kombinuje segmentaci _narůstáním oblastí_ a _detekcí hran_. [^pb130] + 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. @@ -525,12 +525,13 @@ Pracují na každém pixelu a jeho okolí -- strukturním elementu. ![width=600](./img/szp10_watershed.png) +## Zdroje -[^pb130]: [PB130 Úvod do digitálního zpracování obrazu (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PB130/) -[^pv131]: [PV131 Digitální zpracování obrazu (jaro 2023)](https://is.muni.cz/auth/el/fi/jaro2023/PV131/) -[^image]: [Wikipedia: Image moment](https://en.wikipedia.org/wiki/Image_moment) -[^moment]: [Wikipedia: Moment (mathematics)]() -[^morphology]: [Wikipedia: Mathematical morphology](https://en.wikipedia.org/wiki/Mathematical_morphology) +- [[[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)]() +- [[[morphology, 5]]] [Wikipedia: Mathematical morphology](https://en.wikipedia.org/wiki/Mathematical_morphology) ## Další zdroje diff --git a/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md b/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md index 3b692ff..aa98a57 100644 --- a/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md +++ b/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md @@ -12,7 +12,7 @@ description: "TODO" ## 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] +> 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á: @@ -35,7 +35,7 @@ description: "TODO" - 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] + 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**\ @@ -59,7 +59,7 @@ description: "TODO" ## 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] Aproximuje efekty jako absorpci světla nebo jeho rozptyl pod povrchem objektů. +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). @@ -177,7 +177,7 @@ BRDF je řešena pomocí ray tracingu, radiosity, nebo nějakým hybridním ře ## Optimizalizace výkonu vykreslování - **Level-of-detail (LOD) / úrovně detailů**\ - Čím větší vzdálenost, tím méně detailů. [^pv255-2022] + Čí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. @@ -199,7 +199,7 @@ BRDF je řešena pomocí ray tracingu, radiosity, nebo nějakým hybridním ře - **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] + 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. @@ -227,7 +227,7 @@ BRDF je řešena pomocí ray tracingu, radiosity, nebo nějakým hybridním ře - _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] + 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**\ @@ -251,10 +251,11 @@ BRDF je řešena pomocí ray tracingu, radiosity, nebo nějakým hybridním ře - Minimalizovat počet materiálů (např. spojováním textur). - Vypéct všechni nedynamické (statická světla, stíny, atd.) +## Zdroje -[^medek]:: [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]:: http://wiki.polycount.com/wiki/Modular_environments -[^pv227]: [PV227 GPU Rendering (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PV227/) -[^pv255]: [Chmelík, PV255 Game Development I](https://is.muni.cz/auth/el/fi/podzim2022/PV255/um/) -[^texture]: [Wikipedia: Texture mapping](https://en.wikipedia.org/wiki/Texture_mapping) -[^pa010]: [Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021)](https://is.muni.cz/auth/el/fi/podzim2021/PA010/um/) +- [[[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/) diff --git a/szmgr/VPH01_pokrocila_grafika.md b/szmgr/VPH01_pokrocila_grafika.md index aaf51a4..b86982b 100644 --- a/szmgr/VPH01_pokrocila_grafika.md +++ b/szmgr/VPH01_pokrocila_grafika.md @@ -21,7 +21,7 @@ description: "TODO" ### Redukce počtu polygonů -Slučování polygonů (merging) či odstranění polygonů (culling), které nejsou vidět. [^pa010-2021] +Slučování polygonů (merging) či odstranění polygonů (culling), které nejsou vidět. [pa010-2021](#pa010-2021) - **Variational Shape Approximation** @@ -88,35 +88,35 @@ Množina bodů v prostoru, které nemají žádnou strukturu. Nejjednodušší p 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] [^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)** ![width=500rem](./img/vph01_marching_cubes.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] + 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] + 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] + 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] + 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) ![width=300](./img/vph01_delaunay.svg) ### 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] +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]** +**The Process of Volume Rendering [gpugems](#gpugems)** ![width=500rem](./img/vph01_direct_volume_rendering.jpg) - **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] + 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. @@ -140,7 +140,7 @@ V realitě tohle chování paprsku popisujeme integrály. V počítačové grafi ``` - **Volume rendering integral**\ - Intenzitu světla $I$ v místě paprsku $s$ počítáme pomocí: [^pa213] + Intenzitu světla $I$ v místě paprsku $s$ počítáme pomocí: [pa213](#pa213) ```math \begin{aligned} @@ -171,7 +171,7 @@ V realitě tohle chování paprsku popisujeme integrály. V počítačové grafi 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] + Funkce $T$, která mapuje hodnoty voxelů na barvu a průhlednost. Klasifikuje voxely. [pa213](#pa213) ## Modely nasvícení (illumination models) @@ -191,7 +191,7 @@ V realitě tohle chování paprsku popisujeme integrály. V počítačové grafi ## 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] Aproximuje efekty jako absorpci světla nebo jeho rozptyl pod povrchem objektů. +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). @@ -362,20 +362,21 @@ Stíny jsou důležité, jelikož: - **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. - -[^pa010]: Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021) -[^pa010]: Sochor: PA010 Intermediate Computer Graphics (podzim 2020) -[^pa213]: PA213 Advanced Computer Graphics -[^notes]: [Moje poznámky z PA010 (podzim 2020)](/fi/pa010/) -[^manifold]: [Wikipedia: Topological manifold](https://en.wikipedia.org/wiki/Topological_manifold) -[^klein]: [Konrad Polthier: Imaging maths - Inside the Klein bottle ](https://plus.maths.org/content/imaging-maths-inside-klein-bottle) -[^genus]: [Saul Schleimer: Notes on the complex of curves](https://www.researchgate.net/publication/228393582_Notes_on_the_complex_of_curves) -[^gpugems]: [GPU Gems: Volume Rendering Techniques](https://developer.nvidia.com/gpugems/gpugems/part-vi-beyond-triangles/chapter-39-volume-rendering-techniques) -[^marching]: [Marching cubes: A high resolution 3D surface construction algorithm](https://dl.acm.org/doi/10.1145/37402.37422) -[^marching]: [Wikipedia: Marching tetrahedra](https://en.wikipedia.org/wiki/Marching_tetrahedra) -[^dual]: [Dual Contouring Tutorial](https://www.boristhebrave.com/2018/04/15/dual-contouring-tutorial/) -[^delaunay]: [Wikipedia: Delaunay triangulation](https://en.wikipedia.org/wiki/Delaunay_triangulation) -[^pv227]: [PV227 GPU Rendering (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PV227/) +## 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 diff --git a/szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.md b/szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.md index 2be2365..246d1c3 100644 --- a/szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.md +++ b/szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.md @@ -33,7 +33,7 @@ description: "TODO" ## Objekty pro detekci kolizí -V principu funguje detekce kolizí tak, že v každém kroku fyzikální simulace: [^pa199-2022] +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.), @@ -75,5 +75,6 @@ V principu funguje detekce kolizí tak, že v každém kroku fyzikální simulac - **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]: [Chmelík, Trtík, PA199 Advanced Game Development](https://is.muni.cz/auth/el/fi/podzim2022/PA199/um/) +- [[[pa199-2022,9]]] [Chmelík, Trtík, PA199 Advanced Game Development](https://is.muni.cz/auth/el/fi/podzim2022/PA199/um/) diff --git a/szmgr/VPH02_graficke_a_fyzikalni_principy.md b/szmgr/VPH02_graficke_a_fyzikalni_principy.md index bcfafb7..5b6dd36 100644 --- a/szmgr/VPH02_graficke_a_fyzikalni_principy.md +++ b/szmgr/VPH02_graficke_a_fyzikalni_principy.md @@ -15,7 +15,7 @@ description: "TODO" ## 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] +> 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á: @@ -38,7 +38,7 @@ description: "TODO" - 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] + 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**\ @@ -47,7 +47,7 @@ description: "TODO" ## Optimizalizace výkonu vykreslování - **Level-of-detail (LOD) / úrovně detailů**\ - Čím větší vzdálenost, tím méně detailů. [^pv255-2022] + Čí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. @@ -69,7 +69,7 @@ description: "TODO" - **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] + 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. @@ -97,7 +97,7 @@ description: "TODO" - _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] + 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**\ @@ -124,23 +124,23 @@ description: "TODO" ## 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] [^cel] + 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)** ![width=500rem](./img/vph02_cel.png) - **Color grading**\ - Využívá se look-up table (LUT) pro jednotnou barevnou korekci. [^zeleny] [^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] [^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] + 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) ![width=500rem](./img/vph02_dof.png) > [!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] + > 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ů @@ -165,12 +165,12 @@ Ray tracing jsou techniky, které trasují paprsky světla napříč scénou. - 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] + 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) ![width=500rem](./img/vph02_spatial_data_structure.png) - **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] + 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: @@ -246,7 +246,7 @@ Ray tracing jsou techniky, které trasují paprsky světla napříč scénou. ## Objekty pro detekci kolizí -V principu funguje detekce kolizí tak, že v každém kroku fyzikální simulace: [^pa199-2022] +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.), @@ -297,28 +297,29 @@ Specifický pohyb postav bezvědomí. Kombinuje animace a fyziku. Je založená - rozdělení postavy na skupiny rigid bodies, - springs and dampers -- pružiny a tlumiče. -**The first "ragdoll falling downstairs" (1997) [^ragdolls]** +**The first "ragdoll falling downstairs" (1997) [ragdolls](#ragdolls)** ![width=500rem](./img/vph02_ragdoll.jpg) - **Featherstone’s algorithm**\ Algoritmus pro výpočet dynamiky stromovité struktury propojených článků. - -[^medek]:: [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]:: http://wiki.polycount.com/wiki/Modular_environments -[^pa010]: Sochor: PA010 Intermediate Computer Graphics (podzim 2020) -[^cel]: https://en.wikipedia.org/wiki/Cel_shading -[^zeleny]: [Jan Zelený, Grafické efekty](++http://decibel.fi.muni.cz/pv255/2018/slides/PV255_-_09_-_Graficke_efekty.pdf++) -[^hair]: https://www.fxguide.com/fxfeatured/pixars-renderman-marschner-hair/ -[^color]: [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]: https://en.wikipedia.org/wiki/Circle_of_confusion -[^pa199]: [Chmelík, Trtík, PA199 Advanced Game Development](https://is.muni.cz/auth/el/fi/podzim2022/PA199/um/) -[^quickhull]: [Barber, Dopkin, Huhdanpaa: The Quickhull Algorithm for Convex Hulls](https://dl.acm.org/doi/pdf/10.1145/235815.235821) -[^ragdolls]: http://www.animats.com/ -[^bvh]: [Bittner: Bounding Volume Hierarchies for Ray Tracing](https://is.muni.cz/auth/el/fi/jaro2022/PA213/um/slides/BoundingVolumeHierarchiesforRayTracing.pdf) -[^path]: [Path Tracing vs. Ray Tracing, Explained](https://www.techspot.com/article/2485-path-tracing-vs-ray-tracing/) -[^bvh]: [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]: [Chmelík, PV255 Game Development I](https://is.muni.cz/auth/el/fi/podzim2022/PV255/um/) -[^pa010]: [Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021)](https://is.muni.cz/auth/el/fi/podzim2021/PA010/um/) -[^texture]: [Wikipedia: Texture mapping](https://en.wikipedia.org/wiki/Texture_mapping) +## 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) diff --git a/szmgr/VPH03_herni_design_i.md b/szmgr/VPH03_herni_design_i.md index 1d794b4..7775d50 100644 --- a/szmgr/VPH03_herni_design_i.md +++ b/szmgr/VPH03_herni_design_i.md @@ -8,7 +8,7 @@ Hra, videohra, desková hra, digitální hra, počítačová hra, hračka, háda _PA215, PA216_ -> Game design is an idea. An idea is worthless. An idea is not playable.[^pa215-2022] [^pa215-2019] +> Game design is an idea. An idea is worthless. An idea is not playable.[pa215-2022](#pa215-2022) [pa215-2019](#pa215-2019) > > — ZZ @@ -40,7 +40,7 @@ Definice hry je stále aktivní proces, ale zjednodušeně je to něco, co se d > > — ZZ? Asi. -**Vlastnosti her [^schell]** +**Vlastnosti her [schell](#schell)** 1. Games are **entered willfully**. 2. Games have **goals**. @@ -77,7 +77,7 @@ Useless fun fact: _Xbox_ je zkratka pro _DirectX Box_. DirectX zastřešuje něk 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]. + 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**\ @@ -109,7 +109,7 @@ Lidi jsou různí a různí lidi hrají různé hry různě. > I haven’t tried that one, what’s it do? -**Bartle’s Taxonomy of Players [^pa215-2022]** +**Bartle’s Taxonomy of Players [pa215-2022](#pa215-2022)** ![width=500rem](./img/vph03_bartle.png) @@ -118,7 +118,7 @@ Neexistuje hra, která by se líbila všem. Cílová skupina je skupina lidí, k ## Komponenty hry -Na hru se dá dívat z mnoha různých perspektiv: [^pa215-2019] +Na hru se dá dívat z mnoha různých perspektiv: [pa215-2019](#pa215-2019) | Component | Type | Example | @@ -145,9 +145,9 @@ Hry dovedou navodit řadu různých herních zážitků, které můžeme různý #### LeBlanc’s Eight Kinds of Fun > [!TIP] -> Taky označované jako _Taxonomy of Game Pleasures_ a _herní "pošušňáníčka"_. [^pa215-2019] +> 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][^mda] +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. @@ -219,7 +219,7 @@ Designér iterativně vytváří hrubé verze hry, které testuje a upravuje. Pr - ~~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] + - 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. @@ -260,7 +260,7 @@ 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] +Při balancování hry designer úmyslně ničí svoji hru, aby odhalil její hranice. [pa215-2022](#pa215-2022) **Doporučení** @@ -277,9 +277,9 @@ Zjednodušit a předat informace o tom co fungeje a co ne ostatním. Musí umět > [!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] Hodí se při komunikaci s klienty, nevyvojáři a nehráči. [^pa216-2020] +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]** +**The Core Game Ontology [cgo](#cgo)** ![width=100%](./img/vph03_cgo.svg) @@ -298,7 +298,7 @@ Lehký slovník pro popis her. [^cgo] Hodí se při komunikaci s klienty, nevyvo ## Žánry -Herní žánry jsou jednoduchou, byť ne zcela přesnou, klasifikací her podle jejich herních mechanik a herních smyček. [^genre] Hrá může zapadat do jednoho nebo více žánrů. Jsou jimi například: +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. @@ -325,13 +325,17 @@ Herní žánry jsou jednoduchou, byť ne zcela přesnou, klasifikací her podle - [Greg Costikyan: I Have No Words & I Must Design: Toward a Critical Vocabulary for Game](http://www.costik.com/nowords2002.pdf) -[^pa215]: https://is.muni.cz/auth/el/fi/podzim2022/PA215/index.qwarp -[^pa215]: https://is.muni.cz/auth/el/fi/podzim2019/PA215/um/ -[^schell]: Jesse Schell, _The Art of Game Design: A Book of Lenses_ -[^hadanka]: https://cs.wikipedia.org/wiki/H%C3%A1danka -[^leblanc]: http://algorithmancy.8kindsoffun.com/ -[^mda]: https://users.cs.northwestern.edu/~hunicke/pubs/MDA.pdf -[^badges]: https://kumu.io/gamebadges/gamebadges -[^cgo]: https://autosemanticgame.institutedigitalgames.com/ontologies/core-game-ontology/ -[^pa216]: https://is.muni.cz/auth/el/fi/jaro2020/PA216/index.qwarp -[^genre]: https://en.wikipedia.org/wiki/Video_game_genre +- [[[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) diff --git a/szmgr/VPH04_herni_design_ii.md b/szmgr/VPH04_herni_design_ii.md index 6fa7c00..049458e 100644 --- a/szmgr/VPH04_herni_design_ii.md +++ b/szmgr/VPH04_herni_design_ii.md @@ -42,13 +42,13 @@ Obsahuje základní informace o hře v čitelné formě pro negamedesignery (tř > > — 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] [^rules-of-play] +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] +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]. +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. @@ -88,7 +88,7 @@ Balanc mezi nudou a přílišnou obtížností. > [!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] +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 @@ -135,7 +135,7 @@ V dobře vybalancované _Player-vs-Player_ (PvP) hře: ## 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] +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, @@ -147,7 +147,7 @@ Game desiner může využít libovolné herní elementy k tomu, aby komunikoval - system itself (procedural rhetoric), - players themselves (fandom, other texts, ...). -**Interactivity with the narrative game [^zagalo]** +**Interactivity with the narrative game [zagalo](#zagalo)** ![width=500rem](./img/vph04_narrative.png) @@ -198,7 +198,7 @@ Game desiner může využít libovolné herní elementy k tomu, aby komunikoval ### 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] +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ě. @@ -219,7 +219,7 @@ Jak tutoriál tak onboarding učí hráče, jak hru hrát. Onboarding je širš - **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] + - 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. @@ -303,13 +303,14 @@ Proces, kdy je game design testován na hráčích po celou dobu vývoje. A to > > — Pozzi & Zimmerman - -[^magic]: https://en.wikipedia.org/wiki/Magic_circle_(virtual_worlds) -[^rules]: Salen, Katie & Zimmerman, Eric. Rules of Play: Game Design Fundamentals. 2003. -[^zimmerman]: [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]: https://en.wikipedia.org/wiki/Ergodic_literature -[^wiki]: https://en.wikipedia.org/wiki/Game_theory -[^pa215]: https://is.muni.cz/auth/el/fi/podzim2022/PA215/index.qwarp -[^zagalo]: https://www.slideshare.net/nzagalo/videogame-narrative -[^pa215]: https://is.muni.cz/auth/el/fi/podzim2019/PA215/um/ -[^fuck]: [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) +## 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) diff --git a/szmgr/VPH05_vyvoj_her.md b/szmgr/VPH05_vyvoj_her.md index bf430ae..7450a8a 100644 --- a/szmgr/VPH05_vyvoj_her.md +++ b/szmgr/VPH05_vyvoj_her.md @@ -46,7 +46,7 @@ I přes to, že je game engine obecný, neznamená to, že v něm dokážeme (ro ## 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] +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í @@ -69,7 +69,7 @@ Na _virtuální rozhraní_ si hráč nesáhne. Jsou to všemožná menu, invent - **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 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** @@ -112,7 +112,7 @@ BCI je technologie, která umožňuje ovládat počítač přímo pomocí myšle 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] + 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 @@ -120,7 +120,7 @@ Zjednodušeně, UI řeší vizuální stránku rozhraní, kdežto UX tu funkčn - 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] + 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í @@ -221,7 +221,7 @@ Síťová hra nemusí být multiplayer, a multiplayer hra nemusí být síťová 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].** +**State inconsistency due to latency [netwok-delay](#netwok-delay).** ![width=400](./img/vph05_network_delay.jpg) @@ -268,7 +268,7 @@ TCP má spoustu skvělých vlastností které ho ale zpomalují. Hry proto čast ### 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] +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. @@ -292,7 +292,7 @@ Během pre-produkce typicky vzniká řada věcí: ### 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] +_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: @@ -319,7 +319,7 @@ Jakmile hra vyjde, malý tým vývojářů se stará o opravování chyb, vydáv ## 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] +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. @@ -349,9 +349,9 @@ Procedurální generování je technika, která umožňuje generovat herní asse - **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] + 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] + 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ě. @@ -385,18 +385,19 @@ Serious games se dají dělit podle jejich cíle: _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] Gamifikace je proto často brána jako manipulativní a opovrženihodná. +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]: https://is.muni.cz/auth/el/fi/podzim2022/PV255/um/lec/Networking_in_computer_games.ppsx -[^cg]: https://www.cgspectrum.com/blog/game-development-process -[^g2]: https://www.g2.com/articles/stages-of-game-development -[^monetization]: https://en.wikipedia.org/wiki/Video_game_monetization -[^pv255]: https://www.fi.muni.cz/~xchmeli1/PV255/materials.cgi -[^ui]: https://www.gamedeveloper.com/design/user-interface-design-in-video-games -[^figma]: https://www.figma.com/resource-library/difference-between-ui-and-ux/ -[^perlin]: https://en.wikipedia.org/wiki/Perlin_noise -[^serious]: https://grendelgames.com/what-are-serious-games/ -[^serious]: https://grendelgames.com/serious-games-terminology/ -[^serious]: https://grendelgames.com/what-are-the-five-types-of-serious-games/ +- [[[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/ diff --git a/szmgr/VPH06_ai_ve_hrach.md b/szmgr/VPH06_ai_ve_hrach.md index c063ef9..5869354 100644 --- a/szmgr/VPH06_ai_ve_hrach.md +++ b/szmgr/VPH06_ai_ve_hrach.md @@ -73,7 +73,7 @@ Jednoduché algoritmy pro pohyb. Jsou škálovatelné a předvídatelné, ale ma - **Seek**\ Přímočárý... doslova. Najde vektor mířící k cíli a aplikuje je jej jako steering. - **Seek schematic [^steering]** + **Seek schematic [steering](#steering)** ![Seek schematic](./img/vph06_seek.jpg) @@ -89,7 +89,7 @@ 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]** + **Arrival schematic [steering](#steering)** ![Arrival schematic](./img/vph06_arrival.jpg) @@ -160,9 +160,9 @@ Pathfinding vnímá scénu jako graf, ve kterém hledá (obvykle nejkratší) ce ### 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] +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]** +**A\* algoritmus [astar](#astar)** ![width=100%](./img/vph06_astar.png) @@ -238,7 +238,7 @@ List ReconstructPath(Node goal) { - 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] + 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) ![width=400](./img/vph06_euclidean_distance.png) @@ -255,7 +255,7 @@ List ReconstructPath(Node goal) { - **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] + 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. @@ -274,7 +274,7 @@ Agenti nevidí herní svět stejně jako hráči, vidí ho spíš jako graf s uz - **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]** + **Sid Meier’s Civilization V [civ5](#civ5)** ![width=400](./img/vph06_civilization.jpg) @@ -290,18 +290,18 @@ Agenti nevidí herní svět stejně jako hráči, vidí ho spíš jako graf s uz 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]** + **Points of visibility [ai-for-games](#ai-for-games)** ![width=400](./img/vph06_points_of_visibility.png) - **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]** + **Navigation System in Unity [navmesh](#navmesh)** ![Navigation System in Unity](./img/vph06_navmesh.png) - **Polygonal mesh graph [^ai-for-games]** + **Polygonal mesh graph [ai-for-games](#ai-for-games)** ![width=400](./img/vph06_polygonal_mesh_graph.png) @@ -328,7 +328,7 @@ Agenti obvykle musí činit rozhodnutí ohledně toho, co budou dělat dál: za 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]** +**Průchod rozhodovacím stromem [ai-for-games](#ai-for-games)** ![width=500](./img/vph06_decision_trees.png) @@ -336,21 +336,21 @@ Rozhodnutí jsou reprezentována jako strom. Vniřní uzly jsou podmínky, listy 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]** +**State machine [ai-for-games](#ai-for-games)** ![width=500](./img/vph06_state_machine.png) - **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]** + **Hierarchical state machine [ai-for-games](#ai-for-games)** ![width=500](./img/vph06_hierarchical_state_machine.png) - **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]** + **State machine with decision tree transitions [ai-for-games](#ai-for-games)** ![width=500](./img/vph06_decision_tree_state_machine.png) @@ -362,11 +362,11 @@ Reprezentuje aktuální chování agenta pomocí stavů ve stavovém automatu. K - Dá se vyrobit modulárně a znovupoužitelně. - Často pro něj existují i custom editory s GUI. -**Behavior tree [^ai-for-games]** +**Behavior tree [ai-for-games](#ai-for-games)** ![width=500](./img/vph06_behavior_tree.png) -**Parallel behavior tree [^pa217]** +**Parallel behavior tree [pa217](#pa217)** ![width=500](./img/vph06_parallel_behavior_tree.png) @@ -411,7 +411,7 @@ Waypoint je pozice v levelu, která je něčím zajímavá. - **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]** + **Tactical locations [ai-for-games](#ai-for-games)** ![width=500](./img/vph06_tactical_locations.png) @@ -510,10 +510,10 @@ Minmax i alpha-beta pruning se chápe nejlíp s vizualizací. Můžete kouknout - **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] + 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] + 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. @@ -540,13 +540,14 @@ Minmax i alpha-beta pruning se chápe nejlíp s vizualizací. Můžete kouknout - $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$. - -[^pa217]: PA217 AI for Games -[^ai]: Ian Millington, John Funge: Artificial Intelligence for Games -[^steering]: [Steering Behaviors](https://slsdo.github.io/steering-behaviors/) -[^navmesh]: [Navigation System in Unity](https://docs.unity3d.com/Manual/nav-NavigationSystem.html) -[^astar]: [Introduction to the A\* Algorithm](https://www.redblobgames.com/pathfinding/a-star/introduction.html) -[^civ5]: [Sid Meier’s Civilization V](https://store.steampowered.com/app/8930/Sid_Meiers_Civilization_V/) -[^monte]: [Wikipedia: Monte Carlo method](https://en.wikipedia.org/wiki/Monte_Carlo_method) -[^mcts]: [Wikipedia: Monte Carlo tree search](https://en.wikipedia.org/wiki/Monte_Carlo_tree_search) -[^ida]: [Wikipedia: Iterative deepening A\*](https://en.wikipedia.org/wiki/Iterative_deepening_A*) +## 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*) diff --git a/szmgr/VPH07_gpu_rendering.md b/szmgr/VPH07_gpu_rendering.md index 669c56c..5aa9917 100644 --- a/szmgr/VPH07_gpu_rendering.md +++ b/szmgr/VPH07_gpu_rendering.md @@ -40,12 +40,12 @@ description: "TODO" > [!IMPORTANT] > Tahle část otázky má značný překryv s otázkou [Modelování a projekce](../szp08_modelovani_a_projekce/). -**Coordinate Systems [^coordinate-systems]** +**Coordinate Systems [coordinate-systems](#coordinate-systems)** ![width=100%](./img/vph07_coordinate_systems.png) - **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] + 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$ | | --------- | ------------ | ------- | ---------- | ---------- | @@ -66,7 +66,7 @@ description: "TODO" - **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] + 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. @@ -81,10 +81,10 @@ description: "TODO" 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] + > 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] V OpenGL tedy platí: + 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$ | | -------- | ---------------------- | ------- | ------ | -------------------------- | @@ -96,13 +96,13 @@ description: "TODO" | _Window_ | _left-handed_ | doprava | nahoru | **dopředu** | > [!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] + > 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] +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]** +**Diagram of the Rendering Pipeline [pipeline](#pipeline)** ![vph07_pipeline](./img/vph07_pipeline.png) @@ -119,7 +119,7 @@ Při zvolání `glDraw*` se používá OpenGL pipeline, která se skládá z ně - **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] + 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`), @@ -186,7 +186,7 @@ Při zvolání `glDraw*` se používá OpenGL pipeline, která se skládá z ně 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]** +**The Shadow Mapping Depth Comparison [shadow-maps](#shadow-maps)** ![width=500rem](./img/vph07_shadow_maps.jpg) @@ -218,12 +218,12 @@ Při zvolání `glDraw*` se používá OpenGL pipeline, která se skládá z ně ![width=500rem](./img/vph07_cascaded_shadow_maps.png) - **Soft shadow maps -- Percentage-Closer Filtering (PCF)**\ - Rozmazává stíny uniformě fixním kernelem. [^pa010-2021] + Rozmazává stíny uniformě fixním kernelem. [pa010-2021](#pa010-2021) ![width=500rem](./img/vph07_soft_shadows_pcf.png) - **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] + 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} @@ -233,7 +233,7 @@ Při zvolání `glDraw*` se používá OpenGL pipeline, která se skládá z ně ## 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] +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. @@ -264,7 +264,7 @@ Tuto techniku použijeme např. když máme ve scéně fakt hodně světel. - **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]** + **Aliasing [anti-aliasing](#anti-aliasing)** ![width=500rem](./img/vph07_aliasing.png) @@ -275,7 +275,7 @@ Tuto techniku použijeme např. když máme ve scéně fakt hodně světel. - **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]** + **MSAA [anti-aliasing](#anti-aliasing)** ![width=500rem](./img/vph07_msaa.png) @@ -290,24 +290,25 @@ Ambient occlusion approximuje, jak moc je objekt vystaven ambientním světlu. J - **Screen-Space Ambient Occlusion (SSAO)**\ Dívá se na okolí daného pixelu (v G-bufferu) a odhaduje tak jeho okluzi. - **SSAO [^ssao]** + **SSAO [ssao](#ssao)** ![width=500rem](./img/vph07_ssao.png) - -[^pipeline]: [Rendering Pipeline Overview](https://www.khronos.org/opengl/wiki/Rendering_Pipeline_Overview) -[^post]: [Vertex Post-Processing](https://www.khronos.org/opengl/wiki/Vertex_Post-Processing) -[^coordinate]: [LearnOpenGL: Coordinate Systems](https://learnopengl.com/Getting-started/Coordinate-Systems) -[^sw]: [Verge3D Wiki: Coordinate Systems](https://www.soft8soft.com/wiki/index.php/Coordinate_Systems) -[^viewport]: [`glViewport`](https://registry.khronos.org/OpenGL-Refpages/gl4/html/glViewport.xhtml) -[^depth]: [`glDepthRange`](https://registry.khronos.org/OpenGL-Refpages/gl4/html/glDepthRange.xhtml) -[^vulkan]: [Vulkan’s coordinate system](http://anki3d.org/vulkan-coordinate-system/) -[^pv227]: [PV227 GPU Rendering (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PV227/) -[^anti]: [LearnOpenGL: Anti-Aliasing](https://learnopengl.com/Advanced-OpenGL/Anti-Aliasing) -[^ambient]: [Wikipedia: Ambient occlusion](https://en.wikipedia.org/wiki/Ambient_occlusion) -[^ssao]: [LearnOpenGL: SSAO](https://learnopengl.com/Advanced-Lighting/SSAO) -[^shadow]: [The Cg Tutorial: Shadow Mapping](https://developer.download.nvidia.com/CgTutorial/cg_tutorial_chapter09.html) -[^pa010]: Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021) +## 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 diff --git a/szmgr/VPH08_modelovani_3d_postav.md b/szmgr/VPH08_modelovani_3d_postav.md index 8d1f13b..cd71b67 100644 --- a/szmgr/VPH08_modelovani_3d_postav.md +++ b/szmgr/VPH08_modelovani_3d_postav.md @@ -46,7 +46,7 @@ description: "TODO" Vývojáři často zaměňují "postava" a "model". - **Avatar**\ - Grafická reprezentace uživatele či uživatelovy postavy. [^avatar] Ve hrách je typicky implementován skrze 3D mesh (obsažený v modelu) či 2D sprite obohacený o animace, collidery, apod. + 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ě @@ -91,20 +91,20 @@ description: "TODO" - **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] + 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]** + **Flowing edge loops and good topology are crucial for rigging and animation [organic](#organic)** ![width=500rem](./img/vph08_organic_modeling.jpg) - **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] + 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] + 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] + 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 @@ -116,7 +116,7 @@ Typický 3D model se skládá nejen z meshe, ale i z materiálů, které jsou v - **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]** + **Result of unwrapping Suzanne [uv-unwrap](#uv-unwrap)** ![width=500rem](./img/vph08_uv_unwrapping.png) @@ -140,7 +140,7 @@ Typický 3D model se skládá nejen z meshe, ale i z materiálů, které jsou v - **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] + 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 @@ -159,9 +159,9 @@ Typický 3D model se skládá nejen z meshe, ale i z materiálů, které jsou v > — 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] + 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] + 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í. @@ -170,17 +170,18 @@ Typický 3D model se skládá nejen z meshe, ale i z materiálů, které jsou v ![width=300](./img/vph08_tpose.jpg) - **Skinning**\ - Úprava kostry tak, aby se povrch modelu správně deformoval při animaci. [^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. - - -[^avatar]: https://en.wikipedia.org/wiki/Avatar_(computing) -[^vv036]: [VV036 3D Character Modeling (jaro 2023)](https://is.muni.cz/auth/el/fi/jaro2023/VV036/) -[^quads]: [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]: [Tips and tricks for organic modelling](https://www.creativebloq.com/tips-and-tricks-organic-modelling-7123070) -[^texture]: [Texture Baking](http://wiki.polycount.com/wiki/Texture_Baking) -[^fk]: [FK and IK Explained - Which One to Use and When?](https://www.youtube.com/watch?v=0a9qIj7kwiA) -[^envelopes]: [Blender: Deform](https://docs.blender.org/manual/en/latest/animation/armatures/bones/properties/deform.html) -[^uv]: [Blender: Unwrapping > Mapping Types](https://docs.blender.org/manual/en/2.79/editors/uv_image/uv/editing/unwrapping/mapping_types.html) + Ú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 From 8cf07549ddef14276c9cc1830df06e91a3da387c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Sat, 7 Jun 2025 10:32:00 +0200 Subject: [PATCH 11/44] Include dashes in bottom footnotes --- szmgr/PGV03_zaklady_pocitatcove_grafiky.md | 19 ++-- szmgr/PGV04_geometricke_algoritmy.md | 5 +- szmgr/PGV05_deleni_prostoru_a_sceny.md | 5 +- szmgr/PGV06_vykreslovani_objemovych_dat.md | 39 ++++--- szmgr/PGV07_modely_osvetleni.md | 9 +- szmgr/PGV08_real_time_rendering.md | 3 +- szmgr/SZP01_algoritmy.md | 21 ++-- szmgr/SZP02_numericke_metody.md | 69 ++++++----- szmgr/SZP03_statistika.md | 63 +++++------ szmgr/SZP04_3d_modelovani.md | 69 ++++++----- szmgr/SZP05_krivky_a_povrchy.md | 55 +++++---- szmgr/SZP06_strojove_uceni.md | 51 ++++----- szmgr/SZP07_grafy.md | 15 ++- szmgr/SZP08_modelovani_a_projekce.md | 2 +- szmgr/SZP09_zpracovani_obrazu.md | 107 +++++++++--------- szmgr/SZP10_analyza_obrazu.md | 21 ++-- .../VPH01_graficke_principy_ve_vyvoji_her.md | 25 ++-- szmgr/VPH01_pokrocila_grafika.md | 53 +++++---- .../VPH02_fyzikalni_principy_ve_vyvoji_her.md | 5 +- szmgr/VPH02_graficke_a_fyzikalni_principy.md | 65 ++++++----- szmgr/VPH03_herni_design_i.md | 44 +++---- szmgr/VPH04_herni_design_ii.md | 37 +++--- szmgr/VPH05_vyvoj_her.md | 45 ++++---- szmgr/VPH06_ai_ve_hrach.md | 59 +++++----- szmgr/VPH07_gpu_rendering.md | 61 +++++----- szmgr/VPH08_modelovani_3d_postav.md | 43 ++++--- 26 files changed, 483 insertions(+), 507 deletions(-) diff --git a/szmgr/PGV03_zaklady_pocitatcove_grafiky.md b/szmgr/PGV03_zaklady_pocitatcove_grafiky.md index 7f8338d..f2f4d0c 100644 --- a/szmgr/PGV03_zaklady_pocitatcove_grafiky.md +++ b/szmgr/PGV03_zaklady_pocitatcove_grafiky.md @@ -13,7 +13,7 @@ description: "TODO" ![width=600](./img/pgv03_block_diagram.png) -Blokový diagram je abstraktní, high-level popis fungování OpenGL [pv112](#pv112). +Blokový diagram je abstraktní, high-level popis fungování OpenGL [^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](../szp08_modelovani_a_projekce), osvětlení jednotlivých vrcholů @@ -266,7 +266,7 @@ Z Primitive assembly dostáváme bod, čáru, nebo trojúhelník, který potřeb ![width=300](./img/pgv03_rast_point.png) - **Ú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. + Při rasterizaci úsečky použijeme Bresenhamův algoritmus [^pb009]. Poslední bod úsečky zůstane nevykreslený (half-open) kvůli návaznosti na další úsečky. ```cpp // From the solution of PB009 @@ -320,7 +320,7 @@ void Application::bresenham(glm::vec2 start, glm::vec2 end, Raster& raster, Colo - **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. +Při rasterizaci trojúhelníku můžeme použít Pinedaův algoritmus [^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. @@ -369,13 +369,12 @@ Výhodami syntetizovaných textur je: - parametrizovatelnost > [!NOTE] -> 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). +> 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] a [^synthesis2]. -## 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 +[^pv112]: Byška: PV112 Computer Graphics API +[^pb009]: Byška: PB009 Principles of Computer Graphics +[^glsl_tutorial]: https://cgvr.cs.uni-bremen.de/teaching/cg2_07/literatur/glsl_tutorial/index.html +[^synthesis1]: https://en.wikipedia.org/wiki/Texture_synthesis +[^synthesis2]: https://diglib.eg.org:8443/server/api/core/bitstreams/90ad4c13-45b1-4ec0-8ef2-76075b2c73ae/content diff --git a/szmgr/PGV04_geometricke_algoritmy.md b/szmgr/PGV04_geometricke_algoritmy.md index 1ece134..d83d8e5 100644 --- a/szmgr/PGV04_geometricke_algoritmy.md +++ b/szmgr/PGV04_geometricke_algoritmy.md @@ -58,7 +58,7 @@ Tento algoritmus má složitost $O(n h)$, kde n je počet bodů a h je počet bo ### 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). +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]. 1. Zvolíme trojúhelník 3 bodů - Bod s minimálními souřadnicemi $(x, y, z)$ @@ -273,6 +273,5 @@ Range trees jsou paměťově náročnější, zato jsou rychlejší. - 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 +[^so_hull_3d]: https://stackoverflow.com/a/74968910/22953817 diff --git a/szmgr/PGV05_deleni_prostoru_a_sceny.md b/szmgr/PGV05_deleni_prostoru_a_sceny.md index fe9ae86..aaa5ede 100644 --- a/szmgr/PGV05_deleni_prostoru_a_sceny.md +++ b/szmgr/PGV05_deleni_prostoru_a_sceny.md @@ -44,7 +44,7 @@ Složitost vytvoření Octree/Quadtree je $O(n \log n)$. Složitost vyhledává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. +(Převzato z 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. ![width=600](./img/pgv04_kd_build.png) @@ -153,6 +153,5 @@ Detekce kolizí je proces, kdy testujeme, zda se dva objekty v prostoru dotýkaj 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/ +[^pgv04]: ../geometricke_algoritmy/ diff --git a/szmgr/PGV06_vykreslovani_objemovych_dat.md b/szmgr/PGV06_vykreslovani_objemovych_dat.md index 9e2ff74..1293b40 100644 --- a/szmgr/PGV06_vykreslovani_objemovych_dat.md +++ b/szmgr/PGV06_vykreslovani_objemovych_dat.md @@ -38,7 +38,7 @@ Před samotnou rekonstrukcí je často potřeba provézt ještě předzpracován - **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) + 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] 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í. @@ -51,7 +51,7 @@ Před samotnou rekonstrukcí je často potřeba provézt ještě předzpracován ### 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) + 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] ![width=300](./img/vph01_delaunay.svg) @@ -60,9 +60,9 @@ Před samotnou rekonstrukcí je často potřeba provézt ještě předzpracován - **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ů. + [^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) + 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] **Příklady meshe pro různé hodnoty Alpha** @@ -103,14 +103,14 @@ Před samotnou rekonstrukcí je často potřeba provézt ještě předzpracován ![width=500rem](./img/vph01_marching_cubes.svg) - 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) + 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] 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) + 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] - **Flying edges**\ Optimalizovaný algoritmus pro marching cubes, který prochází každou hranu pouze jednou. - **Surface nets**\ @@ -119,22 +119,22 @@ Před samotnou rekonstrukcí je často potřeba provézt ještě předzpracován ![width=500](./img/pgv06_surface_nets.png) - **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) + 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] ![width=500](./img/pgv06_dual_contouring.png) ### 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) +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] 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)** +**The Process of Volume Rendering [^gpugems]** ![width=500rem](./img/vph01_direct_volume_rendering.jpg) - **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) + 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] - $\kappa$ je funkce absorpce, - $q$ je emise. @@ -158,7 +158,7 @@ V realitě tohle chování paprsku popisujeme integrály. V počítačové grafi ``` - **Volume rendering integral**\ - Intenzitu světla $I$ v místě paprsku $s$ počítáme pomocí: [pa213](#pa213) + Intenzitu světla $I$ v místě paprsku $s$ počítáme pomocí: [^pa213] ```math \begin{aligned} @@ -189,14 +189,13 @@ V realitě tohle chování paprsku popisujeme integrály. V počítačové grafi 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) + Funkce $T$, která mapuje hodnoty voxelů na barvu a průhlednost. Klasifikuje voxely. [^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) +[^pa010-2020]: Sochor: PA010 Intermediate Computer Graphics (podzim 2020) +[^pa213]: PA213 Advanced Computer Graphics +[^marching-cubes]: [Marching cubes: A high resolution 3D surface construction algorithm](https://dl.acm.org/doi/10.1145/37402.37422) +[^marching-tetrahedra]: [Wikipedia: Marching tetrahedra](https://en.wikipedia.org/wiki/Marching_tetrahedra) +[^dual-contouring]: [Dual Contouring Tutorial](https://www.boristhebrave.com/2018/04/15/dual-contouring-tutorial/) +[^delaunay-triangulation]: [Wikipedia: Delaunay triangulation](https://en.wikipedia.org/wiki/Delaunay_triangulation) +[^gpugems]: [GPU Gems: Volume Rendering Techniques](https://developer.nvidia.com/gpugems/gpugems/part-vi-beyond-triangles/chapter-39-volume-rendering-techniques) diff --git a/szmgr/PGV07_modely_osvetleni.md b/szmgr/PGV07_modely_osvetleni.md index dc33d67..344643b 100644 --- a/szmgr/PGV07_modely_osvetleni.md +++ b/szmgr/PGV07_modely_osvetleni.md @@ -21,7 +21,7 @@ description: "TODO" ## 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) +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] ![width=600](./img/pgv07_phong_overview.png) @@ -127,7 +127,7 @@ Participující média jsou média, která nejsou zcela průhledná, ale nejsou ## 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ů. +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] 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). @@ -242,7 +242,6 @@ Pro výpočet spekulárního osvětlení se používá zrcadlový vektor a Fresn ![width=600](./img/pgv07_ibr.png) -## 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) +[^pv227-2022]: [PV227 GPU Rendering (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PV227/) +[^pb009-io]: [Interaktivní osnova PB009 by xrosecky](https://is.muni.cz/auth/el/fi/jaro2023/PB009/index.qwarp) diff --git a/szmgr/PGV08_real_time_rendering.md b/szmgr/PGV08_real_time_rendering.md index a2d6383..40a2b11 100644 --- a/szmgr/PGV08_real_time_rendering.md +++ b/szmgr/PGV08_real_time_rendering.md @@ -242,6 +242,5 @@ Stíny jsou důležité, jelikož: - **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-2021]: Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021) diff --git a/szmgr/SZP01_algoritmy.md b/szmgr/SZP01_algoritmy.md index 463c6e2..b89f021 100644 --- a/szmgr/SZP01_algoritmy.md +++ b/szmgr/SZP01_algoritmy.md @@ -153,7 +153,7 @@ Greedy algoritmy nachází řešení globálního problému tak, že volí loká _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) +Technika hledání řešení problému postupným sestavováním _kandidátního_ řešení. [^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. @@ -399,7 +399,7 @@ _String matching_ označuje rodinu problémů obsahující třeba: 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) +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] | Algoritmus | Preprocessing | Searching | | ----------------------------------- | ------------------------------------ | ----------------------------------- | @@ -469,7 +469,7 @@ int KarpRabin(string text, string pattern) - **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í + Jeden takový algoritmus lze získat použitím Hornerova schématu pro evaluaci polynomu. [^horner] Předpokládejme, že $\Sigma = \{0, 1, ..., 9\}$ (velikost může být libovolná), pak pro hash $h$ platí ```math \begin{align*} @@ -552,7 +552,7 @@ Jinými slovy na indexu druhého `D` je `abcD` nejdelší prefix $P$, který je - **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) + Složitost hledání je pak v $\Theta(n)$. [^iv003-strings] ### Knuth-Morris-Pratt (KMP) @@ -623,15 +623,14 @@ int KnuthMorrisPratt(string text, string pattern) > 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) +> "In other words we can amortize character mismatches against earlier character matches." [^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 +[^iv003]: [IV003 Algoritmy a datové struktury II (jaro 2021)](https://is.muni.cz/auth/el/fi/jaro2021/IV003/) +[^iv003-strings]: https://is.muni.cz/auth/el/fi/jaro2021/IV003/um/slides/stringmatching.pdf +[^rabin-karp-wiki]: https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm +[^horner]: https://en.wikipedia.org/wiki/Horner%27s_method +[^backtracking]: https://betterprogramming.pub/the-technical-interview-guide-to-backtracking-e1a03ca4abad diff --git a/szmgr/SZP02_numericke_metody.md b/szmgr/SZP02_numericke_metody.md index f7b64ad..5b6089e 100644 --- a/szmgr/SZP02_numericke_metody.md +++ b/szmgr/SZP02_numericke_metody.md @@ -10,7 +10,7 @@ description: "TODO" - **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) + 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] 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. @@ -26,12 +26,12 @@ description: "TODO" - **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) + 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] - **Řá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) + 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] [^numericka-metoda] [^order-question] ```math \begin{aligned} @@ -47,16 +47,16 @@ description: "TODO" ## 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) + Problém nalezení _kořenů_ (root) funkce $f$. T.j. takových parametrů $x, ...$, kde funkce vrací 0: [^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) + 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] [^root-finding] - **Řád metody / rate of convergence**\ - Hodnota reprezentující, jak rychle metoda konverguje k výsledku. [rate](#rate) + Hodnota reprezentující, jak rychle metoda konverguje k výsledku. [^rate] - **Prostá iterační metoda / metoda pevného bodu / fixed-point iteration**\ Používá se pro rovnice typu $x = g(x)$. @@ -88,7 +88,7 @@ description: "TODO" ![width=400](./img/szp02_secant_method.png) - **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) + 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] ```math x_{k+1} = x_k - \frac{x_k - x_s}{f(x_k) - f(x_s)} f(x_k) @@ -100,7 +100,7 @@ description: "TODO" ### 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: +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] Povoleny jsou následující operace: - výměna dvou řádků, - vynásobení řádku nenulovou konstantou, @@ -108,7 +108,7 @@ Systém rovnice je přepsán do matice. Gaussova eliminace je posloupnost operac ### 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) +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] Nechť $A\mathbf{x} = \mathbf{b}$ je systém $n$ lineárních rovnic. Tedy: @@ -178,7 +178,7 @@ Jelikož $L + U = A - D$, dá to zapsat i jako: ### 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) +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] 1. Zvolíme počáteční odhad $\mathbf{x}^{(0)}$. 2. Nový odhad získáme ze vztahu: @@ -203,7 +203,7 @@ T_{gs} &= (D + L)^{-1} U = 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) +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] ```math \begin{align*} @@ -274,7 +274,7 @@ Metody podobné Gaussově eliminaci, ale s vlastnostmi, které mohou být vyhodn ## 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) +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] Numerická diferenciace se využívá pro aproximaci differenciálních rovnic (převodem na _diferenční rovnice_). @@ -285,7 +285,7 @@ Numerická diferenciace se využívá pro aproximaci differenciálních rovnic ( > Lagrangeovu interpolaci řeší část otázky [Křivky a povrchy](../szp05_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) + 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] Jednotlivým "odstínům" -- konkrétním výpočetním vzorcům -- téhle metody se říká _diferenciační schémata_. @@ -293,7 +293,7 @@ Numerická diferenciace se využívá pro aproximaci differenciálních rovnic ( > 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) + Nejjednodušší schéma numerické diferenciace. Vychází z definice derivace. [^finite-difference] - _Dopředná diference / forward (finite) difference_ @@ -319,24 +319,23 @@ Numerická diferenciace se využívá pro aproximaci differenciálních rovnic ( > 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)]() -- [[[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) + Způsob zlepšení rate of convergence iterativních metod. [^richardson] + + +[^ma018]: [MA018 Numerical Methods (podzim 2019)](https://is.muni.cz/auth/el/fi/podzim2019/MA018/) +[^numerical-analysis]: [Wikipedia: Numerical analysis](https://en.wikipedia.org/wiki/Numerical_analysis) +[^root-finding]: [Wikipedia: Root-finding algorithms](https://en.wikipedia.org/wiki/Root-finding_algorithms) +[^rate]: [Wikipedia: Rate of convergence](https://en.wikipedia.org/wiki/Rate_of_convergence) +[^regula-falsi]: [Wikipedia: Regula falsi](https://en.wikipedia.org/wiki/Regula_falsi) +[^gauss-elimination]: [Wikipedia: Gaussian elimination](https://en.wikipedia.org/wiki/Gaussian_elimination) +[^jacobi-method]: [Wikipedia: Jacobi method](https://en.wikipedia.org/wiki/Jacobi_method) +[^gauss-seidel]: [Wikipedia: Gauss-Seidel method](https://en.wikipedia.org/wiki/Gauss%E2%80%93Seidel_method) +[^relaxation-method]: [Wikipedia: Relaxation (iterative method)]() +[^differentiation]: [Wikipedia: Numerical differentiation](https://en.wikipedia.org/wiki/Numerical_differentiation) +[^finite-difference]: [Wikipedia: Finite difference](https://en.wikipedia.org/wiki/Finite_difference) +[^finite-difference-method]: [Wikipedia: Finite difference method](https://en.wikipedia.org/wiki/Finite_difference_method) +[^richardson]: [Wikipedia: Richardson extrapolation](https://en.wikipedia.org/wiki/Richardson_extrapolation) +[^linear-eq]: [Wikipedia: System of linear equations](https://en.wikipedia.org/wiki/System_of_linear_equations) +[^numerical-stability]: [Wikipedia: Numerical stability](https://en.wikipedia.org/wiki/Numerical_stability) +[^numericka-metoda]: [Wikipedia: Numerická metoda](https://cs.wikipedia.org/wiki/Numerick%C3%A1_metoda) +[^order-question]: [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) diff --git a/szmgr/SZP03_statistika.md b/szmgr/SZP03_statistika.md index 266af06..f27f947 100644 --- a/szmgr/SZP03_statistika.md +++ b/szmgr/SZP03_statistika.md @@ -15,7 +15,7 @@ description: "TODO" > 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) + Zabývá se sbíráním, organizací, analýzou, interpretací a prezentací dat. [^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í. @@ -142,7 +142,7 @@ Stejně jako náhodné veličiny popisují jevy, číselné charakteristiky popi 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) + > Taky někdy označovaný jako _obecný moment prvního řádu / první obecný moment_. [^moment] - **$\alpha$-kvantil $Q_\alpha$**\ Dělí statický soubor na stejně velké části. @@ -173,7 +173,7 @@ Jak moc se od sebe prvky liší (nezávisle na konstantním posunutí)? ``` > [!NOTE] - > Taky někdy označovaný jako _centrální moment druhého řádu / druhý centrální moment_. [moment](#moment) + > Taky někdy označovaný jako _centrální moment druhého řádu / druhý centrální moment_. [^moment] - **Směrodatná odchylka / standard deviation**\ Míra variability NV. Značí se $\sigma$ nebo $\text{SD}(X)$. Je definovaná jako $\sqrt{\sigma^2}$. @@ -283,7 +283,7 @@ Popisuje chování _výběrového průměru_ pro velké soubory vzorků a umož - **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) + Metoda odhadu parametru $\theta$ taková, že s počtem vzorků $n$ konverguje k $\theta$ pro $n \to \infty$. [^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: @@ -299,7 +299,7 @@ Popisuje chování _výběrového průměru_ pro velké soubory vzorků a umož > ``` > [!TIP] - > _Estimator_ je funkce počítající statistiku použitá k odhadu parametru. [statistic](#statistic) + > _Estimator_ je funkce počítající statistiku použitá k odhadu parametru. [^statistic] - **Bodový odhad / point estimate / pointwise estimate**\ Odhad parametru daný **jednou hodnotou**, která hodnotu parametru aproximuje. @@ -363,9 +363,9 @@ Máme vzorek velikosti $n$ s výběrovým průměrem $\overline{X}$ a výběrov > 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) + Metoda odhadu parametru založená na maximalizaci likelihoodu, že model sedí na naměřená data. [^mle] - **Method of moments (MOM)**\ - Metoda odhadu parametru založená na rovnosti teoretického a výběrového momentu. [mom](#mom) + Metoda odhadu parametru založená na rovnosti teoretického a výběrového momentu. [^mom] ## Testování statistických hypotéz @@ -377,7 +377,7 @@ Máme vzorek velikosti $n$ s výběrovým průměrem $\overline{X}$ a výběrov - _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) + 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] > 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_). > @@ -407,7 +407,7 @@ Platí presumpce nevinny. Předpokládáme, že člověk zločin nespáchal, dok - **$p$-hodnota (hladina významnosti)**\ - Nejmenší hladina významnosti $\alpha$, při které ještě zamítáme $H_0$. [p-value](#p-value) + Nejmenší hladina významnosti $\alpha$, při které ještě zamítáme $H_0$. [^p-value] Pravděpodobnost, že došlo k chybě typu I -- zavrhnuli jsme $H_0$, ačkoli platí. @@ -423,9 +423,9 @@ Platí presumpce nevinny. Předpokládáme, že člověk zločin nespáchal, dok 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) + 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] - **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) + 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] ### Neparametrické testy @@ -436,7 +436,7 @@ Neparametrické testy nejsou založené (jen) na parametrech pravděpodobnostní - **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) + Umožňuje ověřit, že dvě kategorické NV jsou nezávislé. [^chi-squared] ### Testy (ne)závislosti náhodných veličin @@ -448,7 +448,7 @@ Neparametrické testy nejsou založené (jen) na parametrech pravděpodobnostní **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) + - 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] - **Nezávislost diskrétních NV** @@ -520,22 +520,21 @@ Neparametrické testy nejsou založené (jen) na parametrech pravděpodobnostní 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]() -- [[[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) + +[^statistics]: [Wikipedia: Statistics](https://en.wikipedia.org/wiki/Statistics) +[^nv]: [Wikipedia: Náhodná veličina](https://cs.wikipedia.org/wiki/N%C3%A1hodn%C3%A1_veli%C4%8Dina) +[^cdf]: [Wikipedia: Cumulative distribution function](https://en.wikipedia.org/wiki/Cumulative_distribution_function) +[^mean]: [Wikipedia: Mean](https://en.wikipedia.org/wiki/Mean) +[^clv]: [Wikipedia: Centrální limitní věta](https://cs.wikipedia.org/wiki/Centr%C3%A1ln%C3%AD_limitn%C3%AD_v%C4%9Bta) +[^consistent-estimator]: [Wikipedia: Consistent estimator](https://en.wikipedia.org/wiki/Consistent_estimator) +[^statistic]: [Wikipedia: Statistic](https://en.wikipedia.org/wiki/Statistic) +[^mle]: [Wikipedia: Maximum likelihood estimation](https://en.wikipedia.org/wiki/Maximum_likelihood_estimation) +[^mom]: [Wikipedia: Method of moments]() +[^null]: [Wikipedia: Null hypothesis](https://en.wikipedia.org/wiki/Null_hypothesis) +[^p-value]: [Wikipedia: P-hodnota](https://cs.wikipedia.org/wiki/P-hodnota) +[^mv013]: [MV013 Statistics for Computer Science (jaro 2021)](https://is.muni.cz/auth/el/fi/jaro2021/MV013/) +[^anova]: [Wikipedia: Analysis of variance](https://en.wikipedia.org/wiki/Analysis_of_variance) +[^nezavislost]: [Wikipedia: Statistická nezávislost](https://cs.wikipedia.org/wiki/Statistick%C3%A1_nez%C3%A1vislost) +[^t-test]: [Wikipedia: T-test](https://cs.wikipedia.org/wiki/T-test) +[^chi-squared]: [Chi-square tests](https://www.scribbr.com/statistics/chi-square-tests/) +[^moment]: [Momenty rozdělení](http://kfe.fjfi.cvut.cz/~limpouch/sigdat/pravdh/node10.html) diff --git a/szmgr/SZP04_3d_modelovani.md b/szmgr/SZP04_3d_modelovani.md index 7c89106..baec7f0 100644 --- a/szmgr/SZP04_3d_modelovani.md +++ b/szmgr/SZP04_3d_modelovani.md @@ -16,21 +16,21 @@ description: "TODO" - **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) + - Zahrnuje zakřivení (curvature), plochu (area), vzdálenosti mezi body, atd. [^pa010-2021] - **Topologie** - Nemění ji deformace. - Např. to jak jsou body propojené. - - Sousednost (neighborhood), souvislost (connectedness), adjacency. atd. [pa010-2021](#pa010-2021) + - Sousednost (neighborhood), souvislost (connectedness), adjacency. atd. [^pa010-2021] - **Topology [topology](#topology)** + **Topology [^topology]** ![Topology](./img/szp04_topology.png) - **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) + Prostor/útvar, který lokálně _připomíná_ (je homeomorfní) $n$-dimenzionální Euklidovský prostor. [^pa010-2021] [^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) + $n$-manifold je takový topologický manifold, kde okolí každého bodu je homeomorfní s $n$-dimenzionálním Euklidovským prostorem. [^manifold-wiki] Manifoldy jsou typicky fyzikálně validní a efektivní (např. pomocí half-edge). @@ -38,7 +38,7 @@ description: "TODO" - 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) + - Každý povrch je 2-manifold až na neuzavřené hrany. [^pa010-2021] - $n$-dimenzionální koule je $n$-manifold. ![width=100%](./img/szp04_manifold.png) @@ -85,7 +85,7 @@ description: "TODO" > [!TIP] > 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í**. + > Následující povrch[^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í**. >
> ![width=500rem](./img/szp04_genus.png) @@ -207,12 +207,12 @@ description: "TODO" - 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) + Numerické chyby v geometrii (např. v pozicích vertexů) mohou způsobit konflikty mezi topologickou a geometrickou informací. [^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) + 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] [^boundaries] > [!NOTE] > Zdá se, že $H$ -- components je ekvivalentní $R$ -- rings. @@ -263,7 +263,7 @@ description: "TODO" - `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) + Regularizace vypadá tak, že nejprve je provedena booleovská operace, poté je vypočítán _interior_ a následně _closure_. [^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$. @@ -274,11 +274,11 @@ description: "TODO" _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)** + **Schéma interior and a boundary tělesa $A \cap B$ [^pa010-2021]** ![width=200](./img/szp04_interior_boundary.png) - **Příklad regularizovaného průniku [pa010-2021](#pa010-2021)** + **Příklad regularizovaného průniku [^pa010-2021]** ![width=100%](./img/szp04_rbo.png) @@ -325,29 +325,29 @@ description: "TODO" > 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](../vph01_pokrocila_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) + 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] ![width=400](./img/szp04_edge_flip.png) - **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) + 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] ![width=400](./img/szp04_edge_split.png) - **Zhroucení grany / edge collapse**\ - Lokální změna, která nahrazuje hranu vrcholem. [pa010-2021](#pa010-2021) + Lokální změna, která nahrazuje hranu vrcholem. [^pa010-2021] ![width=400](./img/szp04_edge_collapse.png) - **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) + 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] ![width=400](./img/szp04_subdivision.png) - **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) + Globální upráva s cílem zlepšit kvalitu meshe, např.: tvar trojúhelníků a četnost vertexů. [^pa010-2021] ![width=400](./img/szp04_mesh_regularization.png) @@ -359,7 +359,7 @@ description: "TODO" 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) + 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] ![width=400](./img/szp04_isotropic_remeshing.png) @@ -417,10 +417,10 @@ _Když máme objekt definovaný polévkou matematických symbolů místo hromád - _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) + kde $d(x, A)$ je nejmenší vzdálenost bodu $x$ od entity $A$. [^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) + 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] - _Sjednocení_: $\min(f, g)$, - _Průnik_: $\max(f, g)$, @@ -428,7 +428,7 @@ _Když máme objekt definovaný polévkou matematických symbolů místo hromád - _Komplement_: $-f$. - **Bloby (kapky)**\ - Součet několika Gaussových křivek. [pa010-2020](#pa010-2020) + Součet několika Gaussových křivek. [^pa010-2020] ```math \begin{align*} @@ -450,7 +450,7 @@ _Když máme objekt definovaný polévkou matematických symbolů místo hromád ![width=300](./img/szp04_blobs.png) - **Metaballs**\ - Podobné blobům, ale nepoužívá exponenciální funkci. Organicky se "slévající" koule. [pa010-2020](#pa010-2020) + Podobné blobům, ale nepoužívá exponenciální funkci. Organicky se "slévající" koule. [^pa010-2020] ```math \begin{align*} @@ -475,16 +475,15 @@ _Když máme objekt definovaný polévkou matematických symbolů místo hromád ![width=100%](./img/szp04_metaballs.png) -## 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) + +[^pa010-2021]: Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021) +[^pa010-2020]: Sochor: PA010 Intermediate Computer Graphics (podzim 2020) +[^notes-pa010]: [Moje poznámky z PA010 (podzim 2020)](/fi/pa010/) +[^manifold-wiki]: [Wikipedia: Topological manifold](https://en.wikipedia.org/wiki/Topological_manifold) +[^klein-bottle]: [Konrad Polthier: Imaging maths - Inside the Klein bottle ](https://plus.maths.org/content/imaging-maths-inside-klein-bottle) +[^genus]: [Saul Schleimer: Notes on the complex of curves](https://www.researchgate.net/publication/228393582_Notes_on_the_complex_of_curves) +[^topology]: [Topology vs. Geometry](https://www.austincc.edu/herbling/shape-of-space.pdf) +[^boundaries]: [Ian Stroud: Boundary Representation Modelling Techniques](https://link.springer.com/book/10.1007/978-1-84628-616-2) +[^rbo]: [Interior, Exterior and Closure](https://pages.mtu.edu/~shene/COURSES/cs3621/NOTES/model/closure.html) +[^validity]: [Representational validity of boundary representation models](https://www.sciencedirect.com/science/article/pii/S0010448500000476) +[^denoising]: [Bilateral Normal Filtering for Mesh Denoising](https://ieeexplore.ieee.org/document/5674028) diff --git a/szmgr/SZP05_krivky_a_povrchy.md b/szmgr/SZP05_krivky_a_povrchy.md index f9dd4a0..539a952 100644 --- a/szmgr/SZP05_krivky_a_povrchy.md +++ b/szmgr/SZP05_krivky_a_povrchy.md @@ -218,22 +218,22 @@ Křivka $Q$ patří do třídy $C^n$, pokud má ve všech bodech $t$ spojitou de ### 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) +Je podobná parametrické spojitosti, ale vyžaduje jen "geometrickou" spojitost. Vyžaduje, aby si derivace byly **sobě úměrné**. [^mallinus] [^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) +- $G^2$ -- platí $G^1$ a navíc mají stejný **střed křivosti** (center of curvature). [^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. +> Podle slidů z PB009 musí faktor úměrnosti být různý od 0. [^pb009-2019] Podle Barskyho a DeRoseho musí v první derivaci být $> 0$ a v dalších už je to šumák. [^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) +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] ```math \ell_i(x) = \prod_{0 \le k \le n, k \neq i}^n \frac{x - x_k}{x_i - x_k} @@ -259,7 +259,7 @@ 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) + Metoda evaluace polynomů. Vychází z myšlenky, že násobení se dá nestovat: [^horner] ```math \begin{aligned} @@ -279,7 +279,7 @@ Asi nejznámnější interpolační křivky v počítačové grafice. Jsou urče 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) + Pro Hermitovskou kubiku platí: [^hermite-spline] [^ferguson] ```math \begin{aligned} @@ -365,12 +365,12 @@ Mezi jejich vlastnosti patří: ### B-spline - **Splajn / spline**\ - Splajn stupně $n$ po částech definovaná polynomiální funkce stupně $n-1$ proměnné $x$. [bspline](#bspline) + Splajn stupně $n$ po částech definovaná polynomiální funkce stupně $n-1$ proměnné $x$. [^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 jsou uzly unikátní, pak je splajn v uzlech $C^{n-2}$ spojitý. [^bspline] - Pokud je $r$ uzlů shodných, je v tomto místě pouze $C^{n-r-1}$ spojitý. --- @@ -428,7 +428,7 @@ S(x) = \sum_{i=0} c_i B_{i,n}(x) ``` - **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) + 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] ```math \begin{aligned} @@ -606,7 +606,7 @@ Aproximační plochy analogické B-spline křivkám, ale se dvěma parametry. - **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. + 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] 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} @@ -621,7 +621,7 @@ Aproximační plochy analogické B-spline křivkám, ale se dvěma parametry. $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) +> 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] ## Surface subdivision / rekurzivní dělení polygonů @@ -659,23 +659,22 @@ Polygonové povrchy dělíme v případě, kdy chceme je zjemnit, vyhladit. **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) + +[^pa010-2021]: Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021) +[^pa010-2020]: Sochor: PA010 Intermediate Computer Graphics (podzim 2020) +[^pb009-2019]: Sochor: PB009 Principles of Computer Graphics (jaro 2019) +[^smoothness]: [Wikipedia: Smoothness](https://en.wikipedia.org/wiki/Smoothness) +[^mallinus]: [Jaakko Kurhila and Matti Mäkelä: Parametric Curves](https://www.cs.helsinki.fi/group/goa/mallinnus/curves/curves.html) +[^geometric-continuity]: [Geometric Continuity of Parametric Curves: Three Equivalent Characterizations](https://ieeexplore.ieee.org/document/41470) +[^lagrange]: [Wikipedia: Lagrange polynomial](https://en.wikipedia.org/wiki/Lagrange_polynomial) +[^bspline]: [Wikipedia: B-spline](https://en.wikipedia.org/wiki/B-spline) +[^hermite-spline]: [Wikipedia: Cubic Hermite spline](https://en.wikipedia.org/wiki/Cubic_Hermite_spline) +[^ferguson]: [ČVUT: Ferguson curve](https://marian.fsik.cvut.cz/~kongo/download/pcgr/lectures/01%20crv_ferg.pdf) +[^coons]: [ČVUT: Coons curve](https://marian.fsik.cvut.cz/~kongo/download/pcgr/lectures/03%20crv_coons.pdf) +[^coons-path]: [Wikipedia: Coons patch](https://en.wikipedia.org/wiki/Coons_patch) +[^nurbs]: [Wikipedia: Non-uniform rational B-spline](https://en.wikipedia.org/wiki/Non-uniform_rational_B-spline) +[^sweeping]: [Wikipedia: Solid modeling](https://en.wikipedia.org/wiki/Solid_modeling#Sweeping) +[^horner]: [Wikipedia: Horner’s method](https://en.wikipedia.org/wiki/Horner%27s_method) ## Další zdroje diff --git a/szmgr/SZP06_strojove_uceni.md b/szmgr/SZP06_strojove_uceni.md index 22e584a..6cd22d1 100644 --- a/szmgr/SZP06_strojove_uceni.md +++ b/szmgr/SZP06_strojove_uceni.md @@ -16,7 +16,7 @@ description: "TODO" - **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) + 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] [^pv021] Používá se např. pro: @@ -28,23 +28,23 @@ description: "TODO" - 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) + 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] - **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) + 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] - **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) + 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] - 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) + 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] - **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) + 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] 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) + 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] - **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) + 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] ## Neuronové sítě @@ -92,7 +92,7 @@ description: "TODO" - **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) + - Binární klasifikátor -- rozlišuje jestli vstup patří nebo nepatří do nějaké jedné kategorie.[^pv021] - Linerání klasifikátor -- jeho funkce kombinuje vstupy lineárně. ![width=400](./img/szp06_perceptron.png) @@ -274,7 +274,7 @@ Za předpokladu, že $E$ je squared error, pak: ## 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) +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] > [!IMPORTANT] > Pro konvoluci viz otázka [Zpracování rastrového obrazu](../szp09_zpracovani_obrazu/). @@ -319,7 +319,7 @@ Neuronové sítě uzpůsobené ke zpracování obrazu. Místo násobení matic p ## 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) +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] - **Výhody** @@ -430,18 +430,17 @@ Neuronové sítě, jejichž architektura obsahuje cykly. Tedy výstup v jednom b ![width=100%](./img/szp06_lstm.png) -## 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) + +[^pv021]: T. Brázdil: PV021 Neural Networks +[^ml]: [Wikipedia: Machine learning](https://en.wikipedia.org/wiki/Machine_learning) +[^classification]: [Wikipedia: Statistical classification](https://en.wikipedia.org/wiki/Statistical_classification) +[^regression]: [Wikipedia: Regression analysis](https://en.wikipedia.org/wiki/Regression_analysis) +[^clustering]: [Wikipedia: Cluster analysis](https://en.wikipedia.org/wiki/Cluster_analysis) +[^pattern-recognition]: [Wikipedia: Pattern recognition](https://en.wikipedia.org/wiki/Pattern_recognition) +[^hopfield]: [Wikipedia: Hopfield network](https://en.wikipedia.org/wiki/Hopfield_network) +[^hebb]: [Wikipedia: Hebbian theory](https://en.wikipedia.org/wiki/Hebbian_theory) +[^cnn]: [Wikipedia: Convolutional neural network](https://en.wikipedia.org/wiki/Convolutional_neural_network) +[^rnn]: [Wikipedia: Recurrent neural network](https://en.wikipedia.org/wiki/Recurrent_neural_network) +[^som]: [Wikipedia: Self-organizing map](https://en.wikipedia.org/wiki/Self-organizing_map) +[^som-tutorial]: [Self-Organizing Maps: Tutorial](https://sites.pitt.edu/~is2470pb/Spring05/FinalProjects/Group1a/tutorial/som.html) +[^som-sdl]: [SDL Component Suite: Kohonen Network](http://www.lohninger.com/helpcsuite/kohonen_network_-_background_information.htm) diff --git a/szmgr/SZP07_grafy.md b/szmgr/SZP07_grafy.md index 1b290d8..cc26699 100644 --- a/szmgr/SZP07_grafy.md +++ b/szmgr/SZP07_grafy.md @@ -526,7 +526,7 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces ## 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) + Množina $M \sube E$ taková, že žádné dvě hrany v $M$ nemají společný vrchol. [^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í. @@ -539,7 +539,7 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces - **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) + 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] 1. Mejmě bipartitní graf $G=(X+Y,E)$. @@ -555,13 +555,12 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces ![width=300](./img/szp07_mcm_03.png) -## 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) +[^ib000]: [IB000 Matematické základy informatiky (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/IB000/um/) +[^ib002]: [IB002 Algoritmy a datové struktury (jaro 2020)](https://is.muni.cz/auth/el/fi/jaro2020/IB002/um/) +[^ib003]: [IV003 Algoritmy a datové struktury II (jaro 2021)](https://is.muni.cz/auth/el/fi/jaro2021/IV003/um/) +[^matching]: [Wikipedia: Párování grafu](https://cs.wikipedia.org/wiki/P%C3%A1rov%C3%A1n%C3%AD_grafu) +[^mcm]: [Wikipedia: Maximum cardinality matching](https://en.wikipedia.org/wiki/Maximum_cardinality_matching) ## Další zdroje diff --git a/szmgr/SZP08_modelovani_a_projekce.md b/szmgr/SZP08_modelovani_a_projekce.md index 58a0518..04748bf 100644 --- a/szmgr/SZP08_modelovani_a_projekce.md +++ b/szmgr/SZP08_modelovani_a_projekce.md @@ -91,7 +91,7 @@ description: A guide in my new Starlight docs site. ### Ortografická projekce -Používáme především k vykreslení 2D scén. Osu Z můžeme využít, abychom jeden sprite schovali za jiný. Nicméně objekty dál od kamery jsou stejně velké jako ty blízko kamery. [camera](#camera) +Používáme především k vykreslení 2D scén. Osu Z můžeme využít, abychom jeden sprite schovali za jiný. Nicméně objekty dál od kamery jsou stejně velké jako ty blízko kamery. [^camera] ![width=500](./img/szp08_orthographic_projection.png) diff --git a/szmgr/SZP09_zpracovani_obrazu.md b/szmgr/SZP09_zpracovani_obrazu.md index 0379dd3..127c70e 100644 --- a/szmgr/SZP09_zpracovani_obrazu.md +++ b/szmgr/SZP09_zpracovani_obrazu.md @@ -10,12 +10,12 @@ description: "TODO" - **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) + 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] > 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) + Oblast informatiky zabývající se manipulací s obrazy pomocí počítače. Obsahuje třeba: [^dip] - zpracování raw dat ze senzorů ve foťácích, - odstranění šumu, @@ -133,7 +133,7 @@ Histogram kvantifikuje množství a frekvenci barev obsažených v obraze. Ve st ``` - **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) + Změna obrazu tak, aby jeho kumulativní histogram měl konkrétní tvar, obvykle aby byl lineární. [^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. @@ -151,7 +151,7 @@ Histogram kvantifikuje množství a frekvenci barev obsažených v obraze. Ve st > 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) + 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-bbc] - průměrný jas, - kontrast, @@ -162,7 +162,7 @@ Histogram kvantifikuje množství a frekvenci barev obsažených v obraze. Ve st ## 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) + 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] - **Š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: @@ -172,7 +172,7 @@ Histogram kvantifikuje množství a frekvenci barev obsažených v obraze. Ve st - _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) + 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] ```math (f * g)(t) = \int_{-\infty}^{\infty} \cdot f(\tau) g(t - \tau) d\tau @@ -340,7 +340,7 @@ Proces, kdy hledání _hran_ v obraze. Hrana je křivka, podél níž pixely vý - **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) + Algoritmus pro detekci hran. [^canny] [^canny-tds] - Má nízké procento chyb. - Přesně lokalizuje hrany. @@ -360,7 +360,7 @@ Proces, kdy hledání _hran_ v obraze. Hrana je křivka, podél níž pixely vý 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) + Divergence je operátor, který vrací skalární hodnotu. Popisuje zda gradient roste či klesá. Je definován jako: [^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} @@ -411,7 +411,7 @@ Hrany lze detekovat pomocí druhé derivace obrazu. Nacházejí se v _nulových ## 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) +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] Patří sem transformace jako: @@ -430,7 +430,7 @@ Patří sem transformace jako: > 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...)_ -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) +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] - 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. @@ -464,7 +464,7 @@ Je operace (integrální transformace) při níž je obraz převeden z _prostoro }_{\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) + **Forward** (z prostorové do frekvenční domény): [^fourier] ```math \begin{align*} @@ -487,7 +487,7 @@ Je operace (integrální transformace) při níž je obraz převeden z _prostoro ``` - **2D Fourierova transformace**\ - **Forward** (z prostorové do frekvenční domény): [fourier](#fourier) + **Forward** (z prostorové do frekvenční domény): [^fourier] ```math \begin{align*} @@ -510,9 +510,9 @@ Je operace (integrální transformace) při níž je obraz převeden z _prostoro ``` - **Fast Fourier Transform (FFT)**\ - Algoritmus pro rychlé výpočty diskrétní Fourierovy transformace (DFT). [fft](#fft) + Algoritmus pro rychlé výpočty diskrétní Fourierovy transformace (DFT). [^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) + Ří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] ```math \mathcal{F} \{ f * g \} = \mathcal{F} \{ f \} \cdot \mathcal{F} \{ g \} @@ -522,15 +522,15 @@ Je operace (integrální transformace) při níž je obraz převeden z _prostoro ## Sampling / vzorkování -Samplování je převod spojitého signálu na diskrétní. [sampling](#sampling) +Samplování je převod spojitého signálu na diskrétní. [^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) + V případě 2D obrazů to může ale nemusí znamenat změnu velikosti obrazu. [^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) + Ří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] - 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. @@ -542,7 +542,7 @@ Samplování je převod spojitého signálu na diskrétní. [sampling](#sampling > 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) + Proces, kdy z diskrétního signálu zpět získáme spojitý signál. [^reconstruction] - **Rekonstrukční filtr**\ Filtr pro rekonstrukci signálu. @@ -554,7 +554,7 @@ Samplování je převod spojitého signálu na diskrétní. [sampling](#sampling ## 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) +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] ```math J \lbrack u, v \rbrack = T(u, v) = I \lbrack x(u, v), y(u, v) \rbrack @@ -581,7 +581,7 @@ Patří sem operace jako: - **Vlnka / wavelet**\ - Funkce $\psi$, která je omezená v čase. Je to "brief oscillation". [wavelet](#wavelet) + Funkce $\psi$, která je omezená v čase. Je to "brief oscillation". [^wavelet] ![width=300](./img/szp09_wavelet.svg) @@ -607,7 +607,7 @@ Patří sem operace jako: --- -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) +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] Používá se k: @@ -675,7 +675,7 @@ Dále platí: 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) +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] ## Houghova transformace @@ -683,7 +683,7 @@ Matematicky vzato, k vysoké korelaci vlnky se signálem (vysokému korelačním > Super [minutu a půl dlouhé video, co ti řekne úplně všechno](https://www.youtube.com/watch?v=X1DxCPS1iwA). -Integrální transformace, která identifikuje přímky v obraze. V rozšířené podobě hledá libovolné tvary zadané parametricky. [hough](#hough) +Integrální transformace, která identifikuje přímky v obraze. V rozšířené podobě hledá libovolné tvary zadané parametricky. [^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. @@ -708,7 +708,7 @@ Integrální transformace, která identifikuje přímky v obraze. V rozšířen 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) +Užitečná je především inverzní Radonova transformace, která se používá v tomografii ("CTčko"). [^radon] ![width=100%](./img/szp09_radon.png) @@ -766,33 +766,32 @@ Inverzní funkce je velice užitečná, ale poměrně složitá, takže doufám, | 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)]() -- [[[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)]() -- [[[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)]() -- [[[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) + +[^pb130]: [PB130 Úvod do digitálního zpracování obrazu (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PB130/) +[^pv131]: [PV131 Digitální zpracování obrazu (jaro 2023)](https://is.muni.cz/auth/el/fi/jaro2023/PV131/) +[^raster]: [Wikipedia: Raster graphics](https://en.wikipedia.org/wiki/Raster_graphics) +[^dip]: [Wikipedia: Digital image processing](https://en.wikipedia.org/wiki/Digital_image_processing) +[^filter]: [Wikipedia: Filter (signal processing)]() +[^convolution]: [Wikipedia: Convolution](https://en.wikipedia.org/wiki/Convolution) +[^edge-detection]: [Wikipedia: Edge detection](https://en.wikipedia.org/wiki/Edge_detection) +[^fourier]: [Wikipedia: Fourier transform](https://en.wikipedia.org/wiki/Fourier_transform) +[^fft]: [Wikipedia: Fast Fourier transform](https://en.wikipedia.org/wiki/Fast_Fourier_transform) +[^samping]: [Wikipedia: Sampling (signal processing)]() +[^scaling]: [Wikipedia: Image scaling](https://en.wikipedia.org/wiki/Image_scaling) +[^n-s]: [Wikipedia: Nyquist–Shannon sampling theorem](https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem) +[^geometric-transform]: [Wikipedia: Geometric transformation](https://en.wikipedia.org/wiki/Geometric_transformation) +[^reconstruction]: [Wikipedia: Signal reconstruction](https://en.wikipedia.org/wiki/Signal_reconstruction) +[^wavelet]: [Wikipedia: Wavelet transform](https://en.wikipedia.org/wiki/Wavelet_transform) +[^hough]: [Wikipedia: Hough transform](https://en.wikipedia.org/wiki/Hough_transform) +[^radon]: [Wikipedia: Radon transform](https://en.wikipedia.org/wiki/Radon_transform) +[^integral-transform]: [Wikipedia: Integral transform](https://en.wikipedia.org/wiki/Integral_transform) +[^histogram]: [Wikipedia: Histogram](https://en.wikipedia.org/wiki/Histogram) +[^histogram-eq]: [Wikipedia: Histogram equalization](https://en.wikipedia.org/wiki/Histogram_equalization) +[^histogram-bbc]: [Bitesize: Histograms - Higher only](https://www.bbc.co.uk/bitesize/guides/zspfcwx/revision/3) +[^sobel]: [Wikipedia: Sobel operator](https://en.wikipedia.org/wiki/Sobel_operator) +[^canny]: [Wikipedia: Canny edge detector](https://en.wikipedia.org/wiki/Canny_edge_detector) +[^canny-tds]: [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]: [Wikipedia: Divergence (operátor)]() +[^dog]: [Wikipedia: Difference of Gaussians](https://en.wikipedia.org/wiki/Difference_of_Gaussians) +[^others]: https://hackmd.io/@fi-muni-viz-2022/SywCznl2t +[^waveleet]: [Wikipedia: Vlnka](https://cs.wikipedia.org/wiki/Vlnka) diff --git a/szmgr/SZP10_analyza_obrazu.md b/szmgr/SZP10_analyza_obrazu.md index 1324771..e3ef0be 100644 --- a/szmgr/SZP10_analyza_obrazu.md +++ b/szmgr/SZP10_analyza_obrazu.md @@ -205,14 +205,14 @@ Popis objektů je proces, při kterém se počítají vlastnosti segmentovaných - _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) + 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] Provazochodci využívají moment setrvačnosti při chůzi po laně. ![szp10_provazochodec](./img/szp10_provazochodec.jpg) > [!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) +> "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] - **Prostorová orientace / spatial orientation**\ Směr a velikost delší strany nejmenšího bounding boxu. Lze ji také spočítat pomocí momentů setrvačnosti. @@ -351,7 +351,7 @@ Mapování, které každému pixelu popředí přiřazuje vzdálenost k nejbliž ## 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) +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] - **Binární obraz**\ Dá se vnímat jako funkce $I: \Omega \rightarrow \{0, 1\}$, kde $\Omega \sub \mathbb{Z}^2$. @@ -363,7 +363,7 @@ Teorie a techniky pro analýzu geometrických struktur. Jsou založené na teori 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) + Množina souřadnic, pomocí které je obraz zpracováván. [^pb130] - Má definovaný _počátek_ -- $(0, 0)$. Schematicky se značí křížkem. - Aktuálně uvažovaná souřadnice do něj nemusí patřit. @@ -504,7 +504,7 @@ Pracují na každém pixelu a jeho okolí -- strukturním elementu. ![width=500](./img/szp10_top_hat.png) - **Watershed**\ - Algoritmický přístup k segmentaci skrze matematickou morfologii. Kombinuje segmentaci _narůstáním oblastí_ a _detekcí hran_. [pb130](#pb130) + Algoritmický přístup k segmentaci skrze matematickou morfologii. Kombinuje segmentaci _narůstáním oblastí_ a _detekcí hran_. [^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. @@ -525,13 +525,12 @@ Pracují na každém pixelu a jeho okolí -- strukturním elementu. ![width=600](./img/szp10_watershed.png) -## 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)]() -- [[[morphology, 5]]] [Wikipedia: Mathematical morphology](https://en.wikipedia.org/wiki/Mathematical_morphology) +[^pb130]: [PB130 Úvod do digitálního zpracování obrazu (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PB130/) +[^pv131]: [PV131 Digitální zpracování obrazu (jaro 2023)](https://is.muni.cz/auth/el/fi/jaro2023/PV131/) +[^image-moment]: [Wikipedia: Image moment](https://en.wikipedia.org/wiki/Image_moment) +[^moment]: [Wikipedia: Moment (mathematics)]() +[^morphology]: [Wikipedia: Mathematical morphology](https://en.wikipedia.org/wiki/Mathematical_morphology) ## Další zdroje diff --git a/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md b/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md index aa98a57..aa08df2 100644 --- a/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md +++ b/szmgr/VPH01_graficke_principy_ve_vyvoji_her.md @@ -12,7 +12,7 @@ description: "TODO" ## 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) +> Poznámky o grayboxingu, iterování, modulárním workflow, atd. jsou z přednášky Lukáše Medka v rámci PV255. [^medek] - **Iterace**\ Práce v iteracích pomáhá: @@ -35,7 +35,7 @@ description: "TODO" - 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) + Využití malého množství assetů pro vytvoření rozsáhlého prostředí. Nutná promyšlená preprodukce. [^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**\ @@ -59,7 +59,7 @@ description: "TODO" ## 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ů. +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] 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). @@ -177,7 +177,7 @@ BRDF je řešena pomocí ray tracingu, radiosity, nebo nějakým hybridním ř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) + Čím větší vzdálenost, tím méně detailů. [^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. @@ -199,7 +199,7 @@ BRDF je řešena pomocí ray tracingu, radiosity, nebo nějakým hybridním ře - **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) + Popisuje, jakým způsobem se pixely textury (texely) mapují na pixely obrazovky / daného polygonu. [^texture-mapping] Součástí problému je potřeba odhadnout, jak velkou plochu polygon zabere na obrazovce. @@ -227,7 +227,7 @@ BRDF je řešena pomocí ray tracingu, radiosity, nebo nějakým hybridním ře - _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) + 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] - **Back-face culling**\ Vykreslování pouze předních stran polygonů. - **View frustum culling**\ @@ -251,11 +251,10 @@ BRDF je řešena pomocí ray tracingu, radiosity, nebo nějakým hybridním ře - 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/) +[^medek]:: [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]:: http://wiki.polycount.com/wiki/Modular_environments +[^pv227-2022]: [PV227 GPU Rendering (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PV227/) +[^pv255-2022]: [Chmelík, PV255 Game Development I](https://is.muni.cz/auth/el/fi/podzim2022/PV255/um/) +[^texture-mapping]: [Wikipedia: Texture mapping](https://en.wikipedia.org/wiki/Texture_mapping) +[^pa010-2021]: [Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021)](https://is.muni.cz/auth/el/fi/podzim2021/PA010/um/) diff --git a/szmgr/VPH01_pokrocila_grafika.md b/szmgr/VPH01_pokrocila_grafika.md index b86982b..4ad84f6 100644 --- a/szmgr/VPH01_pokrocila_grafika.md +++ b/szmgr/VPH01_pokrocila_grafika.md @@ -21,7 +21,7 @@ description: "TODO" ### Redukce počtu polygonů -Slučování polygonů (merging) či odstranění polygonů (culling), které nejsou vidět. [pa010-2021](#pa010-2021) +Slučování polygonů (merging) či odstranění polygonů (culling), které nejsou vidět. [^pa010-2021] - **Variational Shape Approximation** @@ -88,35 +88,35 @@ Množina bodů v prostoru, které nemají žádnou strukturu. Nejjednodušší p 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) + 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] [^marching-cubes] **Marching cubes by [Ryoshoru](https://commons.wikimedia.org/wiki/File:MarchingCubesEdit.svg)** ![width=500rem](./img/vph01_marching_cubes.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) + 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] - **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) + 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] - **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) + 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] - **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) + 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] ![width=300](./img/vph01_delaunay.svg) ### 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) +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] 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)** +**The Process of Volume Rendering [^gpugems]** ![width=500rem](./img/vph01_direct_volume_rendering.jpg) - **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) + 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] - $\kappa$ je funkce absorpce, - $q$ je emise. @@ -140,7 +140,7 @@ V realitě tohle chování paprsku popisujeme integrály. V počítačové grafi ``` - **Volume rendering integral**\ - Intenzitu světla $I$ v místě paprsku $s$ počítáme pomocí: [pa213](#pa213) + Intenzitu světla $I$ v místě paprsku $s$ počítáme pomocí: [^pa213] ```math \begin{aligned} @@ -171,7 +171,7 @@ V realitě tohle chování paprsku popisujeme integrály. V počítačové grafi 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) + Funkce $T$, která mapuje hodnoty voxelů na barvu a průhlednost. Klasifikuje voxely. [^pa213] ## Modely nasvícení (illumination models) @@ -191,7 +191,7 @@ V realitě tohle chování paprsku popisujeme integrály. V počítačové grafi ## 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ů. +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] 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). @@ -362,21 +362,20 @@ Stíny jsou důležité, jelikož: - **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/) + +[^pa010-2021]: Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021) +[^pa010-2020]: Sochor: PA010 Intermediate Computer Graphics (podzim 2020) +[^pa213]: PA213 Advanced Computer Graphics +[^notes-pa010]: [Moje poznámky z PA010 (podzim 2020)](/fi/pa010/) +[^manifold-wiki]: [Wikipedia: Topological manifold](https://en.wikipedia.org/wiki/Topological_manifold) +[^klein-bottle]: [Konrad Polthier: Imaging maths - Inside the Klein bottle ](https://plus.maths.org/content/imaging-maths-inside-klein-bottle) +[^genus]: [Saul Schleimer: Notes on the complex of curves](https://www.researchgate.net/publication/228393582_Notes_on_the_complex_of_curves) +[^gpugems]: [GPU Gems: Volume Rendering Techniques](https://developer.nvidia.com/gpugems/gpugems/part-vi-beyond-triangles/chapter-39-volume-rendering-techniques) +[^marching-cubes]: [Marching cubes: A high resolution 3D surface construction algorithm](https://dl.acm.org/doi/10.1145/37402.37422) +[^marching-tetrahedra]: [Wikipedia: Marching tetrahedra](https://en.wikipedia.org/wiki/Marching_tetrahedra) +[^dual-contouring]: [Dual Contouring Tutorial](https://www.boristhebrave.com/2018/04/15/dual-contouring-tutorial/) +[^delaunay-triangulation]: [Wikipedia: Delaunay triangulation](https://en.wikipedia.org/wiki/Delaunay_triangulation) +[^pv227-2022]: [PV227 GPU Rendering (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PV227/) ## Další zdroje diff --git a/szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.md b/szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.md index 246d1c3..5748b0c 100644 --- a/szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.md +++ b/szmgr/VPH02_fyzikalni_principy_ve_vyvoji_her.md @@ -33,7 +33,7 @@ description: "TODO" ## Objekty pro detekci kolizí -V principu funguje detekce kolizí tak, že v každém kroku fyzikální simulace: [pa199-2022](#pa199-2022) +V principu funguje detekce kolizí tak, že v každém kroku fyzikální simulace: [^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.), @@ -75,6 +75,5 @@ V principu funguje detekce kolizí tak, že v každém kroku fyzikální simulac - **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/) +[^pa199-2022]: [Chmelík, Trtík, PA199 Advanced Game Development](https://is.muni.cz/auth/el/fi/podzim2022/PA199/um/) diff --git a/szmgr/VPH02_graficke_a_fyzikalni_principy.md b/szmgr/VPH02_graficke_a_fyzikalni_principy.md index 5b6dd36..7913370 100644 --- a/szmgr/VPH02_graficke_a_fyzikalni_principy.md +++ b/szmgr/VPH02_graficke_a_fyzikalni_principy.md @@ -15,7 +15,7 @@ description: "TODO" ## 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) +> Poznámky o grayboxingu, iterování, modulárním workflow, atd. jsou z přednášky Lukáše Medka v rámci PV255. [^medek] - **Iterace**\ Práce v iteracích pomáhá: @@ -38,7 +38,7 @@ description: "TODO" - 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) + Využití malého množství assetů pro vytvoření rozsáhlého prostředí. Nutná promyšlená preprodukce. [^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**\ @@ -47,7 +47,7 @@ description: "TODO" ## 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) + Čím větší vzdálenost, tím méně detailů. [^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. @@ -69,7 +69,7 @@ description: "TODO" - **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) + Popisuje, jakým způsobem se pixely textury (texely) mapují na pixely obrazovky / daného polygonu. [^texture-mapping] Součástí problému je potřeba odhadnout, jak velkou plochu polygon zabere na obrazovce. @@ -97,7 +97,7 @@ description: "TODO" - _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) + 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] - **Back-face culling**\ Vykreslování pouze předních stran polygonů. - **View frustum culling**\ @@ -124,23 +124,23 @@ description: "TODO" ## 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) + 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] [^cel] **Cel-shaded Utah Teapot by [NicolasSourd](https://commons.wikimedia.org/w/index.php?curid=1788125)** ![width=500rem](./img/vph02_cel.png) - **Color grading**\ - Využívá se look-up table (LUT) pro jednotnou barevnou korekci. [zeleny](#zeleny) [color-grading](#color-grading) + Využívá se look-up table (LUT) pro jednotnou barevnou korekci. [^zeleny] [^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) + 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] [^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) + 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] ![width=500rem](./img/vph02_dof.png) > [!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) + > 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] ## Ray tracing / sledování paprsků @@ -165,12 +165,12 @@ Ray tracing jsou techniky, které trasují paprsky světla napříč scénou. - 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) + 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] ![width=500rem](./img/vph02_spatial_data_structure.png) - **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) + 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] Chceme od ní dvě věci: @@ -246,7 +246,7 @@ Ray tracing jsou techniky, které trasují paprsky světla napříč scénou. ## Objekty pro detekci kolizí -V principu funguje detekce kolizí tak, že v každém kroku fyzikální simulace: [pa199-2022](#pa199-2022) +V principu funguje detekce kolizí tak, že v každém kroku fyzikální simulace: [^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.), @@ -297,29 +297,28 @@ Specifický pohyb postav bezvědomí. Kombinuje animace a fyziku. Je založená - rozdělení postavy na skupiny rigid bodies, - springs and dampers -- pružiny a tlumiče. -**The first "ragdoll falling downstairs" (1997) [ragdolls](#ragdolls)** +**The first "ragdoll falling downstairs" (1997) [^ragdolls]** ![width=500rem](./img/vph02_ragdoll.jpg) - **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) + +[^medek]:: [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]:: http://wiki.polycount.com/wiki/Modular_environments +[^pa010-2020]: Sochor: PA010 Intermediate Computer Graphics (podzim 2020) +[^cel]: https://en.wikipedia.org/wiki/Cel_shading +[^zeleny]: [Jan Zelený, Grafické efekty](++http://decibel.fi.muni.cz/pv255/2018/slides/PV255_-_09_-_Graficke_efekty.pdf++) +[^hair]: https://www.fxguide.com/fxfeatured/pixars-renderman-marschner-hair/ +[^color-grading]: [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]: https://en.wikipedia.org/wiki/Circle_of_confusion +[^pa199-2022]: [Chmelík, Trtík, PA199 Advanced Game Development](https://is.muni.cz/auth/el/fi/podzim2022/PA199/um/) +[^quickhull]: [Barber, Dopkin, Huhdanpaa: The Quickhull Algorithm for Convex Hulls](https://dl.acm.org/doi/pdf/10.1145/235815.235821) +[^ragdolls]: http://www.animats.com/ +[^bvh-rt]: [Bittner: Bounding Volume Hierarchies for Ray Tracing](https://is.muni.cz/auth/el/fi/jaro2022/PA213/um/slides/BoundingVolumeHierarchiesforRayTracing.pdf) +[^path-tracing]: [Path Tracing vs. Ray Tracing, Explained](https://www.techspot.com/article/2485-path-tracing-vs-ray-tracing/) +[^bvh]: [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]: [Chmelík, PV255 Game Development I](https://is.muni.cz/auth/el/fi/podzim2022/PV255/um/) +[^pa010-2021]: [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]: [Wikipedia: Texture mapping](https://en.wikipedia.org/wiki/Texture_mapping) diff --git a/szmgr/VPH03_herni_design_i.md b/szmgr/VPH03_herni_design_i.md index 7775d50..1f8dd9f 100644 --- a/szmgr/VPH03_herni_design_i.md +++ b/szmgr/VPH03_herni_design_i.md @@ -8,7 +8,7 @@ Hra, videohra, desková hra, digitální hra, počítačová hra, hračka, háda _PA215, PA216_ -> Game design is an idea. An idea is worthless. An idea is not playable.[pa215-2022](#pa215-2022) [pa215-2019](#pa215-2019) +> Game design is an idea. An idea is worthless. An idea is not playable.[^pa215-2022] [^pa215-2019] > > — ZZ @@ -40,7 +40,7 @@ Definice hry je stále aktivní proces, ale zjednodušeně je to něco, co se d > > — ZZ? Asi. -**Vlastnosti her [schell](#schell)** +**Vlastnosti her [^schell]** 1. Games are **entered willfully**. 2. Games have **goals**. @@ -77,7 +77,7 @@ Useless fun fact: _Xbox_ je zkratka pro _DirectX Box_. DirectX zastřešuje něk 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). + 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]. - **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**\ @@ -109,7 +109,7 @@ Lidi jsou různí a různí lidi hrají různé hry různě. > I haven’t tried that one, what’s it do? -**Bartle’s Taxonomy of Players [pa215-2022](#pa215-2022)** +**Bartle’s Taxonomy of Players [^pa215-2022]** ![width=500rem](./img/vph03_bartle.png) @@ -118,7 +118,7 @@ Neexistuje hra, která by se líbila všem. Cílová skupina je skupina lidí, k ## Komponenty hry -Na hru se dá dívat z mnoha různých perspektiv: [pa215-2019](#pa215-2019) +Na hru se dá dívat z mnoha různých perspektiv: [^pa215-2019] | Component | Type | Example | @@ -145,9 +145,9 @@ Hry dovedou navodit řadu různých herních zážitků, které můžeme různý #### 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) +> Taky označované jako _Taxonomy of Game Pleasures_ a _herní "pošušňáníčka"_. [^pa215-2019] -Game designer Marc LeBlanc rozdělil herní zážitky do osmi kategorií: [leblanc](#leblanc)[mda](#mda) +Game designer Marc LeBlanc rozdělil herní zážitky do osmi kategorií: [^leblanc][^mda] - **Sensation**\ Game as sense-pleasure: beautiful visuals, good audio, tactile pleasure. @@ -219,7 +219,7 @@ Designér iterativně vytváří hrubé verze hry, které testuje a upravuje. Pr - ~~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) + - Game designer není zodpovědný za celou hru. Je jen jednou z mnoha rolí, které se na tvorbě hry podílejí. [^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. @@ -260,7 +260,7 @@ 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) +Při balancování hry designer úmyslně ničí svoji hru, aby odhalil její hranice. [^pa215-2022] **Doporučení** @@ -277,9 +277,9 @@ Zjednodušit a předat informace o tom co fungeje a co ne ostatním. Musí umět > [!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) +Lehký slovník pro popis her. [^cgo] Hodí se při komunikaci s klienty, nevyvojáři a nehráči. [^pa216-2020] -**The Core Game Ontology [cgo](#cgo)** +**The Core Game Ontology [^cgo]** ![width=100%](./img/vph03_cgo.svg) @@ -298,7 +298,7 @@ Lehký slovník pro popis her. [cgo](#cgo) Hodí se při komunikaci s klienty, n ## Žá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: +Herní žánry jsou jednoduchou, byť ne zcela přesnou, klasifikací her podle jejich herních mechanik a herních smyček. [^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. @@ -325,16 +325,16 @@ Herní žánry jsou jednoduchou, byť ne zcela přesnou, klasifikací her podle - [Greg Costikyan: I Have No Words & I Must Design: Toward a Critical Vocabulary for Game](http://www.costik.com/nowords2002.pdf) -- [[[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 +[^pa215-2022]: https://is.muni.cz/auth/el/fi/podzim2022/PA215/index.qwarp +[^pa215-2019]: https://is.muni.cz/auth/el/fi/podzim2019/PA215/um/ +[^schell]: Jesse Schell, _The Art of Game Design: A Book of Lenses_ +[^hadanka]: https://cs.wikipedia.org/wiki/H%C3%A1danka +[^leblanc]: http://algorithmancy.8kindsoffun.com/ +[^mda]: https://users.cs.northwestern.edu/~hunicke/pubs/MDA.pdf +[^badges]: https://kumu.io/gamebadges/gamebadges +[^cgo]: https://autosemanticgame.institutedigitalgames.com/ontologies/core-game-ontology/ +[^pa216-2020]: https://is.muni.cz/auth/el/fi/jaro2020/PA216/index.qwarp +[^genre]: https://en.wikipedia.org/wiki/Video_game_genre == Další zdroje diff --git a/szmgr/VPH04_herni_design_ii.md b/szmgr/VPH04_herni_design_ii.md index 049458e..bbd60d1 100644 --- a/szmgr/VPH04_herni_design_ii.md +++ b/szmgr/VPH04_herni_design_ii.md @@ -42,13 +42,13 @@ Obsahuje základní informace o hře v čitelné formě pro negamedesignery (tř > > — 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) +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] [^rules-of-play] -Byť ten termín zmínil jako první Huizinga, zadefinovali a zpopularizovali ho až Salen a Zimmerman. [zimmerman-essay](#zimmerman-essay) +Byť ten termín zmínil jako první Huizinga, zadefinovali a zpopularizovali ho až Salen a Zimmerman. [^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). +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]. 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. @@ -88,7 +88,7 @@ Balanc mezi nudou a přílišnou obtížností. > [!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) +Teorie her se na _hry_ dívá jako na matematické modely, které popisují chování nějakých racionálních agentů.[^wiki] ### Typy her @@ -135,7 +135,7 @@ V dobře vybalancované _Player-vs-Player_ (PvP) hře: ## 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) +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] - text, - video, @@ -147,7 +147,7 @@ Game desiner může využít libovolné herní elementy k tomu, aby komunikoval - system itself (procedural rhetoric), - players themselves (fandom, other texts, ...). -**Interactivity with the narrative game [zagalo](#zagalo)** +**Interactivity with the narrative game [^zagalo]** ![width=500rem](./img/vph04_narrative.png) @@ -198,7 +198,7 @@ Game desiner může využít libovolné herní elementy k tomu, aby komunikoval ### 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) +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] 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ě. @@ -219,7 +219,7 @@ Jak tutoriál tak onboarding učí hráče, jak hru hrát. Onboarding je širš - **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 an early gameplay to motivate the player to play a game. [^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. @@ -303,14 +303,13 @@ Proces, kdy je game design testován na hráčích po celou dobu vývoje. A to > > — 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) + +[^magic-circle-wiki]: https://en.wikipedia.org/wiki/Magic_circle_(virtual_worlds) +[^rules-of-play]: Salen, Katie & Zimmerman, Eric. Rules of Play: Game Design Fundamentals. 2003. +[^zimmerman-essay]: [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]: https://en.wikipedia.org/wiki/Ergodic_literature +[^wiki]: https://en.wikipedia.org/wiki/Game_theory +[^pa215-2022]: https://is.muni.cz/auth/el/fi/podzim2022/PA215/index.qwarp +[^zagalo]: https://www.slideshare.net/nzagalo/videogame-narrative +[^pa215-2019]: https://is.muni.cz/auth/el/fi/podzim2019/PA215/um/ +[^fuck-rules]: [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) diff --git a/szmgr/VPH05_vyvoj_her.md b/szmgr/VPH05_vyvoj_her.md index 7450a8a..8062d64 100644 --- a/szmgr/VPH05_vyvoj_her.md +++ b/szmgr/VPH05_vyvoj_her.md @@ -46,7 +46,7 @@ I přes to, že je game engine obecný, neznamená to, že v něm dokážeme (ro ## 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) +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] ### Fyzická rozhraní @@ -69,7 +69,7 @@ Na _virtuální rozhraní_ si hráč nesáhne. Jsou to všemožná menu, invent - **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) + 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] **Fallout 3** @@ -112,7 +112,7 @@ BCI je technologie, která umožňuje ovládat počítač přímo pomocí myšle 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) + 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] - Layout - Typografii @@ -120,7 +120,7 @@ Zjednodušeně, UI řeší vizuální stránku rozhraní, kdežto UX tu funkčn - 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) + 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] - Průzkum uživatelských očekávání a konkurence - Wireframy a prototypování @@ -221,7 +221,7 @@ Síťová hra nemusí být multiplayer, a multiplayer hra nemusí být síťová 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).** +**State inconsistency due to latency [^netwok-delay].** ![width=400](./img/vph05_network_delay.jpg) @@ -268,7 +268,7 @@ TCP má spoustu skvělých vlastností které ho ale zpomalují. Hry proto čast ### 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) +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] - O čem hra má být. - Kdo je její cílovka. @@ -292,7 +292,7 @@ Během pre-produkce typicky vzniká řada věcí: ### 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_ 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] Produkce prochází mnoha milníky: @@ -319,7 +319,7 @@ Jakmile hra vyjde, malý tým vývojářů se stará o opravování chyb, vydáv ## 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) +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] - **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. @@ -349,9 +349,9 @@ Procedurální generování je technika, která umožňuje generovat herní asse - **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) + Noise, který vymyslel Ken Perlin, když pracoval na filmu Tron (1982) v Disney. Má tu krásnou vlastnost, že není patentovaný. [^perlin] - **Simplex noise**\ - Vylepšený Perlin noise, který taky vymyslel Ken Pelin. Tenhle už si patentovat nechal. [perlin](#perlin) + Vylepšený Perlin noise, který taky vymyslel Ken Pelin. Tenhle už si patentovat nechal. [^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ě. @@ -385,19 +385,18 @@ Serious games se dají dělit podle jejich cíle: _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á. +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] 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/ +[^netwok-delay]: https://is.muni.cz/auth/el/fi/podzim2022/PV255/um/lec/Networking_in_computer_games.ppsx +[^cg]: https://www.cgspectrum.com/blog/game-development-process +[^g2]: https://www.g2.com/articles/stages-of-game-development +[^monetization]: https://en.wikipedia.org/wiki/Video_game_monetization +[^pv255]: https://www.fi.muni.cz/~xchmeli1/PV255/materials.cgi +[^ui]: https://www.gamedeveloper.com/design/user-interface-design-in-video-games +[^figma]: https://www.figma.com/resource-library/difference-between-ui-and-ux/ +[^perlin]: https://en.wikipedia.org/wiki/Perlin_noise +[^serious]: https://grendelgames.com/what-are-serious-games/ +[^serious-terminology]: https://grendelgames.com/serious-games-terminology/ +[^serious-types]: https://grendelgames.com/what-are-the-five-types-of-serious-games/ diff --git a/szmgr/VPH06_ai_ve_hrach.md b/szmgr/VPH06_ai_ve_hrach.md index 5869354..a8a6706 100644 --- a/szmgr/VPH06_ai_ve_hrach.md +++ b/szmgr/VPH06_ai_ve_hrach.md @@ -73,7 +73,7 @@ Jednoduché algoritmy pro pohyb. Jsou škálovatelné a předvídatelné, ale ma - **Seek**\ Přímočárý... doslova. Najde vektor mířící k cíli a aplikuje je jej jako steering. - **Seek schematic [steering](#steering)** + **Seek schematic [^steering]** ![Seek schematic](./img/vph06_seek.jpg) @@ -89,7 +89,7 @@ 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)** + **Arrival schematic [^steering]** ![Arrival schematic](./img/vph06_arrival.jpg) @@ -160,9 +160,9 @@ Pathfinding vnímá scénu jako graf, ve kterém hledá (obvykle nejkratší) ce ### 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) +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] -**A\* algoritmus [astar](#astar)** +**A\* algoritmus [^astar]** ![width=100%](./img/vph06_astar.png) @@ -238,7 +238,7 @@ List ReconstructPath(Node goal) { - 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) + 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] ![width=400](./img/vph06_euclidean_distance.png) @@ -255,7 +255,7 @@ List ReconstructPath(Node goal) { - **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) + Depth-first search s heuristikou. Iterative deepening znamená, že se postupně zvyšuje maximální hloubka prohledávání. [^ida-star] - **Simplified Memory Bounded A** (SMA*)*\ A\* co má nižší paměťové nároky. @@ -274,7 +274,7 @@ Agenti nevidí herní svět stejně jako hráči, vidí ho spíš jako graf s uz - **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)** + **Sid Meier’s Civilization V [^civ5]** ![width=400](./img/vph06_civilization.jpg) @@ -290,18 +290,18 @@ Agenti nevidí herní svět stejně jako hráči, vidí ho spíš jako graf s uz 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)** + **Points of visibility [^ai-for-games]** ![width=400](./img/vph06_points_of_visibility.png) - **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)** + **Navigation System in Unity [^navmesh]** ![Navigation System in Unity](./img/vph06_navmesh.png) - **Polygonal mesh graph [ai-for-games](#ai-for-games)** + **Polygonal mesh graph [^ai-for-games]** ![width=400](./img/vph06_polygonal_mesh_graph.png) @@ -328,7 +328,7 @@ Agenti obvykle musí činit rozhodnutí ohledně toho, co budou dělat dál: za 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)** +**Průchod rozhodovacím stromem [^ai-for-games]** ![width=500](./img/vph06_decision_trees.png) @@ -336,21 +336,21 @@ Rozhodnutí jsou reprezentována jako strom. Vniřní uzly jsou podmínky, listy 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)** +**State machine [^ai-for-games]** ![width=500](./img/vph06_state_machine.png) - **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)** + **Hierarchical state machine [^ai-for-games]** ![width=500](./img/vph06_hierarchical_state_machine.png) - **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)** + **State machine with decision tree transitions [^ai-for-games]** ![width=500](./img/vph06_decision_tree_state_machine.png) @@ -362,11 +362,11 @@ Reprezentuje aktuální chování agenta pomocí stavů ve stavovém automatu. K - 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)** +**Behavior tree [^ai-for-games]** ![width=500](./img/vph06_behavior_tree.png) -**Parallel behavior tree [pa217](#pa217)** +**Parallel behavior tree [^pa217]** ![width=500](./img/vph06_parallel_behavior_tree.png) @@ -411,7 +411,7 @@ Waypoint je pozice v levelu, která je něčím zajímavá. - **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)** + **Tactical locations [^ai-for-games]** ![width=500](./img/vph06_tactical_locations.png) @@ -510,10 +510,10 @@ Minmax i alpha-beta pruning se chápe nejlíp s vizualizací. Můžete kouknout - **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) + Algoritmy a techniky spoléhající na náhodou, mega velké množiny vzorků a statistickou analýzu. [^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) + Heuristický algoritmus pro prohledávání stromových grafů. V kontextu deskových her se používá pro hledání nejlepšího tahu.[^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. @@ -540,14 +540,13 @@ Minmax i alpha-beta pruning se chápe nejlíp s vizualizací. Můžete kouknout - $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*) + +[^pa217]: PA217 AI for Games +[^ai-for-games]: Ian Millington, John Funge: Artificial Intelligence for Games +[^steering]: [Steering Behaviors](https://slsdo.github.io/steering-behaviors/) +[^navmesh]: [Navigation System in Unity](https://docs.unity3d.com/Manual/nav-NavigationSystem.html) +[^astar]: [Introduction to the A\* Algorithm](https://www.redblobgames.com/pathfinding/a-star/introduction.html) +[^civ5]: [Sid Meier’s Civilization V](https://store.steampowered.com/app/8930/Sid_Meiers_Civilization_V/) +[^monte-carlo]: [Wikipedia: Monte Carlo method](https://en.wikipedia.org/wiki/Monte_Carlo_method) +[^mcts]: [Wikipedia: Monte Carlo tree search](https://en.wikipedia.org/wiki/Monte_Carlo_tree_search) +[^ida-star]: [Wikipedia: Iterative deepening A\*](https://en.wikipedia.org/wiki/Iterative_deepening_A*) diff --git a/szmgr/VPH07_gpu_rendering.md b/szmgr/VPH07_gpu_rendering.md index 5aa9917..05ff6b2 100644 --- a/szmgr/VPH07_gpu_rendering.md +++ b/szmgr/VPH07_gpu_rendering.md @@ -40,12 +40,12 @@ description: "TODO" > [!IMPORTANT] > Tahle část otázky má značný překryv s otázkou [Modelování a projekce](../szp08_modelovani_a_projekce/). -**Coordinate Systems [coordinate-systems](#coordinate-systems)** +**Coordinate Systems [^coordinate-systems]** ![width=100%](./img/vph07_coordinate_systems.png) - **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) + 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] | Editor | Handedness | $X$ | $Y$ | $Z$ | | --------- | ------------ | ------- | ---------- | ---------- | @@ -66,7 +66,7 @@ description: "TODO" - **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) + 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] Tento prostor stále používá 4-dimenzionální homogenní souřadnice. @@ -81,10 +81,10 @@ description: "TODO" 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) + > Počátek (origin) viewport space je **vlevo dole** a má ve výchozím nastavení má souřadnice $(0, 0)$. [^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í: + 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] V OpenGL tedy platí: | Space | Handedness | $X$ | $Y$ | $Z$ | | -------- | ---------------------- | ------- | ------ | -------------------------- | @@ -96,13 +96,13 @@ description: "TODO" | _Window_ | _left-handed_ | doprava | nahoru | **dopředu** | > [!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) + > 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] ## Pipeline (typy shaderů) -Při zvolání `glDraw*` se používá OpenGL pipeline, která se skládá z několika fází: [pipeline](#pipeline) +Při zvolání `glDraw*` se používá OpenGL pipeline, která se skládá z několika fází: [^pipeline] -**Diagram of the Rendering Pipeline [pipeline](#pipeline)** +**Diagram of the Rendering Pipeline [^pipeline]** ![vph07_pipeline](./img/vph07_pipeline.png) @@ -119,7 +119,7 @@ Při zvolání `glDraw*` se používá OpenGL pipeline, která se skládá z ně - **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) + OpenGL následně: [^post-process] 1. sestaví primitives, 2. ořeže je podle **user** clip space (nastavené programátorem v VS nebo GS pomocí `gl_ClipDistance`), @@ -186,7 +186,7 @@ Při zvolání `glDraw*` se používá OpenGL pipeline, která se skládá z ně 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)** +**The Shadow Mapping Depth Comparison [^shadow-maps]** ![width=500rem](./img/vph07_shadow_maps.jpg) @@ -218,12 +218,12 @@ Při zvolání `glDraw*` se používá OpenGL pipeline, která se skládá z ně ![width=500rem](./img/vph07_cascaded_shadow_maps.png) - **Soft shadow maps -- Percentage-Closer Filtering (PCF)**\ - Rozmazává stíny uniformě fixním kernelem. [pa010-2021](#pa010-2021) + Rozmazává stíny uniformě fixním kernelem. [^pa010-2021] ![width=500rem](./img/vph07_soft_shadows_pcf.png) - **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) + 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] ```math w_\text{penumbra} = \frac{p_z^s - z_\text{avg}}{z_\text{avg}} w_\text{light} @@ -233,7 +233,7 @@ Při zvolání `glDraw*` se používá OpenGL pipeline, která se skládá z ně ## 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) +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] Tuto techniku použijeme např. když máme ve scéně fakt hodně světel. @@ -264,7 +264,7 @@ Tuto techniku použijeme např. když máme ve scéně fakt hodně světel. - **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)** + **Aliasing [^anti-aliasing]** ![width=500rem](./img/vph07_aliasing.png) @@ -275,7 +275,7 @@ Tuto techniku použijeme např. když máme ve scéně fakt hodně světel. - **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)** + **MSAA [^anti-aliasing]** ![width=500rem](./img/vph07_msaa.png) @@ -290,25 +290,24 @@ Ambient occlusion approximuje, jak moc je objekt vystaven ambientním světlu. J - **Screen-Space Ambient Occlusion (SSAO)**\ Dívá se na okolí daného pixelu (v G-bufferu) a odhaduje tak jeho okluzi. - **SSAO [ssao](#ssao)** + **SSAO [^ssao]** ![width=500rem](./img/vph07_ssao.png) -## 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) + +[^pipeline]: [Rendering Pipeline Overview](https://www.khronos.org/opengl/wiki/Rendering_Pipeline_Overview) +[^post-process]: [Vertex Post-Processing](https://www.khronos.org/opengl/wiki/Vertex_Post-Processing) +[^coordinate-systems]: [LearnOpenGL: Coordinate Systems](https://learnopengl.com/Getting-started/Coordinate-Systems) +[^sw-coordinates]: [Verge3D Wiki: Coordinate Systems](https://www.soft8soft.com/wiki/index.php/Coordinate_Systems) +[^viewport]: [`glViewport`](https://registry.khronos.org/OpenGL-Refpages/gl4/html/glViewport.xhtml) +[^depth-range]: [`glDepthRange`](https://registry.khronos.org/OpenGL-Refpages/gl4/html/glDepthRange.xhtml) +[^vulkan-coords]: [Vulkan’s coordinate system](http://anki3d.org/vulkan-coordinate-system/) +[^pv227]: [PV227 GPU Rendering (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PV227/) +[^anti-aliasing]: [LearnOpenGL: Anti-Aliasing](https://learnopengl.com/Advanced-OpenGL/Anti-Aliasing) +[^ambient-occlusion]: [Wikipedia: Ambient occlusion](https://en.wikipedia.org/wiki/Ambient_occlusion) +[^ssao]: [LearnOpenGL: SSAO](https://learnopengl.com/Advanced-Lighting/SSAO) +[^shadow-maps]: [The Cg Tutorial: Shadow Mapping](https://developer.download.nvidia.com/CgTutorial/cg_tutorial_chapter09.html) +[^pa010-2021]: Byška, Furmanová, Kozlíková, Trtík: PA010 Intermediate Computer Graphics (podzim 2021) ## Další zdroje diff --git a/szmgr/VPH08_modelovani_3d_postav.md b/szmgr/VPH08_modelovani_3d_postav.md index cd71b67..7617ccf 100644 --- a/szmgr/VPH08_modelovani_3d_postav.md +++ b/szmgr/VPH08_modelovani_3d_postav.md @@ -46,7 +46,7 @@ description: "TODO" 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. + Grafická reprezentace uživatele či uživatelovy postavy. [^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ě @@ -91,20 +91,20 @@ description: "TODO" - **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) + 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] 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)** + **Flowing edge loops and good topology are crucial for rigging and animation [^organic]** ![width=500rem](./img/vph08_organic_modeling.jpg) - **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) + 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] - **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) + Proces, kdy začneme od [default cube](https://www.youtube.com/watch?v=SDeVyxtdSUk), subdividneme ji a pokračujeme odtamtaď. [^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) + 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] ## Textury @@ -116,7 +116,7 @@ Typický 3D model se skládá nejen z meshe, ale i z materiálů, které jsou v - **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)** + **Result of unwrapping Suzanne [^uv-unwrap]** ![width=500rem](./img/vph08_uv_unwrapping.png) @@ -140,7 +140,7 @@ Typický 3D model se skládá nejen z meshe, ale i z materiálů, které jsou v - **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) + 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] ## Kostra modelu @@ -159,9 +159,9 @@ Typický 3D model se skládá nejen z meshe, ale i z materiálů, které jsou v > — 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) + 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] - **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) + Animujeme jen koncové kosti. Pohyb rodičovských kostí je dopočítán. Klouby se hýbou po přímkách. [^fk-ik] - **T-pose / reference pose**\ Defaultní póza pro charakter při riggování. @@ -170,18 +170,17 @@ Typický 3D model se skládá nejen z meshe, ale i z materiálů, které jsou v ![width=300](./img/vph08_tpose.jpg) - **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) + Úprava kostry tak, aby se povrch modelu správně deformoval při animaci. [^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. + + +[^avatar]: https://en.wikipedia.org/wiki/Avatar_(computing) +[^vv036-2023]: [VV036 3D Character Modeling (jaro 2023)](https://is.muni.cz/auth/el/fi/jaro2023/VV036/) +[^quads]: [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]: [Tips and tricks for organic modelling](https://www.creativebloq.com/tips-and-tricks-organic-modelling-7123070) +[^texture-baking]: [Texture Baking](http://wiki.polycount.com/wiki/Texture_Baking) +[^fk-ik]: [FK and IK Explained - Which One to Use and When?](https://www.youtube.com/watch?v=0a9qIj7kwiA) +[^envelopes]: [Blender: Deform](https://docs.blender.org/manual/en/latest/animation/armatures/bones/properties/deform.html) +[^uv-unwrap]: [Blender: Unwrapping > Mapping Types](https://docs.blender.org/manual/en/2.79/editors/uv_image/uv/editing/unwrapping/mapping_types.html) ## Další zdroje From 2109d1060e721a32502cd00deae4291801b52fbb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Sat, 7 Jun 2025 10:36:47 +0200 Subject: [PATCH 12/44] Replace `stem` with math blocks --- szmgr/SZP03_statistika.md | 4 ++-- szmgr/SZP05_krivky_a_povrchy.md | 4 ++-- szmgr/SZP07_grafy.md | 9 +++++---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/szmgr/SZP03_statistika.md b/szmgr/SZP03_statistika.md index f27f947..227da19 100644 --- a/szmgr/SZP03_statistika.md +++ b/szmgr/SZP03_statistika.md @@ -411,9 +411,9 @@ Platí presumpce nevinny. Předpokládáme, že člověk zločin nespáchal, dok 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$. diff --git a/szmgr/SZP05_krivky_a_povrchy.md b/szmgr/SZP05_krivky_a_povrchy.md index 539a952..8a248fa 100644 --- a/szmgr/SZP05_krivky_a_povrchy.md +++ b/szmgr/SZP05_krivky_a_povrchy.md @@ -203,7 +203,7 @@ Pro zbytek otázky je podstatné znát několik termínů: 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]) +### Parametrická spojitost stupně $n$ ($C^n$) Křivka $Q$ patří do třídy $C^n$, pokud má ve všech bodech $t$ spojitou derivaci až do řádu $n$. @@ -216,7 +216,7 @@ Křivka $Q$ patří do třídy $C^n$, pokud má ve všech bodech $t$ spojitou de - 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]) +### Geometrická spojitost stupně $n$ ($G^n$) Je podobná parametrické spojitosti, ale vyžaduje jen "geometrickou" spojitost. Vyžaduje, aby si derivace byly **sobě úměrné**. [^mallinus] [^geometric-continuity] diff --git a/szmgr/SZP07_grafy.md b/szmgr/SZP07_grafy.md index cc26699..6ddfde7 100644 --- a/szmgr/SZP07_grafy.md +++ b/szmgr/SZP07_grafy.md @@ -324,12 +324,12 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces - $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$. @@ -394,9 +394,10 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces 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:[ + - platí _relaxováné zachování toku_: + $$ (\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á. From a51f0561e3485c4d261fa148b6e83aa62a1cf04b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Sat, 7 Jun 2025 10:44:47 +0200 Subject: [PATCH 13/44] Replace fancy apostrophe with a normal one Plus add scrolling improvement --- szmgr/PGV02_metody_vizualizace.md | 2 +- szmgr/PGV03_zaklady_pocitatcove_grafiky.md | 2 +- szmgr/PGV08_real_time_rendering.md | 2 +- szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md | 2 +- szmgr/SZP01_algoritmy.md | 2 +- szmgr/SZP05_krivky_a_povrchy.md | 4 +-- szmgr/SZP06_strojove_uceni.md | 2 +- szmgr/VPH01_pokrocila_grafika.md | 2 +- szmgr/VPH02_graficke_a_fyzikalni_principy.md | 2 +- szmgr/VPH03_herni_design_i.md | 20 +++++++-------- szmgr/VPH04_herni_design_ii.md | 26 ++++++++++---------- szmgr/VPH06_ai_ve_hrach.md | 8 +++--- szmgr/VPH07_gpu_rendering.md | 2 +- 13 files changed, 38 insertions(+), 38 deletions(-) diff --git a/szmgr/PGV02_metody_vizualizace.md b/szmgr/PGV02_metody_vizualizace.md index 6684f1d..b1a38c6 100644 --- a/szmgr/PGV02_metody_vizualizace.md +++ b/szmgr/PGV02_metody_vizualizace.md @@ -79,7 +79,7 @@ Node-link diagram, Tree (Klasické zobrazení), Radial Tree (Sunburst, ale strom Tyto interakce můžeme aplikovat na různé operandy. Operand interakce je prostor, na který interakci aplikujeme. > [!TIP] -> 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)) +> 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)) ### Techniky pro prostor obrazovky (Pixely) diff --git a/szmgr/PGV03_zaklady_pocitatcove_grafiky.md b/szmgr/PGV03_zaklady_pocitatcove_grafiky.md index f2f4d0c..0072f85 100644 --- a/szmgr/PGV03_zaklady_pocitatcove_grafiky.md +++ b/szmgr/PGV03_zaklady_pocitatcove_grafiky.md @@ -258,7 +258,7 @@ 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). +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. diff --git a/szmgr/PGV08_real_time_rendering.md b/szmgr/PGV08_real_time_rendering.md index 40a2b11..7044230 100644 --- a/szmgr/PGV08_real_time_rendering.md +++ b/szmgr/PGV08_real_time_rendering.md @@ -237,7 +237,7 @@ Stíny jsou důležité, jelikož: ![width=500rem](./img/vph01_shadow_volumes.png) - 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). + 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. diff --git a/szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md b/szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md index ae6504a..2efab85 100644 --- a/szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md +++ b/szmgr/PGV10_zpracovani_obrazu_pomoci_PDE.md @@ -58,7 +58,7 @@ A z této rovnice už vyjádříme $u_{ij}^{k + 1}$. ($\Delta t$ je časový kro ### 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. +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$ diff --git a/szmgr/SZP01_algoritmy.md b/szmgr/SZP01_algoritmy.md index b89f021..5262a32 100644 --- a/szmgr/SZP01_algoritmy.md +++ b/szmgr/SZP01_algoritmy.md @@ -137,7 +137,7 @@ Greedy algoritmy nachází řešení globálního problému tak, že volí loká #### Problémy -- **Cashier’s algorithm (mince)**\ +- **Cashier's algorithm (mince)**\ Jak zaplatit danou částku s co nejmenším počtem mincí různých hodnot? - **Řešení**\ diff --git a/szmgr/SZP05_krivky_a_povrchy.md b/szmgr/SZP05_krivky_a_povrchy.md index 8a248fa..0214404 100644 --- a/szmgr/SZP05_krivky_a_povrchy.md +++ b/szmgr/SZP05_krivky_a_povrchy.md @@ -258,7 +258,7 @@ 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**\ +- **Hornerovo schéma / Horner's method**\ Metoda evaluace polynomů. Vychází z myšlenky, že násobení se dá nestovat: [^horner] ```math @@ -674,7 +674,7 @@ Polygonové povrchy dělíme v případě, kdy chceme je zjemnit, vyhladit. [^coons-path]: [Wikipedia: Coons patch](https://en.wikipedia.org/wiki/Coons_patch) [^nurbs]: [Wikipedia: Non-uniform rational B-spline](https://en.wikipedia.org/wiki/Non-uniform_rational_B-spline) [^sweeping]: [Wikipedia: Solid modeling](https://en.wikipedia.org/wiki/Solid_modeling#Sweeping) -[^horner]: [Wikipedia: Horner’s method](https://en.wikipedia.org/wiki/Horner%27s_method) +[^horner]: [Wikipedia: Horner's method](https://en.wikipedia.org/wiki/Horner%27s_method) ## Další zdroje diff --git a/szmgr/SZP06_strojove_uceni.md b/szmgr/SZP06_strojove_uceni.md index 6cd22d1..4448afe 100644 --- a/szmgr/SZP06_strojove_uceni.md +++ b/szmgr/SZP06_strojove_uceni.md @@ -423,7 +423,7 @@ Neuronové sítě, jejichž architektura obsahuje cykly. Tedy výstup v jednom b ``` > [!TIP] - > Pokud $\textcolor{red}{\sigma' \cdot W_{k’k}} \not\approx 1$, pak gradient buď vybouchne nebo se ztratí. + > 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: diff --git a/szmgr/VPH01_pokrocila_grafika.md b/szmgr/VPH01_pokrocila_grafika.md index 4ad84f6..6694f73 100644 --- a/szmgr/VPH01_pokrocila_grafika.md +++ b/szmgr/VPH01_pokrocila_grafika.md @@ -357,7 +357,7 @@ Stíny jsou důležité, jelikož: ![width=500rem](./img/vph01_shadow_volumes.png) - 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). + 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. diff --git a/szmgr/VPH02_graficke_a_fyzikalni_principy.md b/szmgr/VPH02_graficke_a_fyzikalni_principy.md index 7913370..6e613a3 100644 --- a/szmgr/VPH02_graficke_a_fyzikalni_principy.md +++ b/szmgr/VPH02_graficke_a_fyzikalni_principy.md @@ -301,7 +301,7 @@ Specifický pohyb postav bezvědomí. Kombinuje animace a fyziku. Je založená ![width=500rem](./img/vph02_ragdoll.jpg) -- **Featherstone’s algorithm**\ +- **Featherstone's algorithm**\ Algoritmus pro výpočet dynamiky stromovité struktury propojených článků. diff --git a/szmgr/VPH03_herni_design_i.md b/szmgr/VPH03_herni_design_i.md index 1f8dd9f..55e6c21 100644 --- a/szmgr/VPH03_herni_design_i.md +++ b/szmgr/VPH03_herni_design_i.md @@ -14,9 +14,9 @@ _PA215, PA216_ > Game design is like a recipe... > -> It looks fine, but you can’t eat it... +> It looks fine, but you can't eat it... > -> Well it can be eaten, but it doesn’t fill you up. +> Well it can be eaten, but it doesn't fill you up. > > — Taky ZZ @@ -107,9 +107,9 @@ Lidi jsou různí a různí lidi hrají různé hry různě. - **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? + > I haven't tried that one, what's it do? -**Bartle’s Taxonomy of Players [^pa215-2022]** +**Bartle's Taxonomy of Players [^pa215-2022]** ![width=500rem](./img/vph03_bartle.png) @@ -142,7 +142,7 @@ Hry dovedou navodit řadu různých herních zážitků, které můžeme různý > [!IMPORTANT] > Herní zážitky souvisí s pojmem obtížnost, kterému se věnuje část otázky [Herní design II](../vph04_herni_design_ii/). -#### LeBlanc’s Eight Kinds of Fun +#### LeBlanc's Eight Kinds of Fun > [!TIP] > Taky označované jako _Taxonomy of Game Pleasures_ a _herní "pošušňáníčka"_. [^pa215-2019] @@ -242,9 +242,9 @@ 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**. +> - 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 @@ -288,9 +288,9 @@ Lehký slovník pro popis her. [^cgo] Hodí se při komunikaci s klienty, nevyvo - **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. + 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. + 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**\ diff --git a/szmgr/VPH04_herni_design_ii.md b/szmgr/VPH04_herni_design_ii.md index bbd60d1..0e15206 100644 --- a/szmgr/VPH04_herni_design_ii.md +++ b/szmgr/VPH04_herni_design_ii.md @@ -22,17 +22,17 @@ Obsahuje základní informace o hře v čitelné formě pro negamedesignery (tř - 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? + - 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 + \*\* must have, should have, could have, won't have ## Teoretické koncepty herní analýzy @@ -101,7 +101,7 @@ V teorii her se hry dělí na: - **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. + 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. @@ -179,13 +179,13 @@ Game desiner může využít libovolné herní elementy k tomu, aby komunikoval ### Struktura -- **Lineární (3-bodová struktura, Monomyth / Hero’s journey)** +- **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. + > [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 @@ -222,7 +222,7 @@ Jak tutoriál tak onboarding učí hráče, jak hru hrát. Onboarding je širš - A design of an early gameplay to motivate the player to play a game. [^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. +> [...] 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 @@ -296,7 +296,7 @@ Proces, kdy je game design testován na hráčích po celou dobu vývoje. A to --- > - Playtest before you think you are ready. -> - Don’t explain. +> - Don't explain. > - Take notes. > - Shut Up. > - Notice everything. @@ -312,4 +312,4 @@ Proces, kdy je game design testován na hráčích po celou dobu vývoje. A to [^pa215-2022]: https://is.muni.cz/auth/el/fi/podzim2022/PA215/index.qwarp [^zagalo]: https://www.slideshare.net/nzagalo/videogame-narrative [^pa215-2019]: https://is.muni.cz/auth/el/fi/podzim2019/PA215/um/ -[^fuck-rules]: [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) +[^fuck-rules]: [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) diff --git a/szmgr/VPH06_ai_ve_hrach.md b/szmgr/VPH06_ai_ve_hrach.md index a8a6706..5a8c5ac 100644 --- a/szmgr/VPH06_ai_ve_hrach.md +++ b/szmgr/VPH06_ai_ve_hrach.md @@ -155,7 +155,7 @@ Pathfinding vnímá scénu jako graf, ve kterém hledá (obvykle nejkratší) ce 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**\ +- **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 @@ -274,7 +274,7 @@ Agenti nevidí herní svět stejně jako hráči, vidí ho spíš jako graf s uz - **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]** + **Sid Meier's Civilization V [^civ5]** ![width=400](./img/vph06_civilization.jpg) @@ -480,7 +480,7 @@ Typicky turn-based hry pro dva hráče, často s perfektní informací. - **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). + 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 @@ -546,7 +546,7 @@ Minmax i alpha-beta pruning se chápe nejlíp s vizualizací. Můžete kouknout [^steering]: [Steering Behaviors](https://slsdo.github.io/steering-behaviors/) [^navmesh]: [Navigation System in Unity](https://docs.unity3d.com/Manual/nav-NavigationSystem.html) [^astar]: [Introduction to the A\* Algorithm](https://www.redblobgames.com/pathfinding/a-star/introduction.html) -[^civ5]: [Sid Meier’s Civilization V](https://store.steampowered.com/app/8930/Sid_Meiers_Civilization_V/) +[^civ5]: [Sid Meier's Civilization V](https://store.steampowered.com/app/8930/Sid_Meiers_Civilization_V/) [^monte-carlo]: [Wikipedia: Monte Carlo method](https://en.wikipedia.org/wiki/Monte_Carlo_method) [^mcts]: [Wikipedia: Monte Carlo tree search](https://en.wikipedia.org/wiki/Monte_Carlo_tree_search) [^ida-star]: [Wikipedia: Iterative deepening A\*](https://en.wikipedia.org/wiki/Iterative_deepening_A*) diff --git a/szmgr/VPH07_gpu_rendering.md b/szmgr/VPH07_gpu_rendering.md index 05ff6b2..22566f2 100644 --- a/szmgr/VPH07_gpu_rendering.md +++ b/szmgr/VPH07_gpu_rendering.md @@ -301,7 +301,7 @@ Ambient occlusion approximuje, jak moc je objekt vystaven ambientním světlu. J [^sw-coordinates]: [Verge3D Wiki: Coordinate Systems](https://www.soft8soft.com/wiki/index.php/Coordinate_Systems) [^viewport]: [`glViewport`](https://registry.khronos.org/OpenGL-Refpages/gl4/html/glViewport.xhtml) [^depth-range]: [`glDepthRange`](https://registry.khronos.org/OpenGL-Refpages/gl4/html/glDepthRange.xhtml) -[^vulkan-coords]: [Vulkan’s coordinate system](http://anki3d.org/vulkan-coordinate-system/) +[^vulkan-coords]: [Vulkan's coordinate system](http://anki3d.org/vulkan-coordinate-system/) [^pv227]: [PV227 GPU Rendering (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/PV227/) [^anti-aliasing]: [LearnOpenGL: Anti-Aliasing](https://learnopengl.com/Advanced-OpenGL/Anti-Aliasing) [^ambient-occlusion]: [Wikipedia: Ambient occlusion](https://en.wikipedia.org/wiki/Ambient_occlusion) From ca54af8571b7de25dd434ae161e247464aeb0d8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Sat, 7 Jun 2025 10:57:32 +0200 Subject: [PATCH 14/44] Fix strikethroughs --- szmgr/SZP04_3d_modelovani.md | 2 +- szmgr/SZP05_krivky_a_povrchy.md | 2 +- szmgr/SZP06_strojove_uceni.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/szmgr/SZP04_3d_modelovani.md b/szmgr/SZP04_3d_modelovani.md index baec7f0..fb18adb 100644 --- a/szmgr/SZP04_3d_modelovani.md +++ b/szmgr/SZP04_3d_modelovani.md @@ -4,7 +4,7 @@ description: "TODO" --- > [!NOTE] -> 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)_**. +> Mnohoúhelníkové a trojúhelníkové sítě: datové struktury, modelování, ~filtrování~ , změna struktury sítě, **\*zjednodušování sítě\*\***. Implicitní **a parametrické\*** reprezentace a modelování **_(SDF, CSG, B-Rep)_**. >
> _PA010_ diff --git a/szmgr/SZP05_krivky_a_povrchy.md b/szmgr/SZP05_krivky_a_povrchy.md index 0214404..abc9c32 100644 --- a/szmgr/SZP05_krivky_a_povrchy.md +++ b/szmgr/SZP05_krivky_a_povrchy.md @@ -4,7 +4,7 @@ description: "TODO" --- > [!NOTE] -> 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ů. +> 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, ~NURBS,~ Coonsovy ~křivky a~ pláty. Povrchy tvořené rekurzivním dělením polygonů. >
> _PB009, PA010_ diff --git a/szmgr/SZP06_strojove_uceni.md b/szmgr/SZP06_strojove_uceni.md index 4448afe..828b24d 100644 --- a/szmgr/SZP06_strojove_uceni.md +++ b/szmgr/SZP06_strojove_uceni.md @@ -4,7 +4,7 @@ description: "TODO" --- > [!NOTE] -> 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>]. +> 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. ~Hopfieldova síť,~ konvoluční sítě, rekurentní sítě ~, samo-organizující mapy~ . >
> _PV021_ From 3c60f1520dd4056167e604684acd39ab12769c7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Sat, 7 Jun 2025 11:30:13 +0200 Subject: [PATCH 15/44] Fix nested callout --- szmgr/SZP04_3d_modelovani.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/szmgr/SZP04_3d_modelovani.md b/szmgr/SZP04_3d_modelovani.md index fb18adb..6bfc989 100644 --- a/szmgr/SZP04_3d_modelovani.md +++ b/szmgr/SZP04_3d_modelovani.md @@ -121,9 +121,9 @@ description: "TODO" >
> 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**\ + > > [!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 From 050040f5e6c8615f1b4c6ec4957e9d8ba53a4d85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Sat, 7 Jun 2025 12:55:02 +0200 Subject: [PATCH 16/44] Print pagebreaks, inline width images --- szmgr/SZP09_zpracovani_obrazu.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/szmgr/SZP09_zpracovani_obrazu.md b/szmgr/SZP09_zpracovani_obrazu.md index 127c70e..563d95e 100644 --- a/szmgr/SZP09_zpracovani_obrazu.md +++ b/szmgr/SZP09_zpracovani_obrazu.md @@ -776,7 +776,7 @@ Inverzní funkce je velice užitečná, ale poměrně složitá, takže doufám, [^edge-detection]: [Wikipedia: Edge detection](https://en.wikipedia.org/wiki/Edge_detection) [^fourier]: [Wikipedia: Fourier transform](https://en.wikipedia.org/wiki/Fourier_transform) [^fft]: [Wikipedia: Fast Fourier transform](https://en.wikipedia.org/wiki/Fast_Fourier_transform) -[^samping]: [Wikipedia: Sampling (signal processing)]() +[^sampling]: [Wikipedia: Sampling (signal processing)]() [^scaling]: [Wikipedia: Image scaling](https://en.wikipedia.org/wiki/Image_scaling) [^n-s]: [Wikipedia: Nyquist–Shannon sampling theorem](https://en.wikipedia.org/wiki/Nyquist%E2%80%93Shannon_sampling_theorem) [^geometric-transform]: [Wikipedia: Geometric transformation](https://en.wikipedia.org/wiki/Geometric_transformation) From 11881eb5440bce54b1ac384eab7dd002613e9b96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Mon, 9 Jun 2025 11:17:41 +0200 Subject: [PATCH 17/44] Add regula falsi figure --- szmgr/SZP02_numericke_metody.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/szmgr/SZP02_numericke_metody.md b/szmgr/SZP02_numericke_metody.md index 5b6089e..1c1805c 100644 --- a/szmgr/SZP02_numericke_metody.md +++ b/szmgr/SZP02_numericke_metody.md @@ -96,6 +96,8 @@ description: "TODO" kde $s$ je největší index takový, že $f(x_k)f(x_s) < 0$. + ![width=400](./img/szp02_regula_falsi.png) + ## Přímé metody pro řešení systému lineárních rovnic ### Gaussova eliminace From f83b23363e4a4bfffe457d7b5bc012ed9310be9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Mon, 9 Jun 2025 11:27:44 +0200 Subject: [PATCH 18/44] Add newton approximation method and binary search --- szmgr/SZP02_numericke_metody.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/szmgr/SZP02_numericke_metody.md b/szmgr/SZP02_numericke_metody.md index 1c1805c..3d8c850 100644 --- a/szmgr/SZP02_numericke_metody.md +++ b/szmgr/SZP02_numericke_metody.md @@ -77,6 +77,22 @@ description: "TODO" 3. Opakujeme 2. dokud nedosáhneme požadované přesnosti odhadu. ![width=400](./img/szp02_newton_method.png) + + + > [!NOTE] + > How to derive Newton approximation method: + > 1. Start with Taylor $f(x)=\sum_{n=0}^{1} \frac{f_n(a)}{n!} \cdot (x-a)^n$ + > 2. Substitute $a = x_n$ + > + > $f(x) \approx f(x_n) + f'(x_n)(x-x_n)$ + > + > Now, we want to find $x_{n+1}$ such that $f(x) = f(x_{n+1}) = 0$. + > + > $0 \approx f(x_n) + f'(x_n)(x_{n+1}-x_n)$ + > + > $0 \approx \frac{f(x_n)}{f'(x_n)} + x_{n+1} - x_n$ + > + > $x_{n+1} = x_n - \frac{f(x_n)}{f'(x_n)}$ - **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: @@ -98,6 +114,10 @@ description: "TODO" ![width=400](./img/szp02_regula_falsi.png) +- **Metoda Binary search** + Podobný princip jako _regula falsi_. Vybereš si interval $(x_0, x_1)$ kde kořen funkce leží v tomto intervalu ($f(x_{0,1})$ mají jiné znaménka). + Interval zmenšuješ binárním dělením - nový bod vybereš přímo uprostřed a interval upravíš aby kořen stále ležel v něm. Regula falsi se snaží zlepšit rychlost konvergence sofistikovanějším výběrem nového bodu, než jen střed. + ## Přímé metody pro řešení systému lineárních rovnic ### Gaussova eliminace From ed76c0bac9bd697bc761fdceb28a8e459e79aa4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Mon, 9 Jun 2025 11:39:32 +0200 Subject: [PATCH 19/44] Align newton method equations --- szmgr/SZP02_numericke_metody.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/szmgr/SZP02_numericke_metody.md b/szmgr/SZP02_numericke_metody.md index 3d8c850..d26fee1 100644 --- a/szmgr/SZP02_numericke_metody.md +++ b/szmgr/SZP02_numericke_metody.md @@ -79,20 +79,23 @@ description: "TODO" ![width=400](./img/szp02_newton_method.png) - > [!NOTE] + > [!TIP] > How to derive Newton approximation method: > 1. Start with Taylor $f(x)=\sum_{n=0}^{1} \frac{f_n(a)}{n!} \cdot (x-a)^n$ > 2. Substitute $a = x_n$ - > + > > $f(x) \approx f(x_n) + f'(x_n)(x-x_n)$ > > Now, we want to find $x_{n+1}$ such that $f(x) = f(x_{n+1}) = 0$. > - > $0 \approx f(x_n) + f'(x_n)(x_{n+1}-x_n)$ - > - > $0 \approx \frac{f(x_n)}{f'(x_n)} + x_{n+1} - x_n$ - > - > $x_{n+1} = x_n - \frac{f(x_n)}{f'(x_n)}$ + > ```math + > \begin{aligned} + > 0 \approx &\ f(x_n) + f'(x_n)(x_{n+1}-x_n) \\ + > 0 \approx &\ \frac{f(x_n)}{f'(x_n)} + x_{n+1} - x_n \\ + > x_{n+1} = &\ x_n - \frac{f(x_n)}{f'(x_n)} + > \end{aligned} + > ``` + - **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: @@ -114,7 +117,7 @@ description: "TODO" ![width=400](./img/szp02_regula_falsi.png) -- **Metoda Binary search** +- **Metoda Binary search**\ Podobný princip jako _regula falsi_. Vybereš si interval $(x_0, x_1)$ kde kořen funkce leží v tomto intervalu ($f(x_{0,1})$ mají jiné znaménka). Interval zmenšuješ binárním dělením - nový bod vybereš přímo uprostřed a interval upravíš aby kořen stále ležel v něm. Regula falsi se snaží zlepšit rychlost konvergence sofistikovanějším výběrem nového bodu, než jen střed. From fe754db1359db7860c6ac579ff8e5ccfbb04d151 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Mon, 9 Jun 2025 11:43:32 +0200 Subject: [PATCH 20/44] Align difference equations --- szmgr/PGV_zpracovani_obrazu_intro.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/szmgr/PGV_zpracovani_obrazu_intro.md b/szmgr/PGV_zpracovani_obrazu_intro.md index 68f11ad..b3d9a68 100644 --- a/szmgr/PGV_zpracovani_obrazu_intro.md +++ b/szmgr/PGV_zpracovani_obrazu_intro.md @@ -17,8 +17,10 @@ Taylorův polynom vypadá takto: $f(x + h) = f(x) + hf'(x) + \frac{h^2}{2!}f''(x 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} + \begin{aligned} + f(x + h) \approx &\ f(x) + hf'(x)\\ + f'(x) \approx &\ \frac{f(x + h) - f(x)}{h} + \end{aligned} ``` 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): @@ -26,9 +28,11 @@ Taylorův polynom vypadá takto: $f(x + h) = f(x) + hf'(x) + \frac{h^2}{2!}f''(x ```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} + \begin{aligned} + 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} + \end{aligned} ``` Podobným stylem získáme i druhou derivaci From 8454b329a5eb25ba0ec7c120db08a1978113d03c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Mon, 9 Jun 2025 19:36:30 +0200 Subject: [PATCH 21/44] [Addition] Neuronky --- szmgr/SZP06_strojove_uceni.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/szmgr/SZP06_strojove_uceni.md b/szmgr/SZP06_strojove_uceni.md index 828b24d..19226c4 100644 --- a/szmgr/SZP06_strojove_uceni.md +++ b/szmgr/SZP06_strojove_uceni.md @@ -190,9 +190,9 @@ Neuronka je model, kde váhy neuronů jsou parametry. Při učení neuronek je n ```math \begin{aligned} - + E(\vec{w}) = -\frac{1}{p} \sum_{k=1}^p \sum_{j \in Y} d_{kj} \ln(y_j) - + \end{aligned} ``` @@ -286,6 +286,7 @@ Neuronové sítě uzpůsobené ke zpracování obrazu. Místo násobení matic p - **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. + $f(i,j) = \sum_{q}^{K} \sum_{b}^{L} f(i-q, j-b) \cdot k(a,b)$ - 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**\ @@ -324,13 +325,14 @@ Neuronové sítě, jejichž architektura obsahuje cykly. Tedy výstup v jednom b - **Výhody** - Umí zpracovat vstupy s variabilní, předem neznámou délkou. + - Vhodné pro time-series data (třeba akciový trh) - 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). + - Gradient může explodovat (exploding) nebo zaniknout (diminishing). ReLU je náchylná k explozi hodnoty neuronu. Třeba sigmoid je v tomto lepší. [V RNN se typicky používá tanh.](#LTSM) ![width=100%](./img/szp06_rnn.png) @@ -381,11 +383,11 @@ Neuronové sítě, jejichž architektura obsahuje cykly. Tedy výstup v jednom b ```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' @@ -398,7 +400,7 @@ Neuronové sítě, jejichž architektura obsahuje cykly. Tedy výstup v jednom b \textcolor{brown}{\frac{\partial E_{(x, d)}}{\partial h_{tk}}} \cdot \sigma' \cdot h_{(t-1)k'} \\ - + \end{aligned} ``` @@ -408,7 +410,7 @@ Neuronové sítě, jejichž architektura obsahuje cykly. Tedy výstup v jednom b \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'}}} @@ -426,7 +428,7 @@ Neuronové sítě, jejichž architektura obsahuje cykly. Tedy výstup v jednom b > 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: + 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: ![width=100%](./img/szp06_lstm.png) From fcaf11dbdfce7d4c391efab2e1645647caa81e40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Mon, 9 Jun 2025 22:34:24 +0200 Subject: [PATCH 22/44] Adjust binary search description --- szmgr/SZP02_numericke_metody.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/szmgr/SZP02_numericke_metody.md b/szmgr/SZP02_numericke_metody.md index d26fee1..fefc1e5 100644 --- a/szmgr/SZP02_numericke_metody.md +++ b/szmgr/SZP02_numericke_metody.md @@ -118,8 +118,7 @@ description: "TODO" ![width=400](./img/szp02_regula_falsi.png) - **Metoda Binary search**\ - Podobný princip jako _regula falsi_. Vybereš si interval $(x_0, x_1)$ kde kořen funkce leží v tomto intervalu ($f(x_{0,1})$ mají jiné znaménka). - Interval zmenšuješ binárním dělením - nový bod vybereš přímo uprostřed a interval upravíš aby kořen stále ležel v něm. Regula falsi se snaží zlepšit rychlost konvergence sofistikovanějším výběrem nového bodu, než jen střed. + Prvotní interval $(x_0, x_1)$ musí obsahovat kořen funkce $f$, tj. $x_0$ a $x_1$ mají různé znaménka. V každém kroku se rozdělí interval na dvě poloviny a dál hledáme v polovině která obsahuje kořen funkce. Metoda _regula falsi_ se pokouší o rychlejší kovergenci sofistikovanějším dělením intervalu. ## Přímé metody pro řešení systému lineárních rovnic From 00743cf66783e0de7a772de0949d1c4037867d72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Wed, 11 Jun 2025 22:42:54 +0200 Subject: [PATCH 23/44] Remove algo string matching --- szmgr/SZP01_algoritmy.md | 243 --------------------------------------- 1 file changed, 243 deletions(-) diff --git a/szmgr/SZP01_algoritmy.md b/szmgr/SZP01_algoritmy.md index 5262a32..6075ba8 100644 --- a/szmgr/SZP01_algoritmy.md +++ b/szmgr/SZP01_algoritmy.md @@ -388,249 +388,6 @@ k + (\|S\| - k) - \|S\| = 0 & \text{pokud } \|S\| > k \\ \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] - -| 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 | $\Theta(m \cdot \vert \Sigma \vert)$ | $\Theta(n)$ | -| Knuth-Morris-Pratt | $\Theta(m)$ | $\Theta(m)$ | -| Boyer-Moore | $\Theta(m + \vert \Sigma \vert)$ | $\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] 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] - -### 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 -/// -/// Computes the longest proper prefix of P[0..i] -/// that is also a suffix of P[0..i]. -/// -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] - -- **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`. - [^iv003]: [IV003 Algoritmy a datové struktury II (jaro 2021)](https://is.muni.cz/auth/el/fi/jaro2021/IV003/) -[^iv003-strings]: https://is.muni.cz/auth/el/fi/jaro2021/IV003/um/slides/stringmatching.pdf -[^rabin-karp-wiki]: https://en.wikipedia.org/wiki/Rabin%E2%80%93Karp_algorithm -[^horner]: https://en.wikipedia.org/wiki/Horner%27s_method [^backtracking]: https://betterprogramming.pub/the-technical-interview-guide-to-backtracking-e1a03ca4abad From 0dd20277154809435b22bee4436546e2d192328e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Wed, 11 Jun 2025 22:43:07 +0200 Subject: [PATCH 24/44] Notes for graphs and graph algorithms --- szmgr/SZP07_grafy.md | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/szmgr/SZP07_grafy.md b/szmgr/SZP07_grafy.md index 6ddfde7..f737373 100644 --- a/szmgr/SZP07_grafy.md +++ b/szmgr/SZP07_grafy.md @@ -135,6 +135,9 @@ 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)$. +- Udělá max $V-1$ iterací, protože nejdelší cesta může mít max $V-1$ hran (přes žádný vertex nepůjdeš dvakrát). +- _Modifikace_: Po $V-1$ by už nejkratší cesty měly být nalezeny. Udělejme ještě jednu iteraci - pokud se hodnoty změní, pak nejkratší cesta obsahuje negativní cyklus. Viz python kód dole. +- _Modifikace_: Early stop - pokud se 2 interace po sobě hodnoty vrcholů nezmění, pak jsme našli nejkratší cesty. ```python def bellmanford(graph: List[List[Tuple[int, int]]], s: int) \ @@ -226,9 +229,9 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces - **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ě. + Najdi cyklus bez červených hran, vyber v něm **neobarvenou** hranu s **nejvyšší** cenou a obarvi ji červeně. Červená hrana znamená odebrání z finální kostry. - **Blue rule**\ - Najdi řez bez modrých hran, vyber v něm **neobarvenou** hranu s **nejmenší** cenou a obarvi ji modře. + Najdi řez bez modrých hran, vyber v něm **neobarvenou** hranu s **nejmenší** cenou a obarvi ji modře. Modrá hrana znamená přidání do finální kostry. - **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**\ @@ -305,7 +308,7 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces 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_ + - _tok hranou je nezáporný a nepřevyšuje povolenou 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_ @@ -332,7 +335,7 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces $$ - **Augmenting path $P$**\ - Jednoduchá $s \rightsquigarrow t$ cesta v residuální síti $G_f$. + Jednoduchá $s \rightsquigarrow t$ cesta v residuální síti $G_f$. Cesty hledáš buď BFS nebo DFS - každou iteraci si prostě nějakou vybereš. > [!NOTE] > T.j. cesta která může jít i proti směru toku $f$. @@ -518,11 +521,11 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces **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 | +| Ford-Fulkerson | Push-Relabel (Goldberg) | +| ------------------------------------ | ----------------------- | +| global character | local character | +| update flow along an augmenting path | update flow on edges | +| flow conservation | preflow | ## Maximální párování v bipartitních grafech @@ -556,14 +559,13 @@ Dijkstrův algoritmus lze optimalizovat, pokud nás zajímá jen nejkratší ces ![width=300](./img/szp07_mcm_03.png) - -[^ib000]: [IB000 Matematické základy informatiky (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/IB000/um/) -[^ib002]: [IB002 Algoritmy a datové struktury (jaro 2020)](https://is.muni.cz/auth/el/fi/jaro2020/IB002/um/) -[^ib003]: [IV003 Algoritmy a datové struktury II (jaro 2021)](https://is.muni.cz/auth/el/fi/jaro2021/IV003/um/) [^matching]: [Wikipedia: Párování grafu](https://cs.wikipedia.org/wiki/P%C3%A1rov%C3%A1n%C3%AD_grafu) [^mcm]: [Wikipedia: Maximum cardinality matching](https://en.wikipedia.org/wiki/Maximum_cardinality_matching) ## Další zdroje +- [IB000 Matematické základy informatiky (podzim 2022)](https://is.muni.cz/auth/el/fi/podzim2022/IB000/um/) +- [IB002 Algoritmy a datové struktury (jaro 2020)](https://is.muni.cz/auth/el/fi/jaro2020/IB002/um/) +- [IV003 Algoritmy a datové struktury II (jaro 2021)](https://is.muni.cz/auth/el/fi/jaro2021/IV003/um/) - [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) From 21eb9ac389123725bde20789228928b1066f7b94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Wed, 11 Jun 2025 22:43:29 +0200 Subject: [PATCH 25/44] Fix capitalization in links --- szmgr/PGV01_zaklady_vizualizace.md | 2 +- szmgr/SZP04_3d_modelovani.md | 2 +- szmgr/VPH01_pokrocila_grafika.md | 2 +- szmgr/VPH02_graficke_a_fyzikalni_principy.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/szmgr/PGV01_zaklady_vizualizace.md b/szmgr/PGV01_zaklady_vizualizace.md index f42e068..be44118 100644 --- a/szmgr/PGV01_zaklady_vizualizace.md +++ b/szmgr/PGV01_zaklady_vizualizace.md @@ -157,7 +157,7 @@ Vytvoříme povrch, kde hodnota je konstantní. Na vytvoření isosurface může ### 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). +Detailní fungování je popsané v otázce [PGV06](../pgv06_vykreslovani_objemovych_dat). ## Geovizualizace diff --git a/szmgr/SZP04_3d_modelovani.md b/szmgr/SZP04_3d_modelovani.md index 6bfc989..422d3ec 100644 --- a/szmgr/SZP04_3d_modelovani.md +++ b/szmgr/SZP04_3d_modelovani.md @@ -322,7 +322,7 @@ description: "TODO" ### 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](../vph01_pokrocila_grafika/) +> Modifikace meshů mají značný přesah do otázky [Křivky a povrchy](../szp05_krivky_a_povrchy/) a taky [Pokročilá počítačová grafika](../vph01_pokrocila_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] diff --git a/szmgr/VPH01_pokrocila_grafika.md b/szmgr/VPH01_pokrocila_grafika.md index 6694f73..75cad18 100644 --- a/szmgr/VPH01_pokrocila_grafika.md +++ b/szmgr/VPH01_pokrocila_grafika.md @@ -4,7 +4,7 @@ description: "TODO" --- > [!WARNING] -> Tato je stará verze otázky. Nová verze: [Grafické principy ve vývoji her](../VPH01_graficke_principy_ve_vyvoji_her). +> Tato je stará verze otázky. Nová verze: [Grafické principy ve vývoji her](../vph01_graficke_principy_ve_vyvoji_her). > [!NOTE] > 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ů. diff --git a/szmgr/VPH02_graficke_a_fyzikalni_principy.md b/szmgr/VPH02_graficke_a_fyzikalni_principy.md index 6e613a3..9ac54ed 100644 --- a/szmgr/VPH02_graficke_a_fyzikalni_principy.md +++ b/szmgr/VPH02_graficke_a_fyzikalni_principy.md @@ -4,7 +4,7 @@ description: "TODO" --- > [!WARNING] -> Tato je stará verze otázky. Nová verze: [Fyzikální principy ve vývoji her](../VPH02_fyzikalni_principy_ve_vyvoji_her). +> Tato je stará verze otázky. Nová verze: [Fyzikální principy ve vývoji her](../vph02_fyzikalni_principy_ve_vyvoji_her). > [!NOTE] > 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. From ed2b288edad2f74f80ce69ce067208693a67ff18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Mon, 16 Jun 2025 09:27:27 +0200 Subject: [PATCH 26/44] Add bspline image --- szmgr/SZP05_krivky_a_povrchy.md | 3 +++ szmgr/img/spz05_bspline.png | Bin 0 -> 149542 bytes 2 files changed, 3 insertions(+) create mode 100644 szmgr/img/spz05_bspline.png diff --git a/szmgr/SZP05_krivky_a_povrchy.md b/szmgr/SZP05_krivky_a_povrchy.md index abc9c32..f72d219 100644 --- a/szmgr/SZP05_krivky_a_povrchy.md +++ b/szmgr/SZP05_krivky_a_povrchy.md @@ -377,6 +377,9 @@ Mezi jejich vlastnosti patří: **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. +![width=400](./img/spz05_bspline.png) + + Lze ji definovat pomocí **Cox-de Boorovy** rekurzivní formule: > [!TIP] diff --git a/szmgr/img/spz05_bspline.png b/szmgr/img/spz05_bspline.png new file mode 100644 index 0000000000000000000000000000000000000000..934009d97d0f099eaa80eb7e8074fc47d88c7f2c GIT binary patch literal 149542 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 z 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 Date: Mon, 16 Jun 2025 12:05:33 +0200 Subject: [PATCH 27/44] Fix design 1 blockquotes --- szmgr/VPH03_herni_design_i.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/szmgr/VPH03_herni_design_i.md b/szmgr/VPH03_herni_design_i.md index 55e6c21..a66130d 100644 --- a/szmgr/VPH03_herni_design_i.md +++ b/szmgr/VPH03_herni_design_i.md @@ -72,9 +72,10 @@ Hry se dají (poměrně hnidopišsky a rozhodně ne jednoznačně) rozdělit na: - **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. +> [!NOTE] +> 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]. @@ -92,17 +93,17 @@ Lidi jsou různí a různí lidi hrají různé hry různě. - **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. + > What happened? I missed it, I was talking. - **Killer**\ Působí na ostatní hráče. Záleží mu na jeho skillech a reputaci. - Die! + > 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! + > Only 4211 points to go! - **Explorer**\ Snaží se objevovat a poznávat svět. Je hrdý na hloubku svých znalostí o světě. From cf2b7b1f4dbe3ca0a17f6a7e13a7743ca1b3db50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Thu, 19 Jun 2025 22:08:28 +0200 Subject: [PATCH 28/44] Typos --- szmgr/VPH03_herni_design_i.md | 4 ++-- szmgr/VPH05_vyvoj_her.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/szmgr/VPH03_herni_design_i.md b/szmgr/VPH03_herni_design_i.md index a66130d..ccae080 100644 --- a/szmgr/VPH03_herni_design_i.md +++ b/szmgr/VPH03_herni_design_i.md @@ -246,7 +246,7 @@ Game designer produkuje taky hromady abstraktních teorií o herním designu. > - 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 @@ -271,7 +271,7 @@ Při balancování hry designer úmyslně ničí svoji hru, aby odhalil její hr - 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. +Zjednodušit a předat informace o tom co funguje a co ne ostatním. Musí umět obhájit své návrhy. ## The Core Game Ontology diff --git a/szmgr/VPH05_vyvoj_her.md b/szmgr/VPH05_vyvoj_her.md index 8062d64..4cbeb67 100644 --- a/szmgr/VPH05_vyvoj_her.md +++ b/szmgr/VPH05_vyvoj_her.md @@ -37,7 +37,7 @@ I přes to, že je game engine obecný, neznamená to, že v něm dokážeme (ro - Crash reporty - Debug gizmos (debug ray, box, sphere...) - Debug menu a konzole -- **Zvkuk**\ +- **Zvuk**\ Speciální engine pro zvuk, často middleware jako FMOD nebo Wwise. - **Graphics**\ Zařizuje vykreslování grafiky, osvětlení, stíny, postprocessing, atd. From b07bf51b747195470d5bff4eff43132478ba5037 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Thu, 19 Jun 2025 22:08:37 +0200 Subject: [PATCH 29/44] Icons + fortunate brain --- szmgr/SZP05_krivky_a_povrchy.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/szmgr/SZP05_krivky_a_povrchy.md b/szmgr/SZP05_krivky_a_povrchy.md index f72d219..0406546 100644 --- a/szmgr/SZP05_krivky_a_povrchy.md +++ b/szmgr/SZP05_krivky_a_povrchy.md @@ -684,5 +684,4 @@ Polygonové povrchy dělíme v případě, kdy chceme je zjemnit, vyhladit. - [NURBS Calculator](http://nurbscalculator.in/) - [ČVUT: Computer Graphics](https://mat.fs.cvut.cz/computer-graphics/) -<div class="fortunate-brain"> -</div> +
From 2c1421e8a420fa8616cd2cfa3833ff1811a1fb9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vojte=CC=8Cch=20Struha=CC=81r?= Date: Thu, 19 Jun 2025 22:52:04 +0200 Subject: [PATCH 30/44] Fix table --- szmgr/SZP04_3d_modelovani.md | 48 +++++++++--------------------------- 1 file changed, 12 insertions(+), 36 deletions(-) diff --git a/szmgr/SZP04_3d_modelovani.md b/szmgr/SZP04_3d_modelovani.md index 422d3ec..3980cc6 100644 --- a/szmgr/SZP04_3d_modelovani.md +++ b/szmgr/SZP04_3d_modelovani.md @@ -219,42 +219,18 @@ description: "TODO" 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 -|==== + | 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 | + | 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. From 9e89f8b41f539084b8a052c459051bbb4e84fa6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20=C5=A0t=C4=9Bp=C3=A1nek?= Date: Sun, 20 Jul 2025 22:29:46 +0200 Subject: [PATCH 31/44] Switch from markdown-it to remark and reintroduce alerts --- _config.ts | 71 ++-- _plugins/remark-alerts.ts | 172 +++++++++ deno.lock | 759 +++++++++++++++++++++++++++++++++++++- 3 files changed, 972 insertions(+), 30 deletions(-) create mode 100644 _plugins/remark-alerts.ts diff --git a/_config.ts b/_config.ts index 4941791..f416022 100644 --- a/_config.ts +++ b/_config.ts @@ -1,5 +1,7 @@ import lume from "lume/mod.ts"; import markdown from "lume/plugins/markdown.ts"; +import remark from "lume/plugins/remark.ts"; +import remarkAlert from "./_plugins/remark-alerts.ts"; import jsx from "lume/plugins/jsx.ts"; import sass from "lume/plugins/sass.ts"; import postcss from "lume/plugins/postcss.ts"; @@ -26,32 +28,51 @@ const site = lume({ }); site.ignore("readme.md", "contributing.md", "public", "deps.ts", "_plugins"); -site.use(markdown({ - plugins: [[markdownItAlerts, { - titles: { - "tip": "", - "note": "", - "important": "", - "warning": "", - "caution": "" - }, - icons: { - "tip": " ", - "note": " ", - "important": " ", - "warning": " ", - "caution": " " - }, - classPrefix: "alert" - }]] -})); -site.use(toc({ - tabIndex: false, - // anchor: false, - anchor: linkInsideHeader({ - placement: "before" - }) +// site.use(markdown({ +// plugins: [[markdownItAlerts, { +// titles: { +// "tip": "", +// "note": "", +// "important": "", +// "warning": "", +// "caution": "" +// }, +// icons: { +// "tip": " ", +// "note": " ", +// "important": " ", +// "warning": " ", +// "caution": " " +// }, +// classPrefix: "alert" +// }]] +// })); +site.use(remark({ + remarkPlugins: [ + [remarkAlert, { + classPrefix: "alert", + icons: { + "TIP": "", + "NOTE": "", + "WARNING": "" + }, + titles: { + "TIP": "Tip", + "NOTE": "Poznámka", + "WARNING": "Varování", + "IMPORTANT": "Důležitost", + "CAUTION": "Bacha!" + } + }] + ] })); +// site.use(toc({ +// tabIndex: false, +// // anchor: false, +// anchor: linkInsideHeader({ +// placement: "before" +// }) +// })); site.use(jsx()); site.use(esbuild({ options: { diff --git a/_plugins/remark-alerts.ts b/_plugins/remark-alerts.ts new file mode 100644 index 0000000..6bc7921 --- /dev/null +++ b/_plugins/remark-alerts.ts @@ -0,0 +1,172 @@ +/* + * Based on https://github.com/hyoban/remark-github-alerts by Stephen Zhou (hyoban), MIT licensed. + */ + +import type { Paragraph, Root, Html } from "npm:@types/mdast"; +import type { Plugin } from "npm:unified"; +import { visit } from "npm:unist-util-visit"; + +export type RemarkGitHubAlertsOptions = { + /** + * List of markers to match. + * @default ['TIP', 'NOTE', 'IMPORTANT', 'WARNING', 'CAUTION'] + */ + markers?: string[] | '*' + + /** + * If markers case sensitively on matching. + * @default false + */ + matchCaseSensitive?: boolean + + /** + * Custom icons for each marker. The key is the marker name, and the value is the html script represent the icon. + * The key is always lowercase. + * + * @default inline svg icons from GitHub + */ + icons?: Record + + /** + * Custom titles for each marker. The key is the marker name, and the value is the title. + * The key is always lowercase. + * + * When the title is not specified, the default title is the capitalized marker name. + */ + titles?: Record + + /** + * Prefix for the class names. + * + * @default 'markdown-alert' + */ + classPrefix?: string + + // ^ options from MarkdownItGitHubAlertsOptions + + /** + * Whether to ignore the square brackets in the marker. + * + * @default false + */ + ignoreSquareBracket?: boolean +} + +function capitalize(str: string) { + return str.charAt(0).toUpperCase() + str.slice(1) +} + +const DEFAULT_GITHUB_ICONS = { + note: '', + tip: '', + important: '', + warning: '', + caution: '', +} + +// https://bl.ocks.org/jennyknuth/222825e315d45a738ed9d6e04c7a88d0 +function encodeSvg(svg: string) { + return svg.replace('', '%3E') +} + +const remarkGithubAlerts: Plugin = ( + options = {}, +) => { + const { + markers = ['TIP', 'NOTE', 'IMPORTANT', 'WARNING', 'CAUTION'], + icons = DEFAULT_GITHUB_ICONS, + matchCaseSensitive = false, + titles = {}, + classPrefix = 'markdown-alert', + ignoreSquareBracket = false, + } = options + + const markerNameRE = markers === '*' ? '\\w+' : markers.join('|') + const RE = new RegExp( + ignoreSquareBracket + ? `^!(${markerNameRE})([^\\n\\r]*)` + : `^\\[\\!(${markerNameRE})\\]([^\\n\\r]*)`, + matchCaseSensitive ? '' : 'i', + ) + + return (tree) => { + visit(tree, 'blockquote', (node, index, parent) => { + const children = node.children as Paragraph[] + const firstParagraph = children[0] + if (!firstParagraph) + return + let firstContent = firstParagraph.children?.[0] + if (!firstContent) + return + if ( + !('value' in firstContent) + && 'children' in firstContent + && firstContent.children[0] + ) { + firstContent = firstContent.children[0] + } + + if (firstContent.type !== 'text') + return + const match = firstContent.value.match(RE) + if (!match) + return + + const type = match[1]?.toLowerCase() as keyof typeof icons + const title = match[2]?.trim() || (titles[type] ?? capitalize(type)) + const icon = icons[type] + + if (index === undefined || !parent) + return + + firstContent.value = firstContent.value.slice(match[0].length).trimStart() + + node.data = { + hName: 'div', + hProperties: { + class: `${classPrefix} ${classPrefix}-${type}`, + }, + } + node.children = [ + { + type: 'paragraph', + data: { + hName: 'p', + hProperties: { + class: `${classPrefix}-title`, + }, + }, + children: [ + ...(icon === undefined ? [] : [{ + type: "html", + value: "", + data: { + hName: "span", + hProperties: { + class: "octicon octicon-${type}", + style: `--oct-icon: url("${`data:image/svg+xml;utf8,${encodeSvg(icon)}`}")` + } + } + } as Html]), + { + type: 'text', + value: title, + }, + ], + }, + ...node.children, + ] + }) + + return tree + } +} + +export default remarkGithubAlerts diff --git a/deno.lock b/deno.lock index c1beec9..60f9afe 100644 --- a/deno.lock +++ b/deno.lock @@ -81,6 +81,7 @@ "npm:markdown-it@*": "14.0.0", "npm:markdown-it@14.0.0": "14.0.0", "npm:markdown-it@14.1.0": "14.1.0", + "npm:mdast@*": "3.0.0", "npm:meriyah@6.0.3": "6.0.3", "npm:meriyah@6.0.5": "6.0.5", "npm:pagefind@1.0.4": "1.0.4", @@ -99,6 +100,15 @@ "npm:react-dom@18.2.0": "18.2.0_react@18.2.0", "npm:react@*": "18.2.0", "npm:react@18.2.0": "18.2.0", + "npm:rehype-raw@7.0.0": "7.0.0", + "npm:rehype-sanitize@6.0.0": "6.0.0", + "npm:rehype-stringify@10.0.1": "10.0.1", + "npm:remark-gfm@4.0.1": "4.0.1", + "npm:remark-github-alerts@*": "0.1.1_@types+mdast@4.0.4_unified@11.0.5", + "npm:remark-github-blockquote-alert@*": "1.3.1", + "npm:remark-parse@11.0.0": "11.0.0", + "npm:remark-rehype@11.1.2": "11.1.2", + "npm:remark@*": "15.0.1", "npm:remove-markdown@0.6.2": "0.6.2", "npm:sass@1.69.6": "1.69.6", "npm:sass@1.69.7": "1.69.7", @@ -111,7 +121,10 @@ "npm:shiki@*": "0.14.7", "npm:svg2png-wasm@1.4.1": "1.4.1", "npm:unidecode@0.1.8": "0.1.8", - "npm:unidecode@1.1.0": "1.1.0" + "npm:unidecode@1.1.0": "1.1.0", + "npm:unified@*": "11.0.5", + "npm:unified@11.0.5": "11.0.5", + "npm:unist-util-visit@*": "5.0.0" }, "jsr": { "@davidbonnet/astring@1.8.6": { @@ -1012,9 +1025,30 @@ ], "scripts": true }, + "@types/debug@4.1.12": { + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": [ + "@types/ms" + ] + }, "@types/estree@1.0.6": { "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" }, + "@types/hast@3.0.4": { + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "dependencies": [ + "@types/unist" + ] + }, + "@types/mdast@4.0.4": { + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "dependencies": [ + "@types/unist" + ] + }, + "@types/ms@2.1.0": { + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==" + }, "@types/node@18.16.19": { "integrity": "sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA==" }, @@ -1032,6 +1066,12 @@ "@types/scheduler@0.16.8": { "integrity": "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A==" }, + "@types/unist@3.0.3": { + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==" + }, + "@ungap/structured-clone@1.3.0": { + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==" + }, "ansi-sequence-parser@1.1.1": { "integrity": "sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==" }, @@ -1095,6 +1135,9 @@ ], "bin": true }, + "bail@2.0.2": { + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==" + }, "balanced-match@1.0.2": { "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, @@ -1158,6 +1201,18 @@ "caniuse-lite@1.0.30001727": { "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==" }, + "ccount@2.0.1": { + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==" + }, + "character-entities-html4@2.1.0": { + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==" + }, + "character-entities-legacy@3.0.0": { + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==" + }, + "character-entities@2.0.2": { + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==" + }, "chokidar@3.5.3": { "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", "dependencies": [ @@ -1202,6 +1257,9 @@ "color-string" ] }, + "comma-separated-tokens@2.0.3": { + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==" + }, "commander@8.3.0": { "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==" }, @@ -1212,6 +1270,21 @@ "csstype@3.1.3": { "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" }, + "debug@4.4.1": { + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dependencies": [ + "ms" + ] + }, + "decode-named-character-reference@1.2.0": { + "integrity": "sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==", + "dependencies": [ + "character-entities" + ] + }, + "dequal@2.0.3": { + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==" + }, "detect-libc@1.0.3": { "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", "bin": true @@ -1225,12 +1298,18 @@ "detect-libc@2.0.4": { "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==" }, + "devlop@1.1.0": { + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "dependencies": [ + "dequal" + ] + }, "dom-serializer@2.0.0": { "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dependencies": [ "domelementtype", "domhandler", - "entities" + "entities@4.5.0" ] }, "domelementtype@2.3.0": { @@ -1262,18 +1341,27 @@ "entities@4.5.0": { "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==" }, + "entities@6.0.1": { + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==" + }, "escalade@3.1.1": { "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" }, "escalade@3.2.0": { "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==" }, + "escape-string-regexp@5.0.0": { + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==" + }, "estree-walker@3.0.3": { "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", "dependencies": [ "@types/estree" ] }, + "extend@3.0.2": { + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" + }, "fill-range@7.0.1": { "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", "dependencies": [ @@ -1323,6 +1411,95 @@ "function-bind" ] }, + "hast-util-from-parse5@8.0.3": { + "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", + "dependencies": [ + "@types/hast", + "@types/unist", + "devlop", + "hastscript", + "property-information@7.1.0", + "vfile", + "vfile-location", + "web-namespaces" + ] + }, + "hast-util-parse-selector@4.0.0": { + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "dependencies": [ + "@types/hast" + ] + }, + "hast-util-raw@9.1.0": { + "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", + "dependencies": [ + "@types/hast", + "@types/unist", + "@ungap/structured-clone", + "hast-util-from-parse5", + "hast-util-to-parse5", + "html-void-elements", + "mdast-util-to-hast", + "parse5", + "unist-util-position", + "unist-util-visit", + "vfile", + "web-namespaces", + "zwitch" + ] + }, + "hast-util-sanitize@5.0.2": { + "integrity": "sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==", + "dependencies": [ + "@types/hast", + "@ungap/structured-clone", + "unist-util-position" + ] + }, + "hast-util-to-html@9.0.5": { + "integrity": "sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==", + "dependencies": [ + "@types/hast", + "@types/unist", + "ccount", + "comma-separated-tokens", + "hast-util-whitespace", + "html-void-elements", + "mdast-util-to-hast", + "property-information@7.1.0", + "space-separated-tokens", + "stringify-entities", + "zwitch" + ] + }, + "hast-util-to-parse5@8.0.0": { + "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", + "dependencies": [ + "@types/hast", + "comma-separated-tokens", + "devlop", + "property-information@6.5.0", + "space-separated-tokens", + "web-namespaces", + "zwitch" + ] + }, + "hast-util-whitespace@3.0.0": { + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "dependencies": [ + "@types/hast" + ] + }, + "hastscript@9.0.1": { + "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", + "dependencies": [ + "@types/hast", + "comma-separated-tokens", + "hast-util-parse-selector", + "property-information@7.1.0", + "space-separated-tokens" + ] + }, "html-dom-parser@5.0.7": { "integrity": "sha512-2YD2/yB0QgrlkBIn0CsGaRXC89E1gtuPVpiOGC52NTzPCC83n0WMdGD+5q7lpcKqbCpnWValQbovuy/NI/0kag==", "dependencies": [ @@ -1340,13 +1517,16 @@ "style-to-js" ] }, + "html-void-elements@3.0.0": { + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==" + }, "htmlparser2@9.1.0": { "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", "dependencies": [ "domelementtype", "domhandler", "domutils", - "entities" + "entities@4.5.0" ] }, "ico-endec@0.1.6": { @@ -1399,6 +1579,9 @@ "is-number@7.0.0": { "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" }, + "is-plain-obj@4.1.0": { + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==" + }, "js-tokens@4.0.0": { "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, @@ -1445,6 +1628,9 @@ "uc.micro@2.0.0" ] }, + "longest-streak@3.1.0": { + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==" + }, "loose-envify@1.4.0": { "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dependencies": [ @@ -1492,7 +1678,7 @@ "integrity": "sha512-seFjF0FIcPt4P9U39Bq1JYblX0KZCjDLFFQPHpL5AzHpqPEKtosxmdq/LTVZnjfH7tjt9BxStm+wXcDBNuYmzw==", "dependencies": [ "argparse", - "entities", + "entities@4.5.0", "linkify-it", "mdurl", "punycode.js", @@ -1504,7 +1690,7 @@ "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", "dependencies": [ "argparse", - "entities", + "entities@4.5.0", "linkify-it", "mdurl", "punycode.js", @@ -1512,6 +1698,139 @@ ], "bin": true }, + "markdown-table@3.0.4": { + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==" + }, + "mdast-util-find-and-replace@3.0.2": { + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "dependencies": [ + "@types/mdast", + "escape-string-regexp", + "unist-util-is", + "unist-util-visit-parents" + ] + }, + "mdast-util-from-markdown@2.0.2": { + "integrity": "sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==", + "dependencies": [ + "@types/mdast", + "@types/unist", + "decode-named-character-reference", + "devlop", + "mdast-util-to-string", + "micromark", + "micromark-util-decode-numeric-character-reference", + "micromark-util-decode-string", + "micromark-util-normalize-identifier", + "micromark-util-symbol", + "micromark-util-types", + "unist-util-stringify-position" + ] + }, + "mdast-util-gfm-autolink-literal@2.0.1": { + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "dependencies": [ + "@types/mdast", + "ccount", + "devlop", + "mdast-util-find-and-replace", + "micromark-util-character" + ] + }, + "mdast-util-gfm-footnote@2.1.0": { + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "dependencies": [ + "@types/mdast", + "devlop", + "mdast-util-from-markdown", + "mdast-util-to-markdown", + "micromark-util-normalize-identifier" + ] + }, + "mdast-util-gfm-strikethrough@2.0.0": { + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "dependencies": [ + "@types/mdast", + "mdast-util-from-markdown", + "mdast-util-to-markdown" + ] + }, + "mdast-util-gfm-table@2.0.0": { + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "dependencies": [ + "@types/mdast", + "devlop", + "markdown-table", + "mdast-util-from-markdown", + "mdast-util-to-markdown" + ] + }, + "mdast-util-gfm-task-list-item@2.0.0": { + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "dependencies": [ + "@types/mdast", + "devlop", + "mdast-util-from-markdown", + "mdast-util-to-markdown" + ] + }, + "mdast-util-gfm@3.1.0": { + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "dependencies": [ + "mdast-util-from-markdown", + "mdast-util-gfm-autolink-literal", + "mdast-util-gfm-footnote", + "mdast-util-gfm-strikethrough", + "mdast-util-gfm-table", + "mdast-util-gfm-task-list-item", + "mdast-util-to-markdown" + ] + }, + "mdast-util-phrasing@4.1.0": { + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "dependencies": [ + "@types/mdast", + "unist-util-is" + ] + }, + "mdast-util-to-hast@13.2.0": { + "integrity": "sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==", + "dependencies": [ + "@types/hast", + "@types/mdast", + "@ungap/structured-clone", + "devlop", + "micromark-util-sanitize-uri", + "trim-lines", + "unist-util-position", + "unist-util-visit", + "vfile" + ] + }, + "mdast-util-to-markdown@2.1.2": { + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "dependencies": [ + "@types/mdast", + "@types/unist", + "longest-streak", + "mdast-util-phrasing", + "mdast-util-to-string", + "micromark-util-classify-character", + "micromark-util-decode-string", + "unist-util-visit", + "zwitch" + ] + }, + "mdast-util-to-string@4.0.0": { + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "dependencies": [ + "@types/mdast" + ] + }, + "mdast@3.0.0": { + "integrity": "sha512-xySmf8g4fPKMeC07jXGz971EkLbWAJ83s4US2Tj9lEdnZ142UP5grN73H1Xd3HzrdbU5o9GYYP/y8F9ZSwLE9g==", + "deprecated": true + }, "mdurl@2.0.0": { "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==" }, @@ -1521,6 +1840,247 @@ "meriyah@6.0.5": { "integrity": "sha512-SrMqQCox7TTwtftWKHy/ZaVe+ZRpRl20pAgDo+PS9hzcAJrMjYsBJQPPiLXTnjztrqdfGS+Zz99r6Bwvydta1w==" }, + "micromark-core-commonmark@2.0.3": { + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "dependencies": [ + "decode-named-character-reference", + "devlop", + "micromark-factory-destination", + "micromark-factory-label", + "micromark-factory-space", + "micromark-factory-title", + "micromark-factory-whitespace", + "micromark-util-character", + "micromark-util-chunked", + "micromark-util-classify-character", + "micromark-util-html-tag-name", + "micromark-util-normalize-identifier", + "micromark-util-resolve-all", + "micromark-util-subtokenize", + "micromark-util-symbol", + "micromark-util-types" + ] + }, + "micromark-extension-gfm-autolink-literal@2.1.0": { + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "dependencies": [ + "micromark-util-character", + "micromark-util-sanitize-uri", + "micromark-util-symbol", + "micromark-util-types" + ] + }, + "micromark-extension-gfm-footnote@2.1.0": { + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "dependencies": [ + "devlop", + "micromark-core-commonmark", + "micromark-factory-space", + "micromark-util-character", + "micromark-util-normalize-identifier", + "micromark-util-sanitize-uri", + "micromark-util-symbol", + "micromark-util-types" + ] + }, + "micromark-extension-gfm-strikethrough@2.1.0": { + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "dependencies": [ + "devlop", + "micromark-util-chunked", + "micromark-util-classify-character", + "micromark-util-resolve-all", + "micromark-util-symbol", + "micromark-util-types" + ] + }, + "micromark-extension-gfm-table@2.1.1": { + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "dependencies": [ + "devlop", + "micromark-factory-space", + "micromark-util-character", + "micromark-util-symbol", + "micromark-util-types" + ] + }, + "micromark-extension-gfm-tagfilter@2.0.0": { + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "dependencies": [ + "micromark-util-types" + ] + }, + "micromark-extension-gfm-task-list-item@2.1.0": { + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "dependencies": [ + "devlop", + "micromark-factory-space", + "micromark-util-character", + "micromark-util-symbol", + "micromark-util-types" + ] + }, + "micromark-extension-gfm@3.0.0": { + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "dependencies": [ + "micromark-extension-gfm-autolink-literal", + "micromark-extension-gfm-footnote", + "micromark-extension-gfm-strikethrough", + "micromark-extension-gfm-table", + "micromark-extension-gfm-tagfilter", + "micromark-extension-gfm-task-list-item", + "micromark-util-combine-extensions", + "micromark-util-types" + ] + }, + "micromark-factory-destination@2.0.1": { + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "dependencies": [ + "micromark-util-character", + "micromark-util-symbol", + "micromark-util-types" + ] + }, + "micromark-factory-label@2.0.1": { + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "dependencies": [ + "devlop", + "micromark-util-character", + "micromark-util-symbol", + "micromark-util-types" + ] + }, + "micromark-factory-space@2.0.1": { + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "dependencies": [ + "micromark-util-character", + "micromark-util-types" + ] + }, + "micromark-factory-title@2.0.1": { + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "dependencies": [ + "micromark-factory-space", + "micromark-util-character", + "micromark-util-symbol", + "micromark-util-types" + ] + }, + "micromark-factory-whitespace@2.0.1": { + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "dependencies": [ + "micromark-factory-space", + "micromark-util-character", + "micromark-util-symbol", + "micromark-util-types" + ] + }, + "micromark-util-character@2.1.1": { + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "dependencies": [ + "micromark-util-symbol", + "micromark-util-types" + ] + }, + "micromark-util-chunked@2.0.1": { + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "dependencies": [ + "micromark-util-symbol" + ] + }, + "micromark-util-classify-character@2.0.1": { + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "dependencies": [ + "micromark-util-character", + "micromark-util-symbol", + "micromark-util-types" + ] + }, + "micromark-util-combine-extensions@2.0.1": { + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "dependencies": [ + "micromark-util-chunked", + "micromark-util-types" + ] + }, + "micromark-util-decode-numeric-character-reference@2.0.2": { + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "dependencies": [ + "micromark-util-symbol" + ] + }, + "micromark-util-decode-string@2.0.1": { + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "dependencies": [ + "decode-named-character-reference", + "micromark-util-character", + "micromark-util-decode-numeric-character-reference", + "micromark-util-symbol" + ] + }, + "micromark-util-encode@2.0.1": { + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==" + }, + "micromark-util-html-tag-name@2.0.1": { + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==" + }, + "micromark-util-normalize-identifier@2.0.1": { + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "dependencies": [ + "micromark-util-symbol" + ] + }, + "micromark-util-resolve-all@2.0.1": { + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "dependencies": [ + "micromark-util-types" + ] + }, + "micromark-util-sanitize-uri@2.0.1": { + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "dependencies": [ + "micromark-util-character", + "micromark-util-encode", + "micromark-util-symbol" + ] + }, + "micromark-util-subtokenize@2.1.0": { + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "dependencies": [ + "devlop", + "micromark-util-chunked", + "micromark-util-symbol", + "micromark-util-types" + ] + }, + "micromark-util-symbol@2.0.1": { + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==" + }, + "micromark-util-types@2.0.2": { + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==" + }, + "micromark@4.0.2": { + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "dependencies": [ + "@types/debug", + "debug", + "decode-named-character-reference", + "devlop", + "micromark-core-commonmark", + "micromark-factory-space", + "micromark-util-character", + "micromark-util-chunked", + "micromark-util-combine-extensions", + "micromark-util-decode-numeric-character-reference", + "micromark-util-encode", + "micromark-util-normalize-identifier", + "micromark-util-resolve-all", + "micromark-util-sanitize-uri", + "micromark-util-subtokenize", + "micromark-util-symbol", + "micromark-util-types" + ] + }, "micromatch@4.0.8": { "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dependencies": [ @@ -1538,6 +2098,9 @@ "integrity": "sha512-sjAkg21peAG9HS+Dkx7hlG9Ztx7HLeKnvB3NQRcu/mltCVmvkF0pisbiTSfDVYTT86XEfZrTUosLdZLStquZUw==", "bin": true }, + "ms@2.1.3": { + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, "nanoid@3.3.11": { "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", "bin": true @@ -1606,6 +2169,12 @@ "pako@2.1.0": { "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" }, + "parse5@7.3.0": { + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dependencies": [ + "entities@6.0.1" + ] + }, "path-parse@1.0.7": { "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==" }, @@ -1710,6 +2279,12 @@ "preact@10.25.1": { "integrity": "sha512-frxeZV2vhQSohQwJ7FvlqC40ze89+8friponWUFeVEkaCfhC6Eu4V0iND5C9CXz8JLndV07QRDeXzH1+Anz5Og==" }, + "property-information@6.5.0": { + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==" + }, + "property-information@7.1.0": { + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==" + }, "punycode.js@2.3.1": { "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==" }, @@ -1745,6 +2320,90 @@ "readdirp@4.0.2": { "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==" }, + "rehype-raw@7.0.0": { + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "dependencies": [ + "@types/hast", + "hast-util-raw", + "vfile" + ] + }, + "rehype-sanitize@6.0.0": { + "integrity": "sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg==", + "dependencies": [ + "@types/hast", + "hast-util-sanitize" + ] + }, + "rehype-stringify@10.0.1": { + "integrity": "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==", + "dependencies": [ + "@types/hast", + "hast-util-to-html", + "unified" + ] + }, + "remark-gfm@4.0.1": { + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "dependencies": [ + "@types/mdast", + "mdast-util-gfm", + "micromark-extension-gfm", + "remark-parse", + "remark-stringify", + "unified" + ] + }, + "remark-github-alerts@0.1.1_@types+mdast@4.0.4_unified@11.0.5": { + "integrity": "sha512-A0NLfeAuu76ymiGIoEoBcHmqlPcdLFq+FoCGiWlzu8vkyhscyDv+pAkMA9paGr+OHpzpFflZKnsqOCvMESG/Uw==", + "dependencies": [ + "@types/mdast", + "unified", + "unist-util-visit" + ] + }, + "remark-github-blockquote-alert@1.3.1": { + "integrity": "sha512-OPNnimcKeozWN1w8KVQEuHOxgN3L4rah8geMOLhA5vN9wITqU4FWD+G26tkEsCGHiOVDbISx+Se5rGZ+D1p0Jg==", + "dependencies": [ + "unist-util-visit" + ] + }, + "remark-parse@11.0.0": { + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "dependencies": [ + "@types/mdast", + "mdast-util-from-markdown", + "micromark-util-types", + "unified" + ] + }, + "remark-rehype@11.1.2": { + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "dependencies": [ + "@types/hast", + "@types/mdast", + "mdast-util-to-hast", + "unified", + "vfile" + ] + }, + "remark-stringify@11.0.0": { + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "dependencies": [ + "@types/mdast", + "mdast-util-to-markdown", + "unified" + ] + }, + "remark@15.0.1": { + "integrity": "sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==", + "dependencies": [ + "@types/mdast", + "remark-parse", + "remark-stringify", + "unified" + ] + }, "remove-markdown@0.6.2": { "integrity": "sha512-EijDXJZbzpGbQBd852ViUzcqgpMujthM+SAEHiWCMcZonRbZ+xViWKLJA/vrwbDwYdxrs1aFDjpBhcGrZoJRGA==" }, @@ -1967,6 +2626,16 @@ "source-map-js@1.2.1": { "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==" }, + "space-separated-tokens@2.0.2": { + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==" + }, + "stringify-entities@4.0.4": { + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "dependencies": [ + "character-entities-html4", + "character-entities-legacy" + ] + }, "style-to-js@1.1.10": { "integrity": "sha512-VC7MBJa+y0RZhpnLKDPmVRLRswsASLmixkiZ5R8xZpNT9VyjeRzwnXd2pBzAWdgSGv/pCNNH01gPCCUsB9exYg==", "dependencies": [ @@ -1992,6 +2661,12 @@ "is-number" ] }, + "trim-lines@3.0.1": { + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==" + }, + "trough@2.2.0": { + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==" + }, "tslib@2.6.2": { "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, @@ -2007,6 +2682,51 @@ "unidecode@1.1.0": { "integrity": "sha512-GIp57N6DVVJi8dpeIU6/leJGdv7W65ZSXFLFiNmxvexXkc0nXdqUvhA/qL9KqBKsILxMwg5MnmYNOIDJLb5JVA==" }, + "unified@11.0.5": { + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "dependencies": [ + "@types/unist", + "bail", + "devlop", + "extend", + "is-plain-obj", + "trough", + "vfile" + ] + }, + "unist-util-is@6.0.0": { + "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", + "dependencies": [ + "@types/unist" + ] + }, + "unist-util-position@5.0.0": { + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "dependencies": [ + "@types/unist" + ] + }, + "unist-util-stringify-position@4.0.0": { + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "dependencies": [ + "@types/unist" + ] + }, + "unist-util-visit-parents@6.0.1": { + "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", + "dependencies": [ + "@types/unist", + "unist-util-is" + ] + }, + "unist-util-visit@5.0.0": { + "integrity": "sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==", + "dependencies": [ + "@types/unist", + "unist-util-is", + "unist-util-visit-parents" + ] + }, "unxhr@1.2.0": { "integrity": "sha512-6cGpm8NFXPD9QbSNx0cD2giy7teZ6xOkCUH3U89WKVkL9N9rBrWjlCwhR94Re18ZlAop4MOc3WU1M3Hv/bgpIw==" }, @@ -2040,17 +2760,44 @@ "util-deprecate@1.0.2": { "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" }, + "vfile-location@5.0.3": { + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "dependencies": [ + "@types/unist", + "vfile" + ] + }, + "vfile-message@4.0.2": { + "integrity": "sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==", + "dependencies": [ + "@types/unist", + "unist-util-stringify-position" + ] + }, + "vfile@6.0.3": { + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "dependencies": [ + "@types/unist", + "vfile-message" + ] + }, "vscode-oniguruma@1.7.0": { "integrity": "sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==" }, "vscode-textmate@8.0.0": { "integrity": "sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==" }, + "web-namespaces@2.0.1": { + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==" + }, "wrappy@1.0.2": { "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "yallist@4.0.0": { "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "zwitch@2.0.4": { + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==" } }, "redirects": { @@ -3196,6 +3943,7 @@ "https://deno.land/x/lume@v3.0.5/deps/pagefind.ts": "b88cbf55ec97a7b02100a9b68c9f16bcc622e0d93122b6a19c766c389a167e35", "https://deno.land/x/lume@v3.0.5/deps/path.ts": "694822db2e75db402af9ef4dc451c1ed3232c108a54c0a394e9bbd6eac952a6c", "https://deno.land/x/lume@v3.0.5/deps/postcss.ts": "7ad7485032d40a2bc7977eb71d9431df8d52b53d61153e60b38c29d1c98cb870", + "https://deno.land/x/lume@v3.0.5/deps/remark.ts": "19d3f6461a9b9c2cb7eb2354ed48d4be2f183e5b4f3281b67eebd75dd5e49d02", "https://deno.land/x/lume@v3.0.5/deps/remove-markdown.ts": "e304dcdd2c1042a1de5b2df53c9c8c39f4462307f95d13e4b2fa1ded26851013", "https://deno.land/x/lume@v3.0.5/deps/sass.ts": "9ae4666ff5651250ca183f32a7e233629008f97f13082034d88b58d8afe93a18", "https://deno.land/x/lume@v3.0.5/deps/sharp.ts": "3c7f0b764ccd6e3c4d56c92b03140e264180ab2c7e9469df0590a5a0a655efb5", @@ -3226,6 +3974,7 @@ "https://deno.land/x/lume@v3.0.5/plugins/paginate.ts": "6a1a9a24d0fabed2f722a6a6f29d98559219c69475685034181816e82d367f2e", "https://deno.land/x/lume@v3.0.5/plugins/picture.ts": "7cfa6bff4e4432b8dfb90d13108249adb71a02a6c76fbffd8b372d1516bcfae4", "https://deno.land/x/lume@v3.0.5/plugins/postcss.ts": "f6ff9ac8377ecb77b15870e162999b5d72e8728788b2312e0aed8a8dcaa5cb09", + "https://deno.land/x/lume@v3.0.5/plugins/remark.ts": "3ce9d92dee6455c522e46933ab2bfe9737f1dd0736fbdd3a1306e896075195a5", "https://deno.land/x/lume@v3.0.5/plugins/resolve_urls.ts": "910dbccd25fcacacc72d577a3df37c5f3cc4adce0ec52b2fc8903863c2e2afae", "https://deno.land/x/lume@v3.0.5/plugins/sass.ts": "09636afcb43a3fecc327e4822202df567509f6999962fa0890b75dbf2dbe06f6", "https://deno.land/x/lume@v3.0.5/plugins/search.ts": "5acb5be828bbbd012fb9226cb97ec3e370d43d05aa44d16e7e7d50bab368b442", From 53b85f66f535df31bb9278ce7e270a83614fea64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20=C5=A0t=C4=9Bp=C3=A1nek?= Date: Sun, 20 Jul 2025 22:47:16 +0200 Subject: [PATCH 32/44] Add back definition lists --- _config.ts | 11 +++- deno.lock | 143 +++++++++++++++++++++++++++++++++++++++++++++++++ sample.md | 14 ++++- szmgr/index.md | 122 ++++++++++++++++++++++++++--------------- 4 files changed, 243 insertions(+), 47 deletions(-) diff --git a/_config.ts b/_config.ts index f416022..309433f 100644 --- a/_config.ts +++ b/_config.ts @@ -2,6 +2,7 @@ import lume from "lume/mod.ts"; import markdown from "lume/plugins/markdown.ts"; import remark from "lume/plugins/remark.ts"; import remarkAlert from "./_plugins/remark-alerts.ts"; +import { remarkDefinitionList, defListHastHandlers } from "npm:remark-definition-list"; import jsx from "lume/plugins/jsx.ts"; import sass from "lume/plugins/sass.ts"; import postcss from "lume/plugins/postcss.ts"; @@ -63,8 +64,14 @@ site.use(remark({ "IMPORTANT": "Důležitost", "CAUTION": "Bacha!" } - }] - ] + }], + [remarkDefinitionList] + ], + rehypeOptions: { + handlers: { + ...defListHastHandlers + } + } })); // site.use(toc({ // tabIndex: false, diff --git a/deno.lock b/deno.lock index 60f9afe..73e7a6a 100644 --- a/deno.lock +++ b/deno.lock @@ -103,6 +103,7 @@ "npm:rehype-raw@7.0.0": "7.0.0", "npm:rehype-sanitize@6.0.0": "6.0.0", "npm:rehype-stringify@10.0.1": "10.0.1", + "npm:remark-definition-list@*": "2.0.0", "npm:remark-gfm@4.0.1": "4.0.1", "npm:remark-github-alerts@*": "0.1.1_@types+mdast@4.0.4_unified@11.0.5", "npm:remark-github-blockquote-alert@*": "1.3.1", @@ -1411,6 +1412,24 @@ "function-bind" ] }, + "hast-util-definition-list@2.1.0": { + "integrity": "sha512-n3U2gleI8TYZ6eVFjE9TZsGTpaOQlMQj10+WZZFn6Ts5uEu/7XzB8HVLNeu5Sgu7Rv96ThFp79/U6bf/4pS0ew==", + "dependencies": [ + "@types/hast", + "@types/mdast", + "@types/unist", + "hast-util-to-mdast", + "mdast-util-definition-list", + "mdast-util-phrasing" + ] + }, + "hast-util-embedded@3.0.0": { + "integrity": "sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==", + "dependencies": [ + "@types/hast", + "hast-util-is-element" + ] + }, "hast-util-from-parse5@8.0.3": { "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", "dependencies": [ @@ -1424,12 +1443,50 @@ "web-namespaces" ] }, + "hast-util-has-property@3.0.0": { + "integrity": "sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==", + "dependencies": [ + "@types/hast" + ] + }, + "hast-util-is-body-ok-link@3.0.1": { + "integrity": "sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==", + "dependencies": [ + "@types/hast" + ] + }, + "hast-util-is-element@3.0.0": { + "integrity": "sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==", + "dependencies": [ + "@types/hast" + ] + }, + "hast-util-minify-whitespace@1.0.1": { + "integrity": "sha512-L96fPOVpnclQE0xzdWb/D12VT5FabA7SnZOUMtL1DbXmYiHJMXZvFkIZfiMmTCNJHUeO2K9UYNXoVyfz+QHuOw==", + "dependencies": [ + "@types/hast", + "hast-util-embedded", + "hast-util-is-element", + "hast-util-whitespace", + "unist-util-is" + ] + }, "hast-util-parse-selector@4.0.0": { "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", "dependencies": [ "@types/hast" ] }, + "hast-util-phrasing@3.0.1": { + "integrity": "sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==", + "dependencies": [ + "@types/hast", + "hast-util-embedded", + "hast-util-has-property", + "hast-util-is-body-ok-link", + "hast-util-is-element" + ] + }, "hast-util-raw@9.1.0": { "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", "dependencies": [ @@ -1472,6 +1529,25 @@ "zwitch" ] }, + "hast-util-to-mdast@10.1.2": { + "integrity": "sha512-FiCRI7NmOvM4y+f5w32jPRzcxDIz+PUqDwEqn1A+1q2cdp3B8Gx7aVrXORdOKjMNDQsD1ogOr896+0jJHW1EFQ==", + "dependencies": [ + "@types/hast", + "@types/mdast", + "@ungap/structured-clone", + "hast-util-phrasing", + "hast-util-to-html", + "hast-util-to-text", + "hast-util-whitespace", + "mdast-util-phrasing", + "mdast-util-to-hast", + "mdast-util-to-string", + "rehype-minify-whitespace", + "trim-trailing-lines", + "unist-util-position", + "unist-util-visit" + ] + }, "hast-util-to-parse5@8.0.0": { "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", "dependencies": [ @@ -1484,6 +1560,15 @@ "zwitch" ] }, + "hast-util-to-text@4.0.2": { + "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", + "dependencies": [ + "@types/hast", + "@types/unist", + "hast-util-is-element", + "unist-util-find-after" + ] + }, "hast-util-whitespace@3.0.0": { "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", "dependencies": [ @@ -1701,6 +1786,18 @@ "markdown-table@3.0.4": { "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==" }, + "mdast-util-definition-list@2.0.0": { + "integrity": "sha512-aFWuASQs77BJndNSDcNdvB1HRqWZBptcEjwv67mnPbaAZsfwMHxI8MwoQxAz4I2bHx41hft/HDRC57ZkhpayOQ==", + "dependencies": [ + "@types/mdast", + "@types/unist", + "mdast-util-from-markdown", + "mdast-util-to-hast", + "mdast-util-to-markdown", + "micromark-extension-definition-list", + "unist-builder" + ] + }, "mdast-util-find-and-replace@3.0.2": { "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", "dependencies": [ @@ -1861,6 +1958,18 @@ "micromark-util-types" ] }, + "micromark-extension-definition-list@2.0.1": { + "integrity": "sha512-lQSkVTWNR0f9qzUbM4p0chJSecIRYvZBjnI+cWqN0k2zDSvzpduGJifWJj4SpCWF4TlpNV9amCF8Y1VEXdJubQ==", + "dependencies": [ + "micromark-core-commonmark", + "micromark-factory-space", + "micromark-util-character", + "micromark-util-chunked", + "micromark-util-symbol", + "micromark-util-types", + "ts-dedent" + ] + }, "micromark-extension-gfm-autolink-literal@2.1.0": { "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", "dependencies": [ @@ -2320,6 +2429,13 @@ "readdirp@4.0.2": { "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==" }, + "rehype-minify-whitespace@6.0.2": { + "integrity": "sha512-Zk0pyQ06A3Lyxhe9vGtOtzz3Z0+qZ5+7icZ/PL/2x1SHPbKao5oB/g/rlc6BCTajqBb33JcOe71Ye1oFsuYbnw==", + "dependencies": [ + "@types/hast", + "hast-util-minify-whitespace" + ] + }, "rehype-raw@7.0.0": { "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", "dependencies": [ @@ -2343,6 +2459,14 @@ "unified" ] }, + "remark-definition-list@2.0.0": { + "integrity": "sha512-OOJ0zUrfUGITUNxOBnsipyFUjqq1m4AgYOqQk10jDXyz+RoODJL3qYvRn8qzYQDzRnz1wlCP3dbDEOpl05LlQw==", + "dependencies": [ + "hast-util-definition-list", + "mdast-util-definition-list", + "micromark-extension-definition-list" + ] + }, "remark-gfm@4.0.1": { "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", "dependencies": [ @@ -2664,9 +2788,15 @@ "trim-lines@3.0.1": { "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==" }, + "trim-trailing-lines@2.1.0": { + "integrity": "sha512-5UR5Biq4VlVOtzqkm2AZlgvSlDJtME46uV0br0gENbwN4l5+mMKT4b9gJKqWtuL2zAIqajGJGuvbCbcAJUZqBg==" + }, "trough@2.2.0": { "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==" }, + "ts-dedent@2.2.0": { + "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==" + }, "tslib@2.6.2": { "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, @@ -2694,6 +2824,19 @@ "vfile" ] }, + "unist-builder@4.0.0": { + "integrity": "sha512-wmRFnH+BLpZnTKpc5L7O67Kac89s9HMrtELpnNaE6TAobq5DTZZs5YaTQfAZBA9bFPECx2uVAPO31c+GVug8mg==", + "dependencies": [ + "@types/unist" + ] + }, + "unist-util-find-after@5.0.0": { + "integrity": "sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==", + "dependencies": [ + "@types/unist", + "unist-util-is" + ] + }, "unist-util-is@6.0.0": { "integrity": "sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==", "dependencies": [ diff --git a/sample.md b/sample.md index 629b1db..3f9824e 100644 --- a/sample.md +++ b/sample.md @@ -6,9 +6,19 @@ useNewStyle: true Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. -## h2 +## h2 -- 2nd level heading -### h3 +First term +: This is an important term that requires defining. + +Second term +: This is an even more important term that requires defining + over + multiple + lines. + ...and also some $m \cdot \text{ath}$. + +### h3 -- 3rd level heading #### h4 diff --git a/szmgr/index.md b/szmgr/index.md index fc20c4d..b35cbdb 100644 --- a/szmgr/index.md +++ b/szmgr/index.md @@ -1,88 +1,124 @@ --- -title: Magisterské státnice 2024 +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** +> [!TIP] +> Odpovědi na některé podotázky jsou jen ve starších materiálech. + +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** +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** +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** + +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** + +PA010 Intermediate Computer Graphics +: - [Podzim 2020](https://is.muni.cz/auth/el/fi/podzim2020/PA010/) -- **PA213 Advanced Computer Graphics** + +PA213 Advanced Computer Graphics +: - [Jaro 2022](https://is.muni.cz/auth/el/fi/jaro2022/PA213/) -- **VV035 3D Modeling** + +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** + +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** + +PV227 GPU Rendering +: - [Podzim 2022](https://is.muni.cz/auth/el/fi/podzim2022/PV227/) -- **PA217 AI for Games** + +PA217 AI for Games +: - [Jaro 2021](https://is.muni.cz/auth/el/fi/jaro2021/PA217/) -- **PV021 Neural Networks** + +PV021 Neural Networks +: - [Podzim 2022](https://is.muni.cz/auth/el/fi/podzim2022/PV021/) -- **IB000 Matematické základy informatiky** + +IB000 Matematické základy informatiky +: - [Podzim 2022](https://is.muni.cz/auth/el/fi/podzim2022/IB000/) -- **IB002 Algoritmy a datové struktury I** + +IB002 Algoritmy a datové struktury I +: - [Jaro 2020](https://is.muni.cz/auth/el/fi/jaro2020/IB002/) -- **MA018 Numerical Methods** + +MA018 Numerical Methods +: - [Podzim 2019](https://is.muni.cz/auth/el/fi/podzim2019/MA018/) -- **PB130 Úvod do digitálního zpracování obrazu** + +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** + +PV131 Digitální zpracování obrazu +: - [Jaro 2023](https://is.muni.cz/auth/el/fi/jaro2023/PV131/) -- **Státnicové poznámky ostatních** + +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) + - [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** + - [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/) + +Meta +: - [Guidelines pro psaní poznámek](./guidelines/) --- From 8e619961608075b108eb72dda1cf9dcd32a923c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20=C5=A0t=C4=9Bp=C3=A1nek?= Date: Wed, 23 Jul 2025 00:30:41 +0200 Subject: [PATCH 33/44] Add smartypants --- _config.ts | 42 +++++++++++++++++---------- deno.lock | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ sample.md | 8 ++++-- 3 files changed, 116 insertions(+), 17 deletions(-) diff --git a/_config.ts b/_config.ts index 309433f..c76699b 100644 --- a/_config.ts +++ b/_config.ts @@ -3,6 +3,7 @@ import markdown from "lume/plugins/markdown.ts"; import remark from "lume/plugins/remark.ts"; import remarkAlert from "./_plugins/remark-alerts.ts"; import { remarkDefinitionList, defListHastHandlers } from "npm:remark-definition-list"; +import smartypants from "npm:remark-smartypants"; import jsx from "lume/plugins/jsx.ts"; import sass from "lume/plugins/sass.ts"; import postcss from "lume/plugins/postcss.ts"; @@ -50,22 +51,33 @@ site.ignore("readme.md", "contributing.md", "public", "deps.ts", "_plugins"); // })); site.use(remark({ remarkPlugins: [ - [remarkAlert, { - classPrefix: "alert", - icons: { - "TIP": "", - "NOTE": "", - "WARNING": "" - }, - titles: { - "TIP": "Tip", - "NOTE": "Poznámka", - "WARNING": "Varování", - "IMPORTANT": "Důležitost", - "CAUTION": "Bacha!" + [ + remarkAlert, + { + classPrefix: "alert", + icons: { + "TIP": "", + "NOTE": "", + "WARNING": "" + }, + titles: { + "TIP": "Tip", + "NOTE": "Poznámka", + "WARNING": "Varování", + "IMPORTANT": "Důležitost", + "CAUTION": "Bacha!" + } } - }], - [remarkDefinitionList] + ], + [remarkDefinitionList], + [ + smartypants, + { + dashes: "oldschool", + openingQuotes: "„", + closingQuotes: "“" + } + ] ], rehypeOptions: { handlers: { diff --git a/deno.lock b/deno.lock index 73e7a6a..570ebe9 100644 --- a/deno.lock +++ b/deno.lock @@ -59,6 +59,7 @@ "npm:@asciidoctor/core@3": "3.0.2", "npm:@js-temporal/polyfill@0.4.4": "0.4.4", "npm:@types/estree@1.0.6": "1.0.6", + "npm:@types/mdast@*": "4.0.4", "npm:@types/node@*": "18.16.19", "npm:@types/react@18.2.47": "18.2.47", "npm:asciidoctor-kroki@*": "0.18.1_@asciidoctor+core@3.0.2", @@ -109,6 +110,7 @@ "npm:remark-github-blockquote-alert@*": "1.3.1", "npm:remark-parse@11.0.0": "11.0.0", "npm:remark-rehype@11.1.2": "11.1.2", + "npm:remark-smartypants@*": "3.0.2", "npm:remark@*": "15.0.1", "npm:remove-markdown@0.6.2": "0.6.2", "npm:sass@1.69.6": "1.69.6", @@ -1050,6 +1052,12 @@ "@types/ms@2.1.0": { "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==" }, + "@types/nlcst@2.0.3": { + "integrity": "sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==", + "dependencies": [ + "@types/unist" + ] + }, "@types/node@18.16.19": { "integrity": "sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA==" }, @@ -1086,6 +1094,9 @@ "argparse@2.0.1": { "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, + "array-iterate@2.0.1": { + "integrity": "sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==" + }, "asciidoctor-kroki@0.18.1_@asciidoctor+core@3.0.2": { "integrity": "sha512-eQxbBCaPTbyNoJtk62Gp+6h4LlJp2147g7eS0QIVjqaLpFa8sseH0BlMiBoATrJUYv1w3nR+FTzvloBJ/MioYg==", "dependencies": [ @@ -2221,6 +2232,12 @@ "napi-wasm@1.1.3": { "integrity": "sha512-h/4nMGsHjZDCYmQVNODIrYACVJ+I9KItbG+0si6W/jSjdA9JbWDoU4LLeMXVcEQGHjttI2tuXqDrbGF7qkUHHg==" }, + "nlcst-to-string@4.0.0": { + "integrity": "sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==", + "dependencies": [ + "@types/nlcst" + ] + }, "node-addon-api@7.1.1": { "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==" }, @@ -2278,6 +2295,17 @@ "pako@2.1.0": { "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==" }, + "parse-latin@7.0.0": { + "integrity": "sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==", + "dependencies": [ + "@types/nlcst", + "@types/unist", + "nlcst-to-string", + "unist-util-modify-children", + "unist-util-visit-children", + "vfile" + ] + }, "parse5@7.3.0": { "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", "dependencies": [ @@ -2511,6 +2539,15 @@ "vfile" ] }, + "remark-smartypants@3.0.2": { + "integrity": "sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==", + "dependencies": [ + "retext", + "retext-smartypants", + "unified", + "unist-util-visit" + ] + }, "remark-stringify@11.0.0": { "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", "dependencies": [ @@ -2540,6 +2577,39 @@ ], "bin": true }, + "retext-latin@4.0.0": { + "integrity": "sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==", + "dependencies": [ + "@types/nlcst", + "parse-latin", + "unified" + ] + }, + "retext-smartypants@6.2.0": { + "integrity": "sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==", + "dependencies": [ + "@types/nlcst", + "nlcst-to-string", + "unist-util-visit" + ] + }, + "retext-stringify@4.0.0": { + "integrity": "sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==", + "dependencies": [ + "@types/nlcst", + "nlcst-to-string", + "unified" + ] + }, + "retext@9.0.0": { + "integrity": "sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==", + "dependencies": [ + "@types/nlcst", + "retext-latin", + "retext-stringify", + "unified" + ] + }, "rusha@0.8.14": { "integrity": "sha512-cLgakCUf6PedEu15t8kbsjnwIFFR2D4RfL+W3iWFJ4iac7z4B0ZI8fxy4R3J956kAI68HclCFGL8MPoUVC3qVA==" }, @@ -2843,6 +2913,13 @@ "@types/unist" ] }, + "unist-util-modify-children@4.0.0": { + "integrity": "sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==", + "dependencies": [ + "@types/unist", + "array-iterate" + ] + }, "unist-util-position@5.0.0": { "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", "dependencies": [ @@ -2855,6 +2932,12 @@ "@types/unist" ] }, + "unist-util-visit-children@3.0.0": { + "integrity": "sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==", + "dependencies": [ + "@types/unist" + ] + }, "unist-util-visit-parents@6.0.1": { "integrity": "sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==", "dependencies": [ diff --git a/sample.md b/sample.md index 3f9824e..0c1365e 100644 --- a/sample.md +++ b/sample.md @@ -6,7 +6,7 @@ useNewStyle: true Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. -## h2 -- 2nd level heading +## h2 --- 2nd level heading First term : This is an important term that requires defining. @@ -17,8 +17,12 @@ Second term multiple lines. ...and also some $m \cdot \text{ath}$. + +Third term +: - With a couple of + - Bullet points -### h3 -- 3rd level heading +### h3 --- 3rd level heading #### h4 From a8fc8ceb681c54833247b077be3080aa2b52e490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20=C5=A0t=C4=9Bp=C3=A1nek?= Date: Wed, 23 Jul 2025 00:37:23 +0200 Subject: [PATCH 34/44] Reconfigure katex --- _config.ts | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/_config.ts b/_config.ts index c76699b..ea5ab32 100644 --- a/_config.ts +++ b/_config.ts @@ -142,7 +142,18 @@ site.use(katex({ fleqn: true, throwOnError: false, output: "html", - strict: false + strict: false, + delimiters: [ + { left: "$", right: "$", display: false }, + { left: "$$", right: "$$", display: true }, + { left: "\\(", right: "\\)", display: false }, + { left: "\\begin{equation}", right: "\\end{equation}", display: true }, + { left: "\\begin{align}", right: "\\end{align}", display: true }, + { left: "\\begin{alignat}", right: "\\end{alignat}", display: true }, + { left: "\\begin{gather}", right: "\\end{gather}", display: true }, + { left: "\\begin{CD}", right: "\\end{CD}", display: true }, + { left: "\\[", right: "\\]", display: true } + ] } })); // .use(await codeHighlight()) From f91db1023b2fc6709ab12e561118bde5da84e1f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20=C5=A0t=C4=9Bp=C3=A1nek?= Date: Wed, 23 Jul 2025 00:49:30 +0200 Subject: [PATCH 35/44] Reimplement heading anchors --- _config.ts | 24 ++++++++++++++++++-- deno.lock | 64 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 86 insertions(+), 2 deletions(-) diff --git a/_config.ts b/_config.ts index ea5ab32..decc3ba 100644 --- a/_config.ts +++ b/_config.ts @@ -3,7 +3,9 @@ import markdown from "lume/plugins/markdown.ts"; import remark from "lume/plugins/remark.ts"; import remarkAlert from "./_plugins/remark-alerts.ts"; import { remarkDefinitionList, defListHastHandlers } from "npm:remark-definition-list"; -import smartypants from "npm:remark-smartypants"; +import remarkSmartypants from "npm:remark-smartypants"; +import rehypeSlug from "npm:rehype-slug"; +import rehypeAutolinkHeadings from "npm:rehype-autolink-headings"; import jsx from "lume/plugins/jsx.ts"; import sass from "lume/plugins/sass.ts"; import postcss from "lume/plugins/postcss.ts"; @@ -19,6 +21,7 @@ import pagefind from "lume/plugins/pagefind.ts"; import { linkInsideHeader } from "lume_markdown_plugins/toc/anchors.ts"; import toc from "lume_markdown_plugins/toc.ts"; import esbuild from "lume/plugins/esbuild.ts"; +import { ElementContent } from "npm:@types/hast"; import { AsciidoctorEngine, asciidocLoader } from "./_plugins/asciidoc.ts"; import { default as markdownItAlerts } from "npm:markdown-it-github-alerts"; @@ -71,7 +74,7 @@ site.use(remark({ ], [remarkDefinitionList], [ - smartypants, + remarkSmartypants, { dashes: "oldschool", openingQuotes: "„", @@ -79,6 +82,22 @@ site.use(remark({ } ] ], + rehypePlugins: [ + [rehypeSlug], + [ + rehypeAutolinkHeadings, + { + content: { + type: "text", + value: "#" + }, + properties: { + tabIndex: -1, + class: "header-anchor" + } + } + ] + ], rehypeOptions: { handlers: { ...defListHastHandlers @@ -166,6 +185,7 @@ site.add("styles"); site.add([".md", ".ad"]); site.add([".png", ".jpg", ".jpeg", ".gif", ".svg"]) site.use(finder()); +site.ignore("szmgr"); site.use(pagefind({ indexing: { rootSelector: "main" diff --git a/deno.lock b/deno.lock index 570ebe9..9a92831 100644 --- a/deno.lock +++ b/deno.lock @@ -59,6 +59,7 @@ "npm:@asciidoctor/core@3": "3.0.2", "npm:@js-temporal/polyfill@0.4.4": "0.4.4", "npm:@types/estree@1.0.6": "1.0.6", + "npm:@types/hast@*": "3.0.4", "npm:@types/mdast@*": "4.0.4", "npm:@types/node@*": "18.16.19", "npm:@types/react@18.2.47": "18.2.47", @@ -67,6 +68,10 @@ "npm:autoprefixer@10.4.20": "10.4.20_postcss@8.4.32", "npm:autoprefixer@10.4.21": "10.4.21_postcss@8.4.32", "npm:estree-walker@3.0.3": "3.0.3", + "npm:h@*": "1.0.0", + "npm:ha@*": "0.0.17", + "npm:has@*": "1.0.4", + "npm:hast@*": "1.0.0", "npm:html-react-parser@*": "5.1.1_react@18.2.0", "npm:ico-endec@0.1.6": "0.1.6", "npm:katex@0.16.15": "0.16.15", @@ -101,8 +106,10 @@ "npm:react-dom@18.2.0": "18.2.0_react@18.2.0", "npm:react@*": "18.2.0", "npm:react@18.2.0": "18.2.0", + "npm:rehype-autolink-headings@*": "7.1.0", "npm:rehype-raw@7.0.0": "7.0.0", "npm:rehype-sanitize@6.0.0": "6.0.0", + "npm:rehype-slug@*": "6.0.0", "npm:rehype-stringify@10.0.1": "10.0.1", "npm:remark-definition-list@*": "2.0.0", "npm:remark-gfm@4.0.1": "4.0.1", @@ -1400,6 +1407,9 @@ "function-bind@1.1.2": { "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" }, + "github-slugger@2.0.0": { + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==" + }, "glob-parent@5.1.2": { "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dependencies": [ @@ -1417,6 +1427,19 @@ ], "deprecated": true }, + "h@1.0.0": { + "integrity": "sha512-nxC1orTrM/gMBsMyWnFqLe2kzqD/iVIVoBIdpOtQc9hyKzWWPuuCiXGwi0o3TwC+3SyhIR5d73WGg6KlcokWzw==", + "dependencies": [ + "cssesc", + "html-escape" + ] + }, + "ha@0.0.17": { + "integrity": "sha512-AH+nKNS1xGIZwVE4kuPpmOeh7zXZYQMm6jixPAQN9qiEVrWvb5CddmZvY8jQghIt3MwGn3ueUp3jOwxj6Sq2Qg==" + }, + "has@1.0.4": { + "integrity": "sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ==" + }, "hasown@2.0.0": { "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", "dependencies": [ @@ -1460,6 +1483,12 @@ "@types/hast" ] }, + "hast-util-heading-rank@3.0.0": { + "integrity": "sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==", + "dependencies": [ + "@types/hast" + ] + }, "hast-util-is-body-ok-link@3.0.1": { "integrity": "sha512-0qpnzOBLztXHbHQenVB8uNuxTnm/QBFUOmdOSsEn7GnBtyY07+ENTWVFBAnXd/zEgd9/SUG3lRY7hSIBWRgGpQ==", "dependencies": [ @@ -1571,6 +1600,12 @@ "zwitch" ] }, + "hast-util-to-string@3.0.1": { + "integrity": "sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==", + "dependencies": [ + "@types/hast" + ] + }, "hast-util-to-text@4.0.2": { "integrity": "sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==", "dependencies": [ @@ -1586,6 +1621,10 @@ "@types/hast" ] }, + "hast@1.0.0": { + "integrity": "sha512-vFUqlRV5C+xqP76Wwq2SrM0kipnmpxJm7OfvVXpB35Fp+Fn4MV+ozr+JZr5qFvyR1q/U+Foim2x+3P+x9S1PLA==", + "deprecated": true + }, "hastscript@9.0.1": { "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", "dependencies": [ @@ -1603,6 +1642,9 @@ "htmlparser2" ] }, + "html-escape@2.0.0": { + "integrity": "sha512-BYh0wceM2Vm4/Q8TNfnKaHXs4DCv2DuYVS87DR40elSvFc+8a6B9mE9ej+8nCOkdqPx7puEx9+hm+GoJ3f9PzA==" + }, "html-react-parser@5.1.1_react@18.2.0": { "integrity": "sha512-L5VK0rKN3VM7uzRH+4wxAL9elvHuCNDjyWKKjcCDR+YWW5Qr7WWSK7+e627DcePVAFi5IMqc+rAU8j/1DpC/Tw==", "dependencies": [ @@ -2457,6 +2499,17 @@ "readdirp@4.0.2": { "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==" }, + "rehype-autolink-headings@7.1.0": { + "integrity": "sha512-rItO/pSdvnvsP4QRB1pmPiNHUskikqtPojZKJPPPAVx9Hj8i8TwMBhofrrAYRhYOOBZH9tgmG5lPqDLuIWPWmw==", + "dependencies": [ + "@types/hast", + "@ungap/structured-clone", + "hast-util-heading-rank", + "hast-util-is-element", + "unified", + "unist-util-visit" + ] + }, "rehype-minify-whitespace@6.0.2": { "integrity": "sha512-Zk0pyQ06A3Lyxhe9vGtOtzz3Z0+qZ5+7icZ/PL/2x1SHPbKao5oB/g/rlc6BCTajqBb33JcOe71Ye1oFsuYbnw==", "dependencies": [ @@ -2479,6 +2532,16 @@ "hast-util-sanitize" ] }, + "rehype-slug@6.0.0": { + "integrity": "sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==", + "dependencies": [ + "@types/hast", + "github-slugger", + "hast-util-heading-rank", + "hast-util-to-string", + "unist-util-visit" + ] + }, "rehype-stringify@10.0.1": { "integrity": "sha512-k9ecfXHmIPuFVI61B9DeLPN0qFHfawM6RsuX48hoqlaKSF61RskNjSm1lI8PhBEM0MRdLxVVm4WmTqJQccH9mA==", "dependencies": [ @@ -4327,6 +4390,7 @@ "https://deno.land/x/xml@2.1.3/utils/streamable.ts": "1603a5f10c859b95d4e9502365a0fba0b19d5d068356e20d5a6813cd37fee780", "https://deno.land/x/xml@2.1.3/utils/stringifier.ts": "c701b506835237c0c6c0a08fd94e0a012b644def3f4c819c64788daf2e649ea3", "https://deno.land/x/xml@2.1.3/utils/types.ts": "ecaf7785e54a6f1da6f8e56da2bce9853407ceb7d5b3b70f0a60a0890151fe4c", + "https://deno.land/x/xml@7.0.0/_types.ts": "203f97a91686f1aa9423ef07abe646da7caa07a2cf13b27897ffc4f43fdeae8f", "https://deno.land/x/xml@7.0.0/mod.ts": "ca2bb5a9a90d236a2b6242c8643717e0c53f645092d2407792dad728e1367f9a", "https://deno.land/x/xml@7.0.0/parse.ts": "8ae0d8339f589c29ab203dd7887e06325e2064efedfe9c61e2cd6d907443b664", "https://deno.land/x/xml@7.0.0/stringify.ts": "f604d3d88b8bdaff11dbc9d57a6e98fd9b353e3bfbafcaa3f421e6b470ea0e02", From 32ee0f2678710984b28d010f91565c2017d86ab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20=C5=A0t=C4=9Bp=C3=A1nek?= Date: Wed, 23 Jul 2025 17:42:55 +0200 Subject: [PATCH 36/44] Add a workaround for Katex exceptions and disable Smartypants --- .vscode/launch.json | 2 +- _config.ts | 17 ++--- _plugins/katex.ts | 2 +- _plugins/katex.vanilla.ts | 155 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 165 insertions(+), 11 deletions(-) create mode 100644 _plugins/katex.vanilla.ts diff --git a/.vscode/launch.json b/.vscode/launch.json index be16dc5..89a142c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -6,7 +6,7 @@ "configurations": [ { "request": "launch", - "name": "Launch Program", + "name": "Debug", "type": "node", "cwd": "${workspaceFolder}", "runtimeExecutable": "C:\\Users\\Adam\\scoop\\shims\\deno.EXE", diff --git a/_config.ts b/_config.ts index decc3ba..c0dfdef 100644 --- a/_config.ts +++ b/_config.ts @@ -73,14 +73,14 @@ site.use(remark({ } ], [remarkDefinitionList], - [ - remarkSmartypants, - { - dashes: "oldschool", - openingQuotes: "„", - closingQuotes: "“" - } - ] + // [ + // remarkSmartypants, + // { + // dashes: "oldschool", + // openingQuotes: "„", + // closingQuotes: "“" + // } + // ] ], rehypePlugins: [ [rehypeSlug], @@ -185,7 +185,6 @@ site.add("styles"); site.add([".md", ".ad"]); site.add([".png", ".jpg", ".jpeg", ".gif", ".svg"]) site.use(finder()); -site.ignore("szmgr"); site.use(pagefind({ indexing: { rootSelector: "main" diff --git a/_plugins/katex.ts b/_plugins/katex.ts index 2e50aec..74e48f6 100644 --- a/_plugins/katex.ts +++ b/_plugins/katex.ts @@ -1,5 +1,5 @@ import Site from "lume/core/site.ts"; -import katex from "lume/plugins/katex.ts"; +import katex from "./katex.vanilla.ts"; import { Options } from "lume/plugins/katex.ts"; const BASE = "https://cdn.jsdelivr.net/npm/katex@0.16.9/dist/"; diff --git a/_plugins/katex.vanilla.ts b/_plugins/katex.vanilla.ts new file mode 100644 index 0000000..48d0613 --- /dev/null +++ b/_plugins/katex.vanilla.ts @@ -0,0 +1,155 @@ +import { assetsUrl, katex as Katex, KatexOptions } from "lume/deps/katex.ts"; +import { renderMathInElement } from "lume/deps/katex-auto-render/auto-render.ts"; +import { merge } from "lume/core/utils/object.ts"; +import { posix } from "lume/deps/path.ts"; +import { read, readFile } from "lume/core/utils/read.ts"; +import { walkUrls } from "lume/core/utils/css_urls.ts"; +import { insertContent } from "lume/core/utils/page_content.ts"; +import { log } from "lume/core/utils/log.ts"; + +import type Site from "lume/core/site.ts"; + +export interface Options { + /** The css selector to apply katex */ + cssSelector?: string; + + /** The CSS file to output the CSS styles */ + cssFile?: string; + + /** The folder to save the fonts */ + fontsFolder?: string; + + /** A placeholder to replace with the generated CSS */ + placeholder?: string; + + /** + * Documentation for katex options: + * @see https://katex.org/docs/options.html + * + * Documentation for auto-render options: + * @see https://katex.org/docs/autorender.html + */ + options?: KatexOptions; +} + +export const defaults: Options = { + cssSelector: ".language-math", + options: { + strict: true, + displayMode: true, + throwOnError: true, + delimiters: [ + { left: "$$", right: "$$", display: true }, + { left: "\\(", right: "\\)", display: false }, + { left: "\\begin{equation}", right: "\\end{equation}", display: true }, + { left: "\\begin{align}", right: "\\end{align}", display: true }, + { left: "\\begin{alignat}", right: "\\end{alignat}", display: true }, + { left: "\\begin{gather}", right: "\\end{gather}", display: true }, + { left: "\\begin{CD}", right: "\\end{CD}", display: true }, + { left: "\\[", right: "\\]", display: true }, + ], + ignoredTags: [ + "script", + "noscript", + "style", + "textarea", + "pre", + "code", + "option", + ], + ignoredClasses: [], + macros: {}, + }, +}; + +/** + * A plugin to render math equations using katex + * @see https://lume.land/plugins/katex/ + */ +export function katex(userOptions?: Options) { + const options = merge(defaults, userOptions); + + return (site: Site) => { + let cssCode = ""; + const cssFile = posix.join("/", options.cssFile || site.options.cssFile); + const fontsFolder = posix.join( + "/", + options.fontsFolder || site.options.fontsFolder, + ); + + const relativePath = posix.relative( + posix.dirname(cssFile), + posix.join(fontsFolder), + ); + + // Download the fonts and generate the CSS + site.addEventListener("beforeBuild", async () => { + const css = await readFile(`${assetsUrl}/katex.css`); + const fonts = new Map(); + + // Fix the urls in the CSS file + cssCode = await walkUrls(css, (url) => { + const file = posix.basename(url); + fonts.set(`${assetsUrl}/${url}`, posix.join("/", fontsFolder, file)); + return posix.join(relativePath, file); + }); + + // Download the fonts + await Promise.all( + Array.from(fonts).map(async ([src, url]) => { + const content = await read(src, true); + site.page({ content, url }); + }), + ); + }); + + // Output the CSS file + site.process(async function processKatexCss() { + const page = await site.getOrCreatePage(cssFile); + page.text = insertContent(page.text, cssCode, options.placeholder); + }); + + // Process the html pages and output the CSS file + site.process([".html"], function processKatex(pages) { + for (const page of pages) { + const { document } = page; + + document.querySelectorAll(options.cssSelector) + .forEach((element) => { + try { + const rendered = Katex.renderToString( + element.textContent || "", + options.options, + ); + const div = document.createElement("div"); + div.innerHTML = rendered.trim(); + + // we've selected the element, we want to also replace the parent
+              const parent = element.parentElement;
+              if (parent && parent.tagName === "PRE") {
+                parent.replaceWith(div.firstChild!);
+              } else {
+                element.replaceWith(div.firstChild!);
+              }
+            } catch (cause) {
+              log.error(
+                `[katex plugin] Failed to render math in ${page.outputPath}: ${cause}`,
+              );
+            }
+          });
+
+        if (options.options.delimiters) {
+          try {
+            renderMathInElement(document.body, options.options);
+          } catch (cause) {
+            log.error(
+              `[katex plugin] Failed to render math in ${page.outputPath}: ${cause}`,
+            );
+          }
+        }
+      }
+    });
+  };
+}
+
+export default katex;

From 81a06cbea5a77dccaa4d61ac2ed483644a6562da Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Adam=20=C5=A0t=C4=9Bp=C3=A1nek?= 
Date: Fri, 1 Aug 2025 23:43:40 +0200
Subject: [PATCH 37/44] Work on a new navigation bar

---
 .vscode/launch.json                           |   5 +-
 _includes/layouts/default.tsx                 | 152 ++++++++++++------
 deno.json                                     |   4 +
 ...ro.md => PGV00_zpracovani_obrazu_intro.md} |   2 +-
 szmgr/_data.ts                                |  19 +++
 szmgr/_data.yml                               |  57 ++-----
 6 files changed, 141 insertions(+), 98 deletions(-)
 rename szmgr/{PGV_zpracovani_obrazu_intro.md => PGV00_zpracovani_obrazu_intro.md} (94%)
 create mode 100644 szmgr/_data.ts

diff --git a/.vscode/launch.json b/.vscode/launch.json
index 89a142c..683f04f 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -1,7 +1,4 @@
 {
-    // Use IntelliSense to learn about possible attributes.
-    // Hover to view descriptions of existing attributes.
-    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
     "version": "0.2.0",
     "configurations": [
         {
@@ -9,7 +6,7 @@
             "name": "Debug",
             "type": "node",
             "cwd": "${workspaceFolder}",
-            "runtimeExecutable": "C:\\Users\\Adam\\scoop\\shims\\deno.EXE",
+            "runtimeExecutable": "deno",
             "runtimeArgs": [
                 "task",
                 "debug"
diff --git a/_includes/layouts/default.tsx b/_includes/layouts/default.tsx
index 406c0d3..63fbd4b 100644
--- a/_includes/layouts/default.tsx
+++ b/_includes/layouts/default.tsx
@@ -1,54 +1,114 @@
 import { Node as TocNode } from "lume_markdown_plugins/toc/mod.ts";
 import { Finder } from "../../_plugins/finder.ts";
 import { NavItem } from "../../_components/NavLevel.tsx";
+import * as path from "@std/path";
 
 export const layout = "layouts/base.tsx";
 
-interface NotePageData extends Lume.Data {
-  course?: string;
-  priority?: number;
-  toc?: TocNode[];
-  showtitle?: boolean;
-  nav?: NavItem[];
-  finder: Finder;
+export interface NotePageData extends Lume.Data {
+    course?: string;
+    discriminator?: string;
+    priority?: number;
+    toc?: TocNode[];
+    showtitle?: boolean;
+    nav?: NavItem[];
+    groups?: NotePageGroup[];
+    finder: Finder;
 }
 
-export default ({ children, search, course, showtitle, title, comp, nav, finder }: NotePageData) => (
-  <>
-    
-    
-
- {(showtitle === true || showtitle === undefined) &&

{title}

} - {children} -
-
- -); +export interface NotePageGroup { + name: string; + display: string; +} + +export default function ( + { + children, + search, + course, + showtitle, + title, + comp, + nav, + finder, + discriminator, + groups, + }: NotePageData, +) { + let groupNav: NavItem[] = []; + if (discriminator) { + const pageGroups = Object.groupBy( + search.pages(discriminator) + .map((p) => { + const captures = path.basename(p.page.sourcePath).match( + /^(([A-Z]+)\d+)_/, + ); + return { + group: captures?.[2] ?? null, + order: captures?.[1] ?? "", + page: p, + }; + }) + .filter((gp) => gp.group != null), + (p) => p.group!, + ); + + groupNav = Object.entries(pageGroups).map(([group, children]) => { + return { + title: groups?.filter((g) => g.name == group)?.at(0)?.display ?? + "Unnamed page group", + children: children + ?.sort((a, b) => a.order!.localeCompare(b.order!)) + ?.map((p) => { + return { + title: `${p.order}. ${p.page.title}`, + href: p.page.url, + }; + }), + }; + }); + } + + return ( + <> + +
+
+ {(showtitle === true || showtitle === undefined) &&

{title}

} + {children} +
+
+ + ); +} diff --git a/deno.json b/deno.json index bd95298..13f34c3 100644 --- a/deno.json +++ b/deno.json @@ -26,5 +26,9 @@ "plugins": [ "https://deno.land/x/lume@v3.0.5/lint.ts" ] + }, + "fmt": { + "lineWidth": 120, + "indentWidth": 4 } } diff --git a/szmgr/PGV_zpracovani_obrazu_intro.md b/szmgr/PGV00_zpracovani_obrazu_intro.md similarity index 94% rename from szmgr/PGV_zpracovani_obrazu_intro.md rename to szmgr/PGV00_zpracovani_obrazu_intro.md index b3d9a68..925523e 100644 --- a/szmgr/PGV_zpracovani_obrazu_intro.md +++ b/szmgr/PGV00_zpracovani_obrazu_intro.md @@ -1,6 +1,6 @@ --- title: Zpracování obrazu - intro -description: "TODO" +description: Úvod do státnicových otázek specializace Zpracování obrazu (PGV). --- > [!TIP] diff --git a/szmgr/_data.ts b/szmgr/_data.ts new file mode 100644 index 0000000..6bc2f6c --- /dev/null +++ b/szmgr/_data.ts @@ -0,0 +1,19 @@ +import { NotePageData } from "../_includes/layouts/default.tsx"; + +export function url(page: Lume.Page) { + let slug = page.data.basename ?? ""; + const groups = page.data.groups?.map(g => g.name) ?? []; + for (const group of groups) { + const groupRegex = new RegExp(`^(${group})\\d*[-_]`); + if (slug.match(groupRegex)) { + slug = slug.replace(groupRegex, ""); + break; + } + } + slug = slug.replaceAll("_", "-"); + if (slug === "index") { + return "./"; + } + + return `./${slug}/`; +} diff --git a/szmgr/_data.yml b/szmgr/_data.yml index ebcae98..eabe4fe 100644 --- a/szmgr/_data.yml +++ b/szmgr/_data.yml @@ -1,57 +1,20 @@ -layout: layouts/question.tsx -styles: ["question"] -mergedKeys: - styles: noop - -# layout: layouts/default.tsx -# useNewStyle: true - +layout: layouts/default.tsx +useNewStyle: true tags: [szmgr] course: SZMGR home: /szmgr/ +discriminator: szmgr + groups: - - name: szp + - name: SZP display: Společný základ programu - - name: vph + - name: VPH display: Vývoj počítačových her - - name: pgv + - name: PGV display: Počítačová grafika a vizualizace - # - name: gd - # display: Grafický design + - name: GD + display: Grafický design + nav: - title: Zpět na seznam předmětů href: / - - title: Společný základ programu - children: - - href: SZP01_algoritmy.ad - - href: SZP02_numericke_metody.ad - - href: SZP03_statistika.ad - - href: SZP04_3d_modelovani.ad - - href: SZP05_krivky_a_povrchy.ad - - href: SZP06_strojove_uceni.ad - - href: SZP07_grafy.ad - - href: SZP08_modelovani_a_projekce.ad - - href: SZP09_zpracovani_obrazu.ad - - href: SZP10_analyza_obrazu.ad - - title: Vývoj počítačových her - children: - - href: VPH01_pokrocila_grafika.ad - - href: VPH02_graficke_a_fyzikalni_principy.ad - - href: VPH03_herni_design_i.ad - - href: VPH04_herni_design_ii.ad - - href: VPH05_vyvoj_her.ad - - href: VPH06_ai_ve_hrach.ad - - href: VPH07_gpu_rendering.ad - - href: VPH08_modelovani_3d_postav.ad - - title: Počítačová grafika a vizualizace - children: - - href: PGV01_zaklady_vizualizace.ad - - href: PGV02_metody_vizualizace.ad - - href: PGV03_zaklady_pocitatcove_grafiky.ad - - href: PGV04_geometricke_algoritmy.ad - - href: PGV05_deleni_prostoru_a_sceny.ad - - href: PGV06_vykreslovani_objemovych_dat.ad - - href: PGV07_modely_osvetleni.ad - - href: PGV08_real_time_rendering.ad - - href: PGV09_minimalizace_energie.ad - - href: PGV10_zpracovani_obrazu_pomoci_PDE.ad From 3be7c360f34a30bca8830b7882e5bed8daf46c63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20=C5=A0t=C4=9Bp=C3=A1nek?= Date: Sat, 2 Aug 2025 22:57:12 +0200 Subject: [PATCH 38/44] Reintroduce shiki for code highlighting --- _config.ts | 49 +++------ _includes/layouts/default.tsx | 4 +- _plugins/shiki.ts | 100 ++++++++++-------- deno.lock | 192 ++++++++++++++++++++++++++++++++++ sample.md | 6 +- 5 files changed, 267 insertions(+), 84 deletions(-) diff --git a/_config.ts b/_config.ts index c0dfdef..0d91940 100644 --- a/_config.ts +++ b/_config.ts @@ -1,9 +1,8 @@ import lume from "lume/mod.ts"; -import markdown from "lume/plugins/markdown.ts"; import remark from "lume/plugins/remark.ts"; import remarkAlert from "./_plugins/remark-alerts.ts"; import { remarkDefinitionList, defListHastHandlers } from "npm:remark-definition-list"; -import remarkSmartypants from "npm:remark-smartypants"; +import remarkTextr from "npm:remark-textr"; import rehypeSlug from "npm:rehype-slug"; import rehypeAutolinkHeadings from "npm:rehype-autolink-headings"; import jsx from "lume/plugins/jsx.ts"; @@ -14,17 +13,15 @@ import picture from "lume/plugins/picture.ts"; import katex from "./_plugins/katex.ts"; import metas from "lume/plugins/metas.ts"; import resolveUrls from "lume/plugins/resolve_urls.ts"; -import codeHighlight from "./_plugins/shiki.ts"; +import shiki from "./_plugins/shiki.ts"; import sitemap from "lume/plugins/sitemap.ts"; import inline from "lume/plugins/inline.ts"; import pagefind from "lume/plugins/pagefind.ts"; -import { linkInsideHeader } from "lume_markdown_plugins/toc/anchors.ts"; import toc from "lume_markdown_plugins/toc.ts"; import esbuild from "lume/plugins/esbuild.ts"; -import { ElementContent } from "npm:@types/hast"; +import typographicBase from "npm:typographic-base"; import { AsciidoctorEngine, asciidocLoader } from "./_plugins/asciidoc.ts"; -import { default as markdownItAlerts } from "npm:markdown-it-github-alerts"; import finder from "./_plugins/finder.ts"; const site = lume({ @@ -33,25 +30,6 @@ const site = lume({ }); site.ignore("readme.md", "contributing.md", "public", "deps.ts", "_plugins"); -// site.use(markdown({ -// plugins: [[markdownItAlerts, { -// titles: { -// "tip": "", -// "note": "", -// "important": "", -// "warning": "", -// "caution": "" -// }, -// icons: { -// "tip": " ", -// "note": " ", -// "important": " ", -// "warning": " ", -// "caution": " " -// }, -// classPrefix: "alert" -// }]] -// })); site.use(remark({ remarkPlugins: [ [ @@ -73,14 +51,17 @@ site.use(remark({ } ], [remarkDefinitionList], - // [ - // remarkSmartypants, - // { - // dashes: "oldschool", - // openingQuotes: "„", - // closingQuotes: "“" - // } - // ] + [ + remarkTextr, + { + options: { + locale: "cs" + }, + plugins: [ + typographicBase + ] + } + ] ], rehypePlugins: [ [rehypeSlug], @@ -175,7 +156,7 @@ site.use(katex({ ] } })); -// .use(await codeHighlight()) +site.use(shiki()) site.loadPages([".ad"], { loader: asciidocLoader, engine: new AsciidoctorEngine() }) site.copy("fonts"); site.add("icons"); diff --git a/_includes/layouts/default.tsx b/_includes/layouts/default.tsx index 63fbd4b..a72df0f 100644 --- a/_includes/layouts/default.tsx +++ b/_includes/layouts/default.tsx @@ -85,8 +85,8 @@ export default function ( {/* */} diff --git a/_plugins/shiki.ts b/_plugins/shiki.ts index 8f49f13..80ec6e2 100644 --- a/_plugins/shiki.ts +++ b/_plugins/shiki.ts @@ -1,12 +1,18 @@ -import { HighlighterOptions, getHighlighter } from "npm:shiki"; +import { + createHighlighter, + BundledHighlighterOptions, + BundledLanguage, + BundledTheme, + Highlighter +} from "npm:shiki@3.9.1"; import { Node } from "lume/deps/dom.ts"; import Site from "lume/core/site.ts"; -import { Page } from "lume/core/file.ts"; +import { merge } from "lume/core/utils/object.ts"; export interface Options { extensions: string[]; - options: HighlighterOptions; + options: BundledHighlighterOptions; cssSelector: string; languageDetectRe: RegExp; } @@ -17,57 +23,59 @@ export const defaults: Options = { cssSelector: "pre code", languageDetectRe: /\blanguage-([\w-]+)\b/i, options: { - langs: ["csharp", "js", "ts", "html", "css", "json", "xml", "yaml", "markdown", "bash", "powershell", "haskell", "prolog", "java", "matlab", "glsl"], - theme: "dark-plus" + langs: ["csharp", "c#", "js", "ts", "html", "css", "json", "xml", "yaml", "markdown", "bash", "powershell", "haskell", "prolog", "java", "matlab", "glsl", "sql", "python", "cpp", "c++", ], + themes: ["dark-plus"] } }; -/** A plugin to syntax-highlight code using the highlight.js library */ -export default async function (userOptions?: Options) { - const options = { ...defaults, ...userOptions }; - const highlighter = await getHighlighter(options.options); +let promise: Promise | null = null; - return (site: Site) => { - site.process(options.extensions, pages => { - pages.forEach(codeHighlight); - }); - - function codeHighlight(page: Page) { - page.document!.querySelectorAll(options.cssSelector) - .forEach((node) => { - if (node.nodeType != Node.ELEMENT_NODE) { - return; - } +async function highlightCode(options: Options, page: Lume.Page) { + const nodes = page.document!.querySelectorAll(options.cssSelector); + for (const node of nodes) { + if (node.nodeType != Node.ELEMENT_NODE) { + continue; + } - let element = node as unknown as HTMLElement; + let element = node as unknown as HTMLElement; - let lang = "plain"; - element.classList.forEach(c => { - const result = options.languageDetectRe.exec(c); - if (result && result.length > 0) { - lang = result[1]; - } - }); - if (lang === "plain") { - return; - } + let lang = "plain"; + element.classList.forEach(c => { + const result = options.languageDetectRe.exec(c); + if (result && result.length > 0) { + lang = result[1]; + } + }); + if (lang === "plain") { + continue; + } - try { - if (element.parentElement?.tagName === "PRE") { - element = element.parentElement; - } + try { + if (element.parentElement?.tagName === "PRE") { + element = element.parentElement; + } - const highlightedCode = highlighter.codeToHtml(element.innerText, { lang }); - const wrapper = element.ownerDocument.createElement("div"); - wrapper.innerHTML = highlightedCode; - const highlightedElement = wrapper.firstElementChild!; - highlightedElement.classList.add("snippet", `language-${lang}`) - highlightedElement.classList.add(...element.classList); - element.outerHTML = highlightedElement.outerHTML; - } catch (e) { - console.log(`${page.sourcePath}: ${e}`); - } - }); + promise ??= createHighlighter(options.options); + const highlighter = await promise; + const highlightedCode = highlighter.codeToHtml(element.innerText, { lang, theme: "dark-plus" }); + const wrapper = element.ownerDocument.createElement("div"); + wrapper.innerHTML = highlightedCode; + const highlightedElement = wrapper.firstElementChild!; + highlightedElement.classList.add("snippet", `language-${lang}`) + highlightedElement.classList.add(...element.classList); + element.outerHTML = highlightedElement.outerHTML; + } catch (e) { + console.log(`${page.sourcePath}: ${e}`); } + } +} + +export default function shiki(userOptions?: Options): Lume.Plugin { + const options = merge(defaults, userOptions); + + return (site: Site) => { + site.process(options.extensions, async pages => { + await Promise.all(pages.map(p => highlightCode(options, p))); + }); }; } diff --git a/deno.lock b/deno.lock index 9a92831..77482e4 100644 --- a/deno.lock +++ b/deno.lock @@ -118,6 +118,7 @@ "npm:remark-parse@11.0.0": "11.0.0", "npm:remark-rehype@11.1.2": "11.1.2", "npm:remark-smartypants@*": "3.0.2", + "npm:remark-textr@*": "6.1.0", "npm:remark@*": "15.0.1", "npm:remove-markdown@0.6.2": "0.6.2", "npm:sass@1.69.6": "1.69.6", @@ -129,7 +130,16 @@ "npm:sharp@0.33.5": "0.33.5", "npm:sharp@0.34.3": "0.34.3", "npm:shiki@*": "0.14.7", + "npm:shiki@3": "3.9.1", + "npm:shiki@3.9": "3.9.1", + "npm:shiki@3.9.1": "3.9.1", "npm:svg2png-wasm@1.4.1": "1.4.1", + "npm:t@*": "0.5.1", + "npm:tr@*": "1.1.2", + "npm:try@*": "1.0.0-beta.10", + "npm:typographic-base@*": "1.0.4", + "npm:typographic-ellipses@*": "1.0.11", + "npm:typographic-quotes@*": "2.0.1", "npm:unidecode@0.1.8": "0.1.8", "npm:unidecode@1.1.0": "1.1.0", "npm:unified@*": "11.0.5", @@ -1035,6 +1045,52 @@ ], "scripts": true }, + "@shikijs/core@3.9.1": { + "integrity": "sha512-W5Vwen0KJCtR7KFRo+3JLGAqLUPsfW7e+wZ4yaRBGIogwI9ZlnkpRm9ZV8JtfzMxOkIwZwMmmN0hNErLtm3AYg==", + "dependencies": [ + "@shikijs/types", + "@shikijs/vscode-textmate", + "@types/hast", + "hast-util-to-html" + ] + }, + "@shikijs/engine-javascript@3.9.1": { + "integrity": "sha512-4hGenxYpAmtALryKsdli2K58F0s7RBYpj/RSDcAAGfRM6eTEGI5cZnt86mr+d9/4BaZ5sH5s4p3VU5irIdhj9Q==", + "dependencies": [ + "@shikijs/types", + "@shikijs/vscode-textmate", + "oniguruma-to-es" + ] + }, + "@shikijs/engine-oniguruma@3.9.1": { + "integrity": "sha512-WPlL/xqviwS3te4unSGGGfflKsuHLMI6tPdNYvgz/IygcBT6UiwDFSzjBKyebwi5GGSlXsjjdoJLIBnAplmEZw==", + "dependencies": [ + "@shikijs/types", + "@shikijs/vscode-textmate" + ] + }, + "@shikijs/langs@3.9.1": { + "integrity": "sha512-Vyy2Yv9PP3Veh3VSsIvNncOR+O93wFsNYgN2B6cCCJlS7H9SKFYc55edsqernsg8WT/zam1cfB6llJsQWLnVhA==", + "dependencies": [ + "@shikijs/types" + ] + }, + "@shikijs/themes@3.9.1": { + "integrity": "sha512-zAykkGECNICCMXpKeVvq04yqwaSuAIvrf8MjsU5bzskfg4XreU+O0B5wdNCYRixoB9snd3YlZ373WV5E/g5T9A==", + "dependencies": [ + "@shikijs/types" + ] + }, + "@shikijs/types@3.9.1": { + "integrity": "sha512-rqM3T7a0iM1oPKz9iaH/cVgNX9Vz1HERcUcXJ94/fulgVdwqfnhXzGxO4bLrAnh/o5CPLy3IcYedogfV+Ns0Qg==", + "dependencies": [ + "@shikijs/vscode-textmate", + "@types/hast" + ] + }, + "@shikijs/vscode-textmate@10.0.2": { + "integrity": "sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==" + }, "@types/debug@4.1.12": { "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", "dependencies": [ @@ -2301,6 +2357,17 @@ "wrappy" ] }, + "oniguruma-parser@0.12.1": { + "integrity": "sha512-8Unqkvk1RYc6yq2WBYRj4hdnsAxVze8i7iPfQr8e4uSP3tRv0rpZcbGUDvxfQQcdwHt/e9PrMvGCsa8OqG9X3w==" + }, + "oniguruma-to-es@4.3.3": { + "integrity": "sha512-rPiZhzC3wXwE59YQMRDodUwwT9FZ9nNBwQQfsd1wfdtlKEyCdRV0avrTcSZ5xlIvGRVPd/cx6ZN45ECmS39xvg==", + "dependencies": [ + "oniguruma-parser", + "regex", + "regex-recursion" + ] + }, "pagefind@1.0.4": { "integrity": "sha512-oRIizYe+zSI2Jw4zcMU0ebDZm27751hRFiSOBLwc1OIYMrsZKk+3m8p9EVaOmc6zZdtqwwdilNUNxXvBeHcP9w==", "optionalDependencies": [ @@ -2499,6 +2566,21 @@ "readdirp@4.0.2": { "integrity": "sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==" }, + "regex-recursion@6.0.2": { + "integrity": "sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==", + "dependencies": [ + "regex-utilities" + ] + }, + "regex-utilities@2.3.0": { + "integrity": "sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==" + }, + "regex@6.0.1": { + "integrity": "sha512-uorlqlzAKjKQZ5P+kTJr3eeJGSVroLKoHmquUj4zHWuR+hEyNqlXsSKlYYF5F4NI6nl7tWCs0apKJ0lmfsXAPA==", + "dependencies": [ + "regex-utilities" + ] + }, "rehype-autolink-headings@7.1.0": { "integrity": "sha512-rItO/pSdvnvsP4QRB1pmPiNHUskikqtPojZKJPPPAVx9Hj8i8TwMBhofrrAYRhYOOBZH9tgmG5lPqDLuIWPWmw==", "dependencies": [ @@ -2619,6 +2701,14 @@ "unified" ] }, + "remark-textr@6.1.0": { + "integrity": "sha512-3A61/6Dn8x5wS7f9BubnIjwZfttEw9+PWVFtwOvRzKXLmZDV1mgi9MJeaQ9BNzWhojsSRHWLNa2JHKCOOI5DfA==", + "dependencies": [ + "@types/mdast", + "textr", + "unist-util-visit" + ] + }, "remark@15.0.1": { "integrity": "sha512-Eht5w30ruCXgFmxVUSlNWQ9iiimq07URKeFS3hNc8cUWy1llX4KDWfyEDZRycMc+znsN9Ux5/tJ/BFdgdOwA3A==", "dependencies": [ @@ -2871,6 +2961,19 @@ "vscode-textmate" ] }, + "shiki@3.9.1": { + "integrity": "sha512-HogZ8nMnv9VAQMrG+P7BleJFhrKHm3fi6CYyHRbUu61gJ0lpqLr6ecYEui31IYG1Cn9Bad7N2vf332iXHnn0bQ==", + "dependencies": [ + "@shikijs/core", + "@shikijs/engine-javascript", + "@shikijs/engine-oniguruma", + "@shikijs/langs", + "@shikijs/themes", + "@shikijs/types", + "@shikijs/vscode-textmate", + "@types/hast" + ] + }, "simple-swizzle@0.2.2": { "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", "dependencies": [ @@ -2912,12 +3015,21 @@ "integrity": "sha512-ZFy1NtwZVAsslaTQoI+/QqX2sg0vjmgJ/jGAuLZZvYcRlndI54hLPiwLC9JzXlFBerfxN5JiS7kpEUG0mrXS3Q==", "deprecated": true }, + "t@0.5.1": { + "integrity": "sha512-VPWkKwJPOldeqDKesRwOLhKNbVRUbzh8yoFWqwMTXqQ2BpdY7SHJqPbIRb6qfidlFhh2LBNBDJQGjPnqQcwSgg==" + }, + "textr@0.3.0": { + "integrity": "sha512-yQrF3w9ThyNvyJjkpFTwBpsVxRQ4870xHg2fue1xeK1J1EZIx5cV7XPW6Fwi/XNC0du/3t9CNWZvlHUfCxPpPg==" + }, "to-regex-range@5.0.1": { "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", "dependencies": [ "is-number" ] }, + "tr@1.1.2": { + "integrity": "sha512-yFo1C5dvhkvQjU80dzXF23BaWwr2F/lnZCI0Jv68M7xAdEpOJDilETPE57xnJnVgbnpHngxsGj6f1cuC4f0H6A==" + }, "trim-lines@3.0.1": { "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==" }, @@ -2927,12 +3039,92 @@ "trough@2.2.0": { "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==" }, + "try@1.0.0-beta.10": { + "integrity": "sha512-g/I/r0keF5pnxdMO4PJ1K7+c+N1U0Q0xtNDfrI/1UQz6q/85ipgbL4bSnowAy1DSAIfHkDiaARihADoqGM2qeA==" + }, "ts-dedent@2.2.0": { "integrity": "sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ==" }, "tslib@2.6.2": { "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" }, + "typographic-apostrophes-for-possessive-plurals@1.0.5": { + "integrity": "sha512-sBUA/sFTAFFjd/ey9Xtld1cq2fXCZJ0tQHmlDovttMC9D1WJDOt2f49b9DxA0Yk2iK3yoDFm0HQAs/mKO24sDg==" + }, + "typographic-apostrophes@1.1.1": { + "integrity": "sha512-3/05j0vg9osPy4whnihGaudPLwNxuyczO3AYmsVeLUBUq/aKhbSfbjVPx1VzV7Rwpkbl0vf9qOwOLP6CgfRWZg==" + }, + "typographic-arrows@1.0.3": { + "integrity": "sha512-RlmhHjxOSQ9QjWQbdHFPb+B54hVQLxwWvbO+liqy5NN0naLUzqnZumYH3V/RrR9Xf6cpAZvxKdmwYzpozlx2Ug==", + "deprecated": true + }, + "typographic-base@1.0.4": { + "integrity": "sha512-R2ABy+ohOfZAKumZkkTmP11NWqj0AG7nZg3yyvnuzzl+D0GL9Gu8jO2+D/oAD+04z+/z0AesMO/rncBooHUs7g==", + "dependencies": [ + "textr", + "typographic-apostrophes", + "typographic-apostrophes-for-possessive-plurals", + "typographic-arrows", + "typographic-copyright", + "typographic-currency", + "typographic-ellipses", + "typographic-em-dashes", + "typographic-en-dashes", + "typographic-math-symbols", + "typographic-quotes@1.2.2", + "typographic-registered-trademark", + "typographic-single-spaces", + "typographic-trademark" + ] + }, + "typographic-copyright@1.0.1": { + "integrity": "sha512-DSx9fojOVoBhtYw5Zh0r9ShFWgjuMwUH615l21OXDbi3m2Fl/bBT5yMoZjbZzuJ51kiF66CnTTfJP5Zu5zVZMg==" + }, + "typographic-currency-db@1.0.0": { + "integrity": "sha512-jWu0u9P4mmpZ+e62f/GHrSKUpwS4WmNxGsSI3ZrZZYmfJlmtjA+WkIt+RvpmM0H8ZzyyFzOYRifV5UbxoeTcAw==" + }, + "typographic-currency@1.1.2": { + "integrity": "sha512-adlN4VO5DwYSx2kxfj1AMmx+FGHn6ShFS3qip0Q3VwBD7tSENE4XUbs22b9hlK9g4thw8mZsLyXS3ca799gYhQ==", + "dependencies": [ + "typographic-currency-db" + ] + }, + "typographic-ellipses@1.0.11": { + "integrity": "sha512-TN83hcvDfvPFxqyWTe4ascexSj1wxuzafnXrLS7cZZq5ZEeHYQPE4UXP15mZnsNg71ysnOJxdNXWckxqeTVMAQ==" + }, + "typographic-em-dashes@1.0.2": { + "integrity": "sha512-9aCk1Crubx0YCWsj2PJCD7PIIpx6dBdyOogPL5lOQuH2gIyZtSMp7OGt7SCcpn0BxbToIal2t38SnSOhsagU9A==" + }, + "typographic-en-dashes@1.0.1": { + "integrity": "sha512-/Zaf64q0tCJZ4yxAbBVUmogPB1pV2upiQ6v3aU3kvU+HxEC8szXmRFA6wDTUkAP6YVrnDYgHlUaLzUvKcFUSiw==" + }, + "typographic-math-symbols@1.1.5": { + "integrity": "sha512-GBYbJzZbERHZJ9eflsqFQMfZDBJGCkguMXVbWerG1PkyndNFOA6fYR1H+jUh9JSobr7ir/C92QJ+7LrcBsAbVw==" + }, + "typographic-quotes-l10n-db@1.0.0": { + "integrity": "sha512-E9/XSBJWtmax9XkFlLwqbNW5wNFBbLhL2CDYShmQ/Kw87wL9TwKU36j8SON7Ro0K2GF+RjfcYb/SdUN3XqZkvg==" + }, + "typographic-quotes@1.2.2": { + "integrity": "sha512-rdbJx2ho7ovckr+Yd+zccU3UnTyS0U+lwEzBl0FoMMECewQn7ZM0tLMBWPEvOOHPHCiYaP2C0Wx9Lq1F+Ou8yg==", + "dependencies": [ + "typographic-quotes-l10n-db" + ] + }, + "typographic-quotes@2.0.1": { + "integrity": "sha512-ebXALmr22j1ttpwbfBXrBov9uOrQKUTKs29dOz1nF+vLVX228X0ol8dD+549yIJG7gjC0Pj/tUahdb0xYKve5g==", + "dependencies": [ + "typographic-quotes-l10n-db" + ] + }, + "typographic-registered-trademark@1.0.1": { + "integrity": "sha512-pxjY5hicdCH+VPEzqgoYlQD9ZXMqaJZgOLrAweIzBl19hs6SLLdf8CD0kXF6jv9s4QRCjTl/uiaoVkid6paI9Q==" + }, + "typographic-single-spaces@1.0.2": { + "integrity": "sha512-OTfrg6zmAx2XXaaXywdFfFIJ/w2e2/DZdRwBK+IqJHjEEzN0C1QtQ7kkOCW/Rdf04S1K639Wcb3y5OPVlP4zew==" + }, + "typographic-trademark@1.0.1": { + "integrity": "sha512-d+vFEiagUVltY/cFD2wzATb1YZvOvx+SmxHtCq1QLc22mImkpAccOD826d6eRCUFx75eGhsE3nWjNKOsis2Ibg==" + }, "uc.micro@2.0.0": { "integrity": "sha512-DffL94LsNOccVn4hyfRe5rdKa273swqeA5DJpMOeFmEn1wCDc7nAbbB0gXlgBCL7TNzeTv6G7XVWzan7iJtfig==" }, diff --git a/sample.md b/sample.md index 0c1365e..5b6ffcb 100644 --- a/sample.md +++ b/sample.md @@ -6,7 +6,9 @@ useNewStyle: true Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. -## h2 --- 2nd level heading +"This is a text in quotes..." + +## h2 -- 2nd level heading First term : This is an important term that requires defining. @@ -22,7 +24,7 @@ Third term : - With a couple of - Bullet points -### h3 --- 3rd level heading +### h3 -- 3rd level heading #### h4 From 736ac88307a2acaedc9e114536cda0b7b8141556 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20=C5=A0t=C4=9Bp=C3=A1nek?= Date: Sat, 2 Aug 2025 23:12:20 +0200 Subject: [PATCH 39/44] Remove toc from config --- _config.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/_config.ts b/_config.ts index 0d91940..63271f2 100644 --- a/_config.ts +++ b/_config.ts @@ -17,7 +17,6 @@ import shiki from "./_plugins/shiki.ts"; import sitemap from "lume/plugins/sitemap.ts"; import inline from "lume/plugins/inline.ts"; import pagefind from "lume/plugins/pagefind.ts"; -import toc from "lume_markdown_plugins/toc.ts"; import esbuild from "lume/plugins/esbuild.ts"; import typographicBase from "npm:typographic-base"; @@ -85,13 +84,6 @@ site.use(remark({ } } })); -// site.use(toc({ -// tabIndex: false, -// // anchor: false, -// anchor: linkInsideHeader({ -// placement: "before" -// }) -// })); site.use(jsx()); site.use(esbuild({ options: { From 2e13d1943deecaff28d15d5f9f64f5d6f9aad6b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adam=20=C5=A0t=C4=9Bp=C3=A1nek?= Date: Sun, 3 Aug 2025 19:55:07 +0200 Subject: [PATCH 40/44] Add more plugins - Tailwind - Custom git commit SHA extractor - Remark title extractor --- _config.ts | 8 +- _includes/layouts/base.tsx | 68 +++--- _includes/layouts/default.tsx | 19 +- _plugins/git.ts | 41 ++++ _plugins/remark-title.ts | 67 ++++++ deno.lock | 318 ++++++++++++++++++++++++- sample.md | 3 +- styles/tailwind.css | 1 + szmgr/PGV00_zpracovani_obrazu_intro.md | 3 +- szmgr/_data.yml | 1 + 10 files changed, 482 insertions(+), 47 deletions(-) create mode 100644 _plugins/git.ts create mode 100644 _plugins/remark-title.ts create mode 100644 styles/tailwind.css diff --git a/_config.ts b/_config.ts index 63271f2..2caf7f7 100644 --- a/_config.ts +++ b/_config.ts @@ -3,6 +3,7 @@ import remark from "lume/plugins/remark.ts"; import remarkAlert from "./_plugins/remark-alerts.ts"; import { remarkDefinitionList, defListHastHandlers } from "npm:remark-definition-list"; import remarkTextr from "npm:remark-textr"; +import remarkTitle from "./_plugins/remark-title.ts"; import rehypeSlug from "npm:rehype-slug"; import rehypeAutolinkHeadings from "npm:rehype-autolink-headings"; import jsx from "lume/plugins/jsx.ts"; @@ -19,9 +20,11 @@ import inline from "lume/plugins/inline.ts"; import pagefind from "lume/plugins/pagefind.ts"; import esbuild from "lume/plugins/esbuild.ts"; import typographicBase from "npm:typographic-base"; +import tailwindcss from "lume/plugins/tailwindcss.ts"; import { AsciidoctorEngine, asciidocLoader } from "./_plugins/asciidoc.ts"; import finder from "./_plugins/finder.ts"; +import git from "./_plugins/git.ts"; const site = lume({ dest: "public/", @@ -60,7 +63,8 @@ site.use(remark({ typographicBase ] } - ] + ], + [remarkTitle] ], rehypePlugins: [ [rehypeSlug], @@ -97,6 +101,7 @@ site.use(esbuild({ } })); site.use(sass()); +site.use(tailwindcss()); site.use(postcss()); site.use(metas()); site.use(resolveUrls()); @@ -158,6 +163,7 @@ site.add("styles"); site.add([".md", ".ad"]); site.add([".png", ".jpg", ".jpeg", ".gif", ".svg"]) site.use(finder()); +site.use(git()); site.use(pagefind({ indexing: { rootSelector: "main" diff --git a/_includes/layouts/base.tsx b/_includes/layouts/base.tsx index ed07f8d..863d2a6 100644 --- a/_includes/layouts/base.tsx +++ b/_includes/layouts/base.tsx @@ -1,41 +1,45 @@ export interface FrontPageData extends Lume.Data { - styles?: string[]; - useNewStyle?: boolean; + styles?: string[]; + useNewStyle?: boolean; } export default function ( - { title, children, styles, useNewStyle }: FrontPageData, + { title, children, styles, useNewStyle }: FrontPageData, ) { - return ( - // dark theme is not ready yet - - - - - - - - {title ? `${title} | Poznámky z FI` : "Poznámky z FI"} + const timestamp = Math.floor(Date.now() / 1000); + return ( + // dark theme is not ready yet + + + + + + + + {title ? `${title} | Poznámky z FI` : "Poznámky z FI"} - {!useNewStyle && - (styles ?? []).map((style) => ( - - ))} - {useNewStyle && } + {!useNewStyle && + (styles ?? []).map((style) => )} + {useNewStyle && ( + <> + + + + )} - -