====== Rastrový zobrazovací řetězec, jeho fixní a programovatelné bloky, programování pomocí shaderů. Typické transformace a jejich reprezentace. Osvětlovací model. Základní parametrické křivky. ====== [[https://fel.cvut.cz/cz/education/bk/predmety/31/32/p3132906|B0B39PGR]] [[https://cw.fel.cvut.cz/wiki/courses/pgr/start|Webové stránky předmětu]] * **Rastrový zobrazovací řetězec, jeho fixní a programovatelné bloky** – popis logických bloků v zobrazovacím řetězci a jejich funkce. Perspektivně správná interpolace. Vrstvy obrazové paměti a jejich účel (použití v bloku operací a testů). Textury – zobrazování (způsoby kombinace s osvětlením), filtrování, mip-mapping, mapa prostředí. * **Programování pomocí shaderů** – základní datové typy v GLSL (skalár, vektor, matice, sampler). Rozdíl mezi proměnnými in a uniform. Jak se přiřazují hodnoty proměnných z OpenGL do GLSL. * **Typické transformace a jejich reprezentace** – lineární a afinní transformace a jejich maticová reprezentace, homogenní souřadnice. Sestavení matice rotace podle jedné souřadné osy, škálování, nastavení kamery (lookAt) a záběru (viewport). Posloupnost souřadných systémů, kterými prochází vrchol, než získá souřadnice v rámci okna. Transformace vůči zadanému souřadnému systému. Matice rovnoběžného a perspektivního promítání. Gimbal lock. Interpolace translace a rotace (kvaterniony, lerp a slerp). * **Osvětlovací model** – normálový vektor a jeho použití při výpočtu osvětlení v bodě. Výpočet normály trojúhelníka. Interpolace normály a ostatních vektorů a proč se používají normalizované vektory. Phongův osvětlovací model, vzorce jednotlivých složek. Proč stačí kanály RGB (metamerismus)? Základní typy světel a jejich simulace ve Phongově osvětlovacím modelu. Metody stínování. * **Základní parametrické křivky** – interpolační (Ferguson, Catmull-Rom) a aproximační křivky (Bézier, B-spline, NURBS). Parametrická reprezentace. Spojitost při napojování segmentů. Adaptivní vykreslování Bézierovy křivky (algoritmus de Casteljau). ===== 1. Rastrový zobrazovací řetězec ===== ==== 1. Popis rastrového zobrazovacího řetězce ==== Rastrový zobrazovací řetězec (pipeline) je sekvence operací, která převádí 3D scénu na 2D obraz. Obsahuje programovatelné (*) i fixní bloky. **Pipeline kroky:** * **Vertex data** – vstupní data: pozice, normály, barvy, texturovací souřadnice. * **Vertex Shader** (*) – operace nad každým vertexem: transformace vertexů do prostoru kamery, výpočet osvětlení (per-vertex) a texturovacích souřadnic * **Tesselation** (*) – volitelně rozdělí geometrii na jemnější prvky (detailnější modely) * **Primitive Assembly** – spojení vertexů do základních grafických útvarů (primitiv - trojúhelníky, quady) * **Clipping** – odstraní části primitiv, které leží mimo pohledový objem (frustum) * **Back-face culling** – odstraní plochy, které jsou odvráceny od kamery (zrychluje vykreslování) * **Perspective Divide** – převod souřadnic do normalizovaného prostoru zařízení (NDC) * **Viewport Transform** – převede NDC souřadnice do okna aplikace (obrazovky) * **Geometry Shader** (*) – volitelně generuje nové vrcholy nebo primitiva z existujících * **Rasterizace** – převede primitiva na fragmenty (kandidáty na pixely) * **Fragment Shader** (*) – vypočítá barvu, texturu a efekty pro každý fragment * **Operace s fragmenty** – rozhodují, zda a jak se fragment vykreslí: * **Depth test** – fragment se vykreslí jen pokud je blíže k kameře než předchozí fragment (řeší zakrývání objektů) * **Stencil test** – umožňuje omezit vykreslování na specifické oblasti nebo tvary (např. efekty, zrcadla) * **Blending** – kombinuje barvu nového fragmentu s barvou již existující (například pro průhlednost nebo světelné efekty) * **Scissor test** – kreslí se jen fragmenty uvnitř předem definovaného obdélníku (používá se například při optimalizaci výpočtů) {{:statnice:bakalar:pasted:20250311-101844.png?350}} Poznámka: Fragment je soubor hodnot vytvořený rasterizací, který reprezentuje vzorek z oblasti jednoho pixelu vykreslovaného primitiva. Obsahuje například interpolovanou barvu, hloubku nebo pozici v okně. ==== 2. Perspektivně správná interpolace ==== Při rasterizaci musí být atributy (barvy, normály, texturovací souřadnice) interpolovány tak, aby respektovaly perspektivní zkreslení. Lineární interpolace v obrazovém prostoru by vedla ke zkreslení. **Postup:** 1. Atributy vertexu se vynásobí hodnotou \( W_c \), kde: \[ W_c = -z_{\text{eye}} \] 2. Následuje lineární interpolace mezi vrcholy: \[ A_{\text{interpolated}} = (1 - t) A_1 W_{c1} + t A_2 W_{c2} \] 3. Výsledek se vydělí interpolovanou hodnotou \( W_c \): \[ A = \frac{A_{\text{interpolated}}}{W_{c,\text{interpolated}}} \] Tím je dosaženo perspektivně správné interpolace. ==== 3. Vrstvy obrazové paměti ==== Různé vrstvy obrazové paměti slouží k uchovávání informací o scéně během vykreslování. * **Depth buffer (Z-buffer)** – ukládá hloubku každého pixelu vůči kameře. Zajišťuje, že blíže položené objekty překryjí vzdálenější. * **Stencil buffer** – obsahuje masku pro určení, které části obrazu se mají vykreslit. Používá se např. pro odrazy nebo výřezy. * **Color buffer** – obsahuje barevné hodnoty pixelů. Má dvě verze: * **Front buffer** – aktuálně zobrazovaný obraz. * **Back buffer** – obraz připravovaný v paměti před překreslením. * **Stereo buffer** – obsahuje dva obrazy (pro levé a pravé oko) pro stereoskopické zobrazování. ==== 4. Testy fragmentů ==== Při vykreslování jsou fragmenty testovány, zda mají být zapsány do framebufferu. * **Pixel ownership test** – testuje, zda pixel náleží aplikaci (například zda není překryt jiným oknem). * **Scissor test** – povolí vykreslení pouze uvnitř definovaného obdélníku. * **Depth test** – fragment je vykreslen jen pokud je blíže než již uložený pixel v depth bufferu. * **Stencil test** – kontroluje, zda fragment splňuje podmínky masky nastavené ve stencil bufferu. ==== 5. Operace s fragmenty ==== Po úspěšném průchodu testy mohou být fragmenty upraveny před zápisem do framebufferu. * **Blending** – míchání barvy fragmentu a barvy pozadí, umožňuje např. průhledné objekty. * **Logické operace** – provádí bitové operace mezi barvou fragmentu a barvou v bufferu (např. invertování nebo mazání). ==== 6. Textury ==== Textura je 2D obrázek nebo vzorek, který se aplikuje na povrch objektu pro zajištění detailu, barvy, lesku nebo průhlednosti. === Texturování === * **Texture coordinates** – dvojice [s, t] nebo [u, v], které definují pozici texelu na ploše objektu. * **Dopředné mapování** – převod souřadnic textury na plochu modelu. * **Inverzní mapování** – výpočet texturových souřadnic zpětně z pozice fragmentu na obrazovce. === Filtering === Slouží ke zjemnění nebo zrychlení zobrazení textur při zvětšení nebo zmenšení. * **GL_NEAREST** – zvolí nejbližší texel; rychlé, ale vzniká aliasing (kostrbaté hrany). * **GL_LINEAR** – provádí vážený průměr několika texelů; hladší výsledek, vyšší náročnost. === Mip-Mapping === Optimalizační technika, kdy jsou předpočítané menší verze textury (pyramida textur různých rozlišení) * Při zmenšování objektu se použije odpovídající úroveň detailu → vyšší výkon a menší aliasing. === Opakování textur === Určuje, jak se textura chová mimo rozsah souřadnic [0, 1]. * **Clamp** – opakuje poslední texel na okraji. * **Clamp to border** – okolí je vyplněno zvolenou barvou (často černou). * **Repeat** – textura se opakuje periodicky. * **Mirrored repeat** – textura se periodicky opakuje s převrácením. ==== 7. Sjednocení textury a světla ==== Při vykreslování se barva objektu určuje kombinací textury a světelného modelu: \[ \text{Barva objektu} = \text{Textura} \times (\text{Ambient} + \text{Diffuse} + \text{Specular}) \] Lze aplikovat více textur současně pomocí **alpha blending** (průhlednosti), což umožňuje například kombinovat základní texturu a detailní mapu. ==== 8. Environment mapping ==== Technika pro simulaci odlesků okolního prostředí na povrchu objektu. * **Sphere map** – sférická mapa prostředí, jednoduchá, ale odrazy správné jen z jednoho pohledu. * **Cube map** – šestiúhelníková textura tvořená 6 stranami krychle (±X, ±Y, ±Z); poskytuje realistické odlesky z různých směrů. **Cube mapping** je dnes standard díky své univerzálnosti a podpoře dynamických odrazů v real-time grafice. ===== 2. Programování pomocí shaderů ===== ==== 1. Shader a jeho význam ==== Shader je program běžící na GPU, který zpracovává grafická data během jednotlivých fází renderovací pipeline. Shadery umožňují velmi rychlé paralelní výpočty (**SIMD**). **GLSL (OpenGL Shading Language)** je jazyk používaný k psaní shaderů. Typy shaderů: * **Vertex shader** – operace s vrcholy (pozice, normály, textury). * **Fragment shader** – určuje barvu a vzhled každého fragmentu. * **Geometry shader** (volitelný) – generování nebo modifikace geometrie. * (další: tessellation shader, compute shader) {{:statnice:bakalar:pasted:20250514-222243.png}} ==== 2. Základní datové typy v GLSL ==== * **Skaláry** – `float`, `double`, `bool`, `int`, `uint`. * **Vektory** – např. `vec2`, `vec3`, `vec4`, `ivec3` (kombinace typu a dimenze). * **Matice** – `mat2`, `mat3`, `mat4` (čtvercové, obsahují `float`). * **Sampler** – speciální typ pro práci s texturami (`sampler2D`, `samplerCube`). ==== 3. Proměnné a jejich použití ==== * **in** – vstupní proměnná shaderu; data z předchozí fáze pipeline (např. `in vec3 normal` ve fragment shaderu). * **out** – výstupní proměnná shaderu; předává data do další fáze pipeline. * **uniform** – globální proměnná neměnná během vykreslení jednoho objektu; nastavuje se z CPU přes OpenGL (např. `uniform mat4 modelViewMatrix`). ==== 4. Předávání dat z OpenGL do GLSL ==== **Uniformy**: * Získání polohy proměnné: \[ \text{location} = \text{glGetUniformLocation(program, "name")} \] * Nastavení hodnoty: \[ \text{glUniform*}(location, value) \] V praxi to je např. glUniform1f, glUniform3fv **Atributy (Vertex Attributes)**: * Vytvoření a naplnění bufferů (`VBO`, `VAO`). * Přiřazení atributů k vertex shaderu: * Získání polohy: \[ \text{location} = \text{glGetAttribLocation(program, "attributeName")} \] * Aktivace atributu: \[ \text{glEnableVertexAttribArray(location)} \] * Nastavení formátu: \[ \text{glVertexAttribPointer(location, size, type, normalized, stride, pointer)} \] **Poznámka**: `stride` určuje vzdálenost mezi jednotlivými instancemi atributu, `pointer` určuje offset prvního prvku. ==== 5. Proces aplikace shaderů ==== - Vytvoření a kompilace shaderů (vertex, fragment) pomocí GLSL zdrojového kódu. - Připojení shaderů k programu (`glAttachShader`) pro vytvoření kompletního pipeline. - Aktivace programu (`glUseProgram`) před vykreslováním geometrie. - Naplnění bufferů daty (`VBO`, `EBO`) obsahujícími vrcholy a indexy objektů. - Přiřazení dat shaderům (nastavení vertex atributů a uniformních proměnných). - Vykreslení scény voláním (`glDrawArrays`, `glDrawElements`) podle dat v bufferech. - Update scénických dat / animace pro dynamické změny v průběhu vykreslování. - Vyčištění frame bufferu (`glClear`) pro přípravu na další snímek. ===== 3. Typické transformace a jejich reprezentace ===== ==== 1. Transformace a reprezentace ==== Transformace v grafice upravují pozice vertexů v prostoru a jsou reprezentovány maticemi (4×4). Rozlišujeme: * **Lineární transformace** – zahrnují škálování (scale) a rotace, neobsahují translaci. * **Afinní transformace** – rozšíření lineárních transformací o translaci. * **Homogenní souřadnice** – umožňují reprezentaci všech typů transformací jednotnou maticovou operací. ==== 2. Lineární a afinní transformace a jejich maticová reprezentace ==== * Předpokládáme, že bod je sloupcový vektor souřadnic a ho maticí zleva (v OpenGL), pokud by byl řádkový a matice by byla transponovaná, násobil by se vektor zprava (DirectX) === Lineární transformace === * **Rotace kolem osy X:** \[ R_x(\theta) = \begin{bmatrix} 1 & 0 & 0 & 0 \\ 0 & \cos\theta & -\sin\theta & 0 \\ 0 & \sin\theta & \cos\theta & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} \] * **Rotace kolem osy Y:** \[ R_y(\theta) = \begin{bmatrix} \cos\theta & 0 & \sin\theta & 0 \\ 0 & 1 & 0 & 0 \\ -\sin\theta & 0 & \cos\theta & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} \] * **Rotace kolem osy Z:** \[ R_z(\theta) = \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í:** \[ S(s_x, s_y, s_z) = \begin{bmatrix} s_x & 0 & 0 & 0 \\ 0 & s_y & 0 & 0 \\ 0 & 0 & s_z & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} \] === Afinní transformace === * **Translace:** \[ T(t_x, t_y, t_z) = \begin{bmatrix} 1 & 0 & 0 & t_x \\ 0 & 1 & 0 & t_y \\ 0 & 0 & 1 & t_z \\ 0 & 0 & 0 & 1 \end{bmatrix} \] * **Obecná afinní transformace se skládá z translace a lineární transformace:** \[ A = \begin{bmatrix} L & T \\ 0 & 1 \end{bmatrix} \] * kde \( L \) je 3×3 matice obsahující rotaci a škálování. === Rigidita (Proper Rigidity) === * **Rigidní transformace** – zachovávají vzdálenosti mezi body objektu, a tím i jeho tvar. * Pokud rigidní transformace zahrnuje zrcadlení, dochází ke změně orientace souřadného systému. * **Testy rigidity:** * **Ortogonalita** – vektory jsou na sebe kolmé, což samo o sobě nestačí. * **Ortonormalita** – vektory jsou kolmé a jednotkové, determinant matice je 1. * **Determinant = -1** – označuje přítomnost lichého počtu zrcadlení. * **Determinant nelze použít jako spolehlivý test rigidity, pokud matice není ortogonální.** ==== 3. Homogenní souřadnice ==== * V homogenních souřadnicích přidáváme čtvrtou souřadnici \( w \), což umožňuje jednotnou reprezentaci projekcí: \[ (x, y, z) \to (xw, yw, zw, w) \] * **Interpretace souřadnice \( w \):** * Pro body je \( w = 1 \), což umožňuje aplikaci translací (posunutí). * Pro vektory je \( w = 0 \), což znamená, že nejsou ovlivněny translací (zůstávají pouze jako směry). ==== 4. Nastavení kamery (LookAt) a záběru (Viewport) ==== === LookAt matice === Definuje pohled kamery na bod ve scéně, vstupy jsou: * **Eye** – pozice kamery * **Center** – bod, kam kamera míří * **Up** – směr nahoru * Výpočet os souřadného systému kamery: \[ Z = \text{normalize}(E - C),\\ X = \text{normalize}(\text{up} \times Z),\\ Y = Z \times X \] * Matice LookAt: \[ E = \begin{bmatrix} X & Y & Z & e \end{bmatrix} \] === Viewport === * Transformace souřadnic Normalized Device Coordinates (NDC) do okna aplikace: \[ O_x = x \frac{w}{2} + \frac{w}{2}, \\ O_y = y \frac{h}{2} + \frac{h}{2} \] ==== 5. Souřadné systémy a jejich transformace ==== {{:statnice:bakalar:pasted:20250311-101844.png?400}} * Proces, jakým prochází vertex od lokálního systému objektu až po vykreslení na obrazovce, lze popsat následovně: * **Objektový systém** – lokální souřadnice, definují pozici vertexů relativně k objektu. \[ v_{obj} = \begin{bmatrix} x_0 \\ y_0 \\ z_0 \\ w_0 \end{bmatrix} \] * **Světový systém** – aplikací modelovací transformace se převádí vertex do globálního referenčního rámce: \[ v_{world} = M \cdot v_{obj} \] * **Pohledový systém (kamera)** – aplikací pohledové transformace (LookAt matice) přesuneme vertexy do souřadnic kamery (oka): \[ v_{view} = V \cdot v_{world} \] * **Projekční systém a ořezávací souřadnice (clipping)** – pomocí projekční matice (ortogonální nebo perspektivní) transformujeme souřadnice do tzv. ořezávacího prostoru (clipping space): \[ v_{clip} = P \cdot v_{view} \] * Následuje clipping, kdy se odstraní vertexy mimo pohled kamery. * **Normalizované souřadnice zařízení (NDC)** – provede se perspektivní dělení, normalizace podle homogenní složky \( w \): \[ v_{NDC} = \frac{v_{clip}}{w} \] * **Souřadnice okna (viewport transformace)** – nakonec se NDC transformují do okna aplikace (viewport): \[ v_{window} = V_p \cdot v_{NDC} \] ==== 6. Projekční matice ==== * **Rovnoběžná (ortogonální) projekce** – nezohledňuje perspektivu, všechny body jsou promítány rovnoběžně na projekční rovinu. Používá se například pro technické výkresy. * **Perspektivní projekce** – zohledňuje vzdálenost, blízké objekty jsou větší než vzdálené. Používají se homogenní souřadnice. * **Perspektivní projekční matice** – reprezentuje převod ze světového prostoru do projekčního prostoru: \[ \begin{bmatrix} \frac{2n}{r-l} & 0 & \frac{r+l}{r-l} & 0 \\ 0 & \frac{2n}{t-b} & \frac{t+b}{t-b} & 0 \\ 0 & 0 & -\frac{f+n}{f-n} & -\frac{2fn}{f-n} \\ 0 & 0 & -1 & 0 \end{bmatrix} \] * **Ortogonální projekční matice** – slouží pro ortogonální zobrazení, kde nejsou objekty zkresleny perspektivou: \[ \begin{bmatrix} \frac{2}{r-l} & 0 & 0 & 0 \\ 0 & \frac{2}{t-b} & 0 & 0 \\ 0 & 0 & -\frac{2}{f-n} & 0 \\ 0 & 0 & 0 & 1 \end{bmatrix} \] * **Perspektivní matice** – tato matice odpovídá za převod hloubky do homogenních souřadnic: \[ \begin{bmatrix} n & 0 & 0 & 0 \\ 0 & n & 0 & 0 \\ 0 & 0 & n+f & fn \\ 0 & 0 & -1 & 0 \end{bmatrix} \] * **Vztah mezi projekčními maticemi** – Perspektivní projekční matice je výsledkem násobení ortogonální projekční matice a perspektivní matice: \[ P_{perspective} = P_{orthographic} \cdot P_{perspective\_depth} \] ==== 7. Gimbal Lock ==== * Rotace kolem dvou os může vést ke ztrátě osy volnosti. Možné řešení: * **Použití kvaternionů místo Eulerových úhlů.** ==== 8. Interpolace translace a rotace ==== Kvaterniony poskytují stabilní a efektivní způsob reprezentace a interpolace rotací v počítačové grafice. Oproti maticové reprezentaci nevedou k problémům jako je **Gimbal Lock** a umožňují plynulejší interpolaci. === Kvaterniony === * Kvaterniony jsou čtyřrozměrné vektory (skalární část \( q_0 \) a trojrozměrná imaginární část \( \mathbf{q} \)), které rozšiřují komplexní čísla pro reprezentaci rotací: \[ q = q_0 + \mathbf{q} = q_0 + q_1 i + q_2 j + q_3 k \] * **Ryzí kvaternion** – nemá skalární část: \( q_0 = 0 \). * **Jednotkový kvaternion** – má normu \( |q| = 1 \) a představuje rotaci. * **Sdružený kvaternion** – kvaternion s opačnou imaginární částí: \[ q^* = q_0 - \mathbf{q} \] * **Inverzní kvaternion** – vypočítá se jako: \[ q^{-1} = \frac{q^*}{|q|^2} \] * **Násobení kvaternionů**: * **Ryzí kvaterniony**: \[ pq = -\mathbf{p} \cdot \mathbf{q} + \mathbf{p} \times \mathbf{q} \] * **Obecné kvaterniony**: \[ p q = p_0 q_0 - \mathbf{p} \cdot \mathbf{q} + p_0 \mathbf{q} + q_0 \mathbf{p} + \mathbf{p} \times \mathbf{q} \] * Kvaterniony lze získat **z rotace maticí** nebo **ze dvou vektorů pomocí úhlu a normalizovaného vektorového součinu**. === Kvaternion jako rotace === * Kvaterniony umožňují reprezentaci rotace kolem osy \( \mathbf{u} \) o úhel \( \alpha \): \[ q = \cos \frac{\alpha}{2} + \mathbf{u} \sin \frac{\alpha}{2} \] * \( \mathbf{u} \) – jednotkový vektor osy rotace, \( \alpha \) – úhel rotace. === Interpolace kvaternionů v animaci === Interpolace mezi dvěma kvaterniony se používá k plynulé změně rotace v čase. * **LERP (Linear Interpolation)** – lineární interpolace mezi dvěma kvaterniony: \[ LERP(q_1, q_2, t) = (1 - t) q_1 + t q_2 \] * Zajišťuje konstantní rychlost interpolace, ale nemusí udržovat jednotkovou délku kvaternionu. * **nLERP (Normalized LERP)** – varianta LERP, která normalizuje výsledek: \[ nLERP(q_1, q_2, t) = \text{normalize}((1 - t) q_1 + t q_2) \] * Udržuje jednotkovou délku, ale neinterpoluje s konstantní úhlovou rychlostí. * **SLERP (Spherical Linear Interpolation)** – interpolace po jednotkové sféře: \[ SLERP(q_1, q_2, t) = \frac{\sin((1 - t) \theta)}{\sin \theta} q_1 + \frac{\sin(t \theta)}{\sin \theta} q_2 \] * Zachovává konstantní úhlovou rychlost a je ideální pro plynulé rotace velkých úhlů. * Kvaterniony jsou v počítačové grafice široce používány pro **animaci kamer, objektů, pohybových trajektorií a fyzikálních simulací**. ===== 4. Osvětlovací model ===== ==== 1. Normálový vektor a jeho použití při výpočtu osvětlení ==== * **Normálový vektor** je vektor kolmý na povrch, který ovlivňuje výpočet osvětlení a směr odrazu světla. * Určuje, jak se světlo odráží od povrchu a jak intenzivní bude osvětlení v daném bodě. * Normála musí být **normalizována**, aby měla jednotkovou délku: \[ \vec{n}_{normalized} = \frac{\vec{n}}{|\vec{n}|} \] * Každý vertex musí mít přiřazený normálový vektor. * **Normály nejsou automaticky počítány v OpenGL**, musí být definovány a uloženy v bufferu. * **U plochých povrchů** (flat surface) stačí jedna normála na celý povrch. * **U zakřivených povrchů** (curved surface) se normála mění v každém bodě. ==== 2. Výpočet normály trojúhelníka ==== * Normála trojúhelníka se vypočítá jako **vektorový součin** dvou hran trojúhelníka: \[ \vec{n} = \text{normalize}(\vec{CB} \times \vec{CA}) \] * Výsledná normála musí být **normalizována**, aby měla jednotkovou délku. ==== 3. Interpolace normály a proč se musí normalizovat ==== * Při interpolaci normál ve fragment shaderu dochází ke zkrácení jejich délky. * Interpolované normály musí být v fragment shaderu znovu normalizovány. * **Příčina zkrácení normál** – během interpolace mezi vertexy nejsou normály vždy udržovány s jednotkovou délkou. * **Rigidní transformace (rotace, translace)** nemění délku normál, zatímco nelineární transformace (škálování) mohou délku změnit. === Bonus: Transformace normálových vektorů ==== == Proč je nutné transformovat normály == * **Pokud je aplikována nerigidní transformace**, například neuniformní škálování, normálový vektor ztratí kolmou orientaci k povrchu. * K opravě normály se používá **normálová matice**, která se vypočítá jako transponovaná inverzní matice modelu: \[ N = (M^{-1})^T \] * U rigidních transformací platí zjednodušení: \[ M^{-1} = M^T \Rightarrow N = M_{3 \times 3} \] == Škálování a normály == * **Uniformní škálování** ovlivňuje délku normálového vektoru násobením škálovacím faktorem \( k \). * Zjednodušení výpočtu: \[ \vec{n'} = \frac{\vec{n}}{k} \] * což ušetří výpočetní výkon při normalizaci. == Výpočet normál pro základní tvary == * **Krychle** – Každá plocha má vlastní normálu, vertexy sdílejí normály sousedních ploch. * **Koule** – Normála v bodě \( P \) se vypočítá jako: \[ \vec{n} = \text{normalize}(P - \text{origin}) \] * **Trojúhelníky a síť (mesh)**: * Normála trojúhelníka: \[ \vec{n} = \text{normalize}(\text{crossProduct}(\text{edge}_1, \text{edge}_2)) \] * **Pro síť (mesh)** se normála vertexu počítá jako **průměr normalizovaných normál sousedních polygonů**: \[ \vec{N} = \text{normalize}(\sum_{i=0}^{pcount} \vec{N}_i) \] ==== 4. Phongův osvětlovací model ==== * Lokální empirický model osvětlení používaný v počítačové grafice. {{:statnice:bakalar:pasted:20250312-135525.png?350}} * Počítá osvětlení na základě normálového vektoru a směru světla. * Neřeší globální světelné efekty jako odrazy nebo lomy světla. * **Osvětlení se počítá zvlášť pro kanály R, G, B** a výsledná barva je jejich součet. * Celková barva bodu: \[ \text{color} = \text{emission} + \text{globalAmbient}_\text{reflected} + \sum \text{light}_i \] * Každý světelný příspěvek: \[ \text{light}_i = \text{spotlightEffect} \times \text{attenuationFactor} \times (\text{ambient}_\text{reflected} + \text{diffuse}_\text{reflected} + \text{specular}_\text{reflected}) \] === 4.1 Ambientní složka === * **Ambientní složka (ambient reflection)** simuluje nepřímé osvětlení, které je rovnoměrně rozptýlené po scéně. * Nezávisí na směru světla ani pohledu kamery. \[ \text{ambient}_\text{reflected} = \text{ambient}_\text{light} \cdot \text{ambient}_\text{material} \] * **Globální ambientní složka**: \[ \text{globalAmbient}_\text{reflected} = \text{globalAmbient}_\text{environment} \cdot \text{ambient}_\text{material} \] * Bez ambientního světla jsou neosvětlené části úplně černé. === 4.2 Difuzní složka === * **Difuzní složka (diffuse reflection)** závisí na úhlu dopadajícího světla. Používá Lambertův model: \[ \text{diffuse}_\text{reflected} = \max(\cos\alpha, 0) \cdot \text{diffuse}_\text{light} \cdot \text{diffuse}_\text{material} \] * kde \( \cos\alpha = \vec{l} \cdot \vec{n} \) * Světlo je rozptýleno rovnoměrně všemi směry. === 4.3 Spekulární složka === * **Spekulární složka (specular reflection)** modeluje odraz světla v konkrétním směru. \[ \text{specular}_\text{reflected} = [\max(cos\,\beta,0)]^\text{shininess} \cdot \text{specular}_\text{light} \cdot \text{specular}_\text{material} \] * kde \( \cos\beta = \vec{c} \cdot \vec{r} \) * Odražený vektor: \[ \vec{r} = -\vec{l} + 2(\vec{l} \cdot \vec{n})\vec{n} \] * **Shininess** určuje ostrost odlesku. === 4.4 Emisivní složka === * **Emisivní světlo (emissive light)** simuluje objekty, které samy vydávají světlo. * Není ovlivněno žádnými jinými světelnými zdroji. * Používá se např. pro světelné objekty nebo obrazovky. === 4.5 Skládání složek === * Celkové osvětlení je součet všech složek: \[ \text{color} = \text{emission} + \text{globalAmbient}_\text{reflected} + \sum \text{light}_i \] * Každá složka se počítá zvlášť pro kanály RGB. * Výsledná hodnota je omezena na rozsah \( \langle 0,1 \rangle \). === Bonus: Illuminační modely === * **Illuminační model** určuje, jak je světlo vypočítáno na povrchu objektu. * Barva bodu závisí na materiálu, světelných zdrojích a úhlu pohledu. * **Fyzikální modely** – přesné, berou v úvahu celý světelný tok (např. Lambert). * **Empirické modely** – přibližné, rychlé pro real-time (např. Phong). * **Lokální modely** – výpočet osvětlení pro každý bod zvlášť, neřeší odrazy. * **Globální modely** – berou v úvahu odrazy a stíny (např. ray tracing). == Vstupní parametry == * **\( \vec{n} \)** – normálový vektor. * **\( \vec{l} \)** – směr ke světlu. * **\( \vec{r} \)** – odražený vektor. * **\( \vec{v} \)** – směr kamery. * **Materiálové vlastnosti** – barva, lesklost, emisivita. ==== 5. Metamerismus ==== * Vjem, kdy se dvě různé barvy jeví stejně, i když mají odlišné spektrální složení. * RGB je dostačující díky třem typům čípků v lidském oku, což umožňuje efektivní reprezentaci barev v digitálních obrazech. * **Chromatická adaptace** – mozek kompenzuje barevné změny okolního osvětlení (např. white balance u kamer). * **Purkyňův jev** – při slabém světle je oko citlivější na modré tóny, červené barvy se jeví tmavší. === Bonus: Vnímání barev a spektrální odrazivost === * Barva objektu závisí na **spektrofotometrické odrazivosti** povrchu: \[ L_{\text{reflected}}(\lambda) = L_{\text{incoming}}(\lambda) \cdot \rho(\lambda) \] * Různé materiály odrážejí světlo různě podle vlnové délky, což ovlivňuje jejich vnímanou barvu. ==== 6. Typy světelných zdrojů ve Phongově modelu ==== * Světelné zdroje jsou **neviditelné**, pouze osvětlují objekty ve scéně. * Každý vertex je ovlivněn všemi zapnutými světly. * Stíny nejsou ve Phongově modelu řešeny – je nutný speciální algoritmus. === 6.1 Směrové světlo (Directional Light) === {{:statnice:bakalar:pasted:20250312-142740.png?200}} * Má pouze **směr**, ne polohu. * Neztrácí intenzitu s rostoucí vzdáleností (žádná atenuace). * Výpočet světla: \[ \text{light}_i = \text{ambient}_\text{reflected} + \text{diffuse}_\text{reflected} + \text{specular}_\text{reflected} \] * Vektor světla \( \vec{l} \) je normalizovaný směr ke světelnému zdroji. === 6.2 Bodové světlo (Point Light) === {{:statnice:bakalar:pasted:20250312-143033.png?200}} * Má konkrétní **pozici** ve scéně. * Intenzita klesá se vzdáleností (atenuace). * Směr světla: \[ \vec{l} = \text{normalize}(\text{pozice}_\text{světla} - \text{bod}) \] * Atenuace: \[ \text{attenuationFactor} = \frac{1.0}{k_C + k_L \cdot d + k_Q \cdot d^2} \] * Výpočet světla: \[ \text{light}_i = \text{attenuationFactor} \times (\text{ambient}_\text{reflected} + \text{diffuse}_\text{reflected} + \text{specular}_\text{reflected}) \] === 6.3 Reflektor (Spotlight) === {{:statnice:bakalar:pasted:20250312-143714.png?200}} * Bodové světlo s **kuželovým vyzařováním**. * Bere v úvahu **směr reflektoru** a **úhel kužele**. * Výpočet intenzity v kuželu: \[ \text{spotlightEffect} = (\vec{\text{spot}} \cdot \vec{l})^\text{SPOT\_EXPONENT} \] * Výpočet světla: \[ \text{light}_i = \text{spotlightEffect} \times \text{attenuationFactor} \times (\text{ambient}_\text{reflected} + \text{diffuse}_\text{reflected} + \text{specular}_\text{reflected}) \] === Bonus: Materiály === * **Materiál ovlivňuje interakci povrchu se světlem** – určuje, jaká část světla se pohltí, odrazí nebo rozptýlí. * **Hlavní vlastnosti materiálu:** * **Ambientní barva** – základní barva materiálu při nepřímém osvětlení. * **Difuzní barva** – rozptýlené světlo, závisí na úhlu dopadu. * **Spekulární barva** – barva odlesků, závisí na směru pohledu. * **Emisivní barva** – světlo vyzařované materiálem. * **Shininess** – určuje ostrost odlesků (vyšší hodnota = ostřejší odlesky). * **Isotropní materiály** – odrážejí světlo rovnoměrně všemi směry (plast, matné kovy). * **Anizotropní materiály** – odrážejí světlo směrově (leštěný kov, vlasy). == Způsoby zadávání materiálů v shaderech == * **Hardcoded** – pevně definované v kódu shaderu. * **Uniform proměnná** – stejný materiál pro celý objekt. * **Textury** – různé mapy (diffuse, specular, normal) umožňují detailní variace. ==== 7. Metody stínování ==== * Metody stínování určují, jak se provádí výpočet osvětlení povrchů objektů: * **Flat Shading** – každý polygon má konstantní barvu, určenou normálou středu polygonu nebo jednoho z vertexů. * **Výhoda** – rychlé výpočty. * **Nevýhoda** – viditelné hrany mezi polygony, nereálný vzhled. * **Gouraud Shading** – výpočet osvětlení ve vrcholech a interpolace barvy uvnitř polygonů. * **Výhoda** – hladší přechody než Flat Shading. * **Nevýhoda** – odlesky mohou být nepřesné nebo se ztratit. * **Phong Shading** – interpolace normál mezi vertexy a výpočet osvětlení pro každý pixel. * **Výhoda** – nejrealističtější výsledek, přesné odlesky a hladké přechody. * **Nevýhoda** – vyšší výpočetní náročnost. ===== 5. Základní parametrické křivky ===== {{:statnice:bakalar:pasted:20250527-120704.png?300}} ==== 1. Parametrická reprezentace křivek ==== Křivky můžeme popsat třemi hlavními způsoby: * **Explicitní reprezentace** – křivka je vyjádřena jako funkce \( y = f(x) \). Lze použít jen pro jednoduché křivky, nelze ji snadno použít v 3D nebo při rotacích. * **Implicitní reprezentace** – křivka je definována rovnicí \( F(x, y) = 0 \). Vhodná pro testování, zda bod leží na křivce, ale obtížná pro 3D. * **Parametrická reprezentace** – souřadnice bodu jsou funkcemi parametru \( t \): \[ x = x(t),\ y = y(t),\ z = z(t) \] Výhody: * Lze snadno určit libovolný bod na křivce. * Funguje i v 3D, na rozdíl od explicitní (např. \( y = f(x) \)) nebo implicitní (\( F(x,y) = 0 \)) reprezentace. * Parametrizace není jednoznačná: stejná křivka může být popsána různými funkcemi. ==== 2. Spojitost křivek ==== {{:statnice:bakalar:pasted:20250527-121934.png?300}} Křivky používané v počítačové grafice bývají složené z více segmentů – dílčích úseků, které dohromady tvoří celou křivku \( Q(t) \). Každý segment (např. \( Q_0(t), Q_1(t), \ldots \)) je typicky popsán polynomiálně a má zajištěnou plynulost uvnitř sebe. Aby však celá složená křivka působila plynule, je potřeba řešit **spojitost v místech napojení segmentů** – tzv. **uzlech (join points, knot points)**. Uzel je bod, kde končí jeden segment a začíná další, např. \( Q_0(1) = Q_1(0) \). V praxi vyžadujeme, aby jednotlivé segmenty na sebe navazovaly nejen v poloze, ale i ve směru nebo rychlosti – podle toho rozlišujeme různé **typy spojitosti**: * **Spojitost křivky uvnitř segmentu** je zajištěna přímo její parametrickou definicí (např. polynomem). * **Spojitost mezi segmenty** je klíčová pro zachování vizuálně plynulého tvaru celé křivky. {{:statnice:bakalar:pasted:20250527-122115.png?200}} {{:statnice:bakalar:pasted:20250527-122139.png?130}} === Parametrická spojitost (C) === {{:statnice:bakalar:pasted:20250527-122227.png?200}} Zohledňuje **směr i velikost** derivací (rychlost, zrychlení). Pokud je parametrická spojitost splněna, je zaručena i geometrická spojitost. * **C0** – křivky končí a začínají ve stejném bodě. * **C1** – křivky mají v místě napojení stejný směr a velikost první derivace (rychlosti). * **C2** – shoda i druhé derivace (zrychlení). === Geometrická spojitost (G) === Zohledňuje pouze **směr** derivací bez ohledu na velikost. Poskytuje vizuálně hladké přechody, ale bez zajištění konzistentní rychlosti. * **G0** – stejný bod (jako C0). * **G1** – stejné směry tečen, ale mohou mít různou velikost (plynulý přechod). * **G2** – stejné směry a akcelerace, velikosti se mohou lišit. {{:statnice:bakalar:pasted:20250527-122338.png?350}} ==== 3. Interpolační křivky ==== {{:statnice:bakalar:pasted:20250527-122441.png?300}} Interpolační křivky vždy **procházejí všemi zadanými kontrolními body**. Jsou vhodné například pro animace trajektorií, protože přesně sledují zadané pozice. Změna polohy jednoho bodu ovlivní i sousední segmenty. === Fergusonova (Hermitova) křivka === {{:statnice:bakalar:pasted:20250527-122725.png?300}} {{:statnice:bakalar:pasted:20250527-122755.png?250}} Parametrická kubická křivka definovaná dvěma body a jejich tečnami (směry v daných bodech). Používá 4 bázové funkce, které kombinují pozice a tečny: \[ P(t) = h_1(t)P_0 + h_2(t)P_1 + h_3(t)T_0 + h_4(t)T_1 \] * Zajišťuje spojitost **C1** (plynulé napojení polohy a rychlosti). * Vhodná pro definování pohybových drah nebo animace kostí v počítačové grafice. * Výhodou je možnost přesně ovlivnit směr a rychlost pohybu v klíčových bodech. === Catmull-Rom spline === {{:statnice:bakalar:pasted:20250527-123528.png?200}} Speciální typ kubické Hermitovy křivky, která **automaticky generuje tečny** z okolních bodů. Tečna ve středu mezi dvěma body se určuje jako: \[ T_i = \frac{P_{i+1} - P_{i-1}}{2} \] * Výrazně usnadňuje použití, protože nejsou potřeba ručně definované tečny. * Zajišťuje hladké přechody mezi body s parametrickou spojitostí **C1**. * Velmi často se používá při animacích pohybu kamery, objektů nebo částic podél cesty definované body. ==== 4. Aproximační křivky ==== {{:statnice:bakalar:pasted:20250527-122843.png?300}} Aproximační křivky **neprocházejí přímo kontrolními body**, ale jejich poloha a váha určují tvar křivky. Používají se tam, kde je důležitá hladkost a flexibilita křivky. Výhodou je i **lokální vliv změn** – posun kontrolního bodu ovlivní jen část křivky. === Bézierova křivka === {{:statnice:bakalar:pasted:20250527-122908.png?200}} {{:statnice:bakalar:pasted:20250527-122951.png?150}} Křivka definovaná pomocí Bernsteinových polynomů: \[ B(t) = \sum_{i=0}^{n} b_i B_{i,n}(t) \] kde: \[ B_{i,n}(t) = \binom{n}{i} (1 - t)^{n - i} t^i \] * **C0 spojitost** – poslední bod první křivky je shodný s prvním bodem druhé. * **C1 spojitost** – dosažitelná vhodným symetrickým umístěním ovládacích bodů. * Nejčastější je **kubická Bézierova křivka** (4 body, stupeň 3). * Používá se v počítačové grafice, typografii (fonty), vektorové grafice a animacích. * Jednoduchá implementace, ale globální vliv – změna bodu ovlivní celou křivku. === Bonus: Bernsteinovy polynomy === Bernsteinovy polynomy tvoří základní bázové funkce Bézierových křivek. Pro stupeň \( n \) a index \( i \) jsou definovány jako: \[ B_{i,n}(t) = \binom{n}{i} (1 - t)^{n - i} t^i \] kde \( t \in [0,1] \). Mají tyto vlastnosti: * Všechny hodnoty jsou nezáporné. * Mají maximum v jediném bodě. * Součet všech polynomů daného stupně je vždy 1: \[ \sum_{i=0}^{n} B_{i,n}(t) = 1 \] Tím zajišťují stabilitu a plynulou interpolaci mezi kontrolními body. === Algoritmus de Casteljau === {{:statnice:bakalar:pasted:20250527-123058.png?300}} Stabilní numerická metoda pro výpočet bodu na Bézierově křivce: * Funguje na principu opakované lineární interpolace mezi body: \[ P_{i}^{r}(t) = (1 - t) P_{i}^{r-1} + t P_{i+1}^{r-1} \] kde \( P_{i}^{0} = P_i \) jsou původní kontrolní body. * Opakuje se, dokud nezůstane jediný bod \( P_{0}^{n}(t) \), což je bod na křivce. * Umožňuje rozdělit křivku na dvě menší v libovolném parametru \( t \). * Používá se při adaptivním vykreslování a vektorových editorech. **Rozdíl:** de Casteljau algoritmus přímo počítá body Bézierovy křivky a umožňuje její stabilní dělení. === B-Spline === Segmentovaná polynomiální křivka s možností řízení tvaru přes tzv. **uzlový vektor**: * **Uniform B-Spline** – uzly jsou rozloženy pravidelně (rovnoměrné segmenty). * **Non-Uniform B-Spline (NUBS)** – uzly lze rozmístit libovolně, což dává větší kontrolu nad tvarem. * Zajišťuje **C2 spojitost** – plynulé spojení segmentů (pozice, tečna i křivost). * **Lokální vliv** – změna jednoho kontrolního bodu ovlivní jen příslušný úsek křivky. * Využití: animace, CAD modelování, počítačová grafika. === Coonsova křivka === {{:statnice:bakalar:pasted:20250527-122925.png?200}} {{:statnice:bakalar:pasted:20250527-123148.png?150}} Speciální případ uniformního kubického B-Spline: * Definována čtyřmi kontrolními body. * Pozice bodu na křivce je dána lineární kombinací těchto bodů pomocí bázových funkcí: \[ P(t) = \sum_{i=0}^{3} B_i(t) P_i \] kde \( B_i(t) \) jsou uniformní kubické B-Spline funkce. * Kontrolní body neleží přímo na křivce, ale určují její průběh. * Tangenty v krajních bodech jsou rovnoběžné s úsečkami ke krajním bodům. * Při sdílení dvou sousedních bodů lze dosáhnout **C2 spojitosti**. * Křivka **prochází antitěžištěm** svých čtyř kontrolních bodů – tedy bodem, který je aritmetickým průměrem jejich souřadnic. Tento bod ovlivňuje celkový tvar křivky a přispívá k její symetrii. {{:statnice:bakalar:pasted:20250527-123218.png?200}} **Rozdíl:** Coonsova křivka je aproximační (křivka neprochází kontrolními body), zatímco de Casteljau je interpolační pro Bézierovy křivky. === Bonus: Výpočetní náročnost křivek === Při práci s křivkami v grafice je důležitá i **efektivita výpočtu** a **vhodnost použití** pro různé účely. * **Bézierovy křivky**: * Výpočet bodu na křivce: pomocí **de Casteljau algoritmu** (rekurzivní interpolace), náročnost roste s počtem bodů. * **Nevýhoda**: změna jednoho kontrolního bodu ovlivní celou křivku (globální vliv). * **Výhoda**: jednoduché na implementaci, vhodné pro krátké segmenty nebo přesně řízené tvary. * **B-Spline**: * Výpočet bodu pomocí **rekurze Cox–de Boor** – bod se určuje postupným váženým zprůměrováním sousedních bodů podle uzlového vektoru. * **Výhoda**: **lokální vliv** – změna bodu ovlivní jen část křivky. * **Lepší škálování** při animacích a komplexních modelech (např. CAD, modelování povrchů). Obecně platí: * **Bézier** – rychlejší pro malé množství bodů, intuitivnější řízení. * **B-Spline** – výhodnější pro složitější, dlouhé nebo dynamicky měněné křivky. === NURBS (Non-Uniform Rational B-Spline) === NURBS (neuniformní racionální B-Spline) jsou **nejobecnější formou křivek používaných v počítačové grafice a modelování**. Umožňují velmi přesně řídit tvar pomocí **vážených kontrolních bodů** a **nepravidelného rozložení uzlů**. \[ P(t) = \frac{\sum N_{i,p}(t) w_i P_i}{\sum N_{i,p}(t) w_i} \] * \( P_i \) jsou **kontrolní body** * \( w_i \) jsou jejich **váhy** – čím větší váha, tím více křivka přiléhá k danému bodu * \( N_{i,p}(t) \) jsou **B-Spline bázové funkce** stupně \( p \) * Výraz je **racionální zlomek** – jmenovatel zajišťuje správnou normalizaci váženého průměru **Důležité vlastnosti a pojmy:** * **Afinní i perspektivní invariantnost** – NURBS zachovávají tvar i při projekcích (např. kamera). * **Homogenní souřadnice** \((xw, yw, zw, w)\) umožňují efektivní práci s váhami a transformacemi. * Dokážou přesně reprezentovat klasické tvary jako **kružnice, elipsy, kužely, válce** nebo složité CAD objekty. * **Uzlový vektor** nemusí být rovnoměrný – neuniformní rozložení umožňuje větší flexibilitu tvaru. * Umožňují **libovolnou spojitost** až po **C2**, závisle na stupni a opakování uzlů. NURBS jsou dnes **standardem v CAD systémech, 3D grafice a průmyslovém návrhu**, protože spojují přesnost, flexibilitu a efektivní výpočet.