GPU RAYTRACER PRO OSG
|
|
- Robert Mašek
- před 6 lety
- Počet zobrazení:
Transkript
1 VYSOKÉ UČENÍ TECHNICKÉ V BRNĚ BRNO UNIVERSITY OF TECHNOLOGY FAKULTA INFORMAČNÍCH TECHNOLOGIÍ ÚSTAV POČÍTAČOVÉ GRAFIKY A MULTIMÉDIÍ FACULTY OF INFORMATION TECHNOLOGY DEPARTMENT OF COMPUTER GRAPHICS AND MULTIMEDIA GPU RAYTRACER PRO OSG BAKALÁŘSKÁ PRÁCE BACHELOR S THESIS AUTOR PRÁCE AUTHOR JIŘÍ KANTOR BRNO 2013
2 VYSOKÉ UČENÍ TECHNICKÉ V BRNĚ BRNO UNIVERSITY OF TECHNOLOGY FAKULTA INFORMAČNÍCH TECHNOLOGIÍ ÚSTAV POČÍTAČOVÉ GRAFIKY A MULTIMÉDIÍ FACULTY OF INFORMATION TECHNOLOGY DEPARTMENT OF COMPUTER GRAPHICS AND MULTIMEDIA GPU RAYTRACER PRO OSG GPU RAYTRACER FOR OSG BAKALÁŘSKÁ PRÁCE BACHELOR S THESIS AUTOR PRÁCE AUTHOR VEDOUCÍ PRÁCE SUPERVISOR JIŘÍ KANTOR ING. TOMÁŠ STARKA BRNO 2013
3 Abstrakt Tato práce popisuje tvorbu jednoduchého raytraceru pro OpenSceneGraph, který běží na grafické kartě. V práci jsou popsány věci, které bylo nutné provést v OpenSceneGraphu, aby bylo možno předávat data do GPU a také několik metod pro hledání průsečíků paprsku a trojúhelníku, což je klíčový algoritmus v raytracingu. Abstract This work describes creation of a simple raytracer for OpenSceneGraph, which performs its operations on the graphics card. Things, that needed to be done in OpenSceneGraph in order to pass data to the GPU and also several ray-triangle intersection methods, are described in this work. Klíčová slova raytracing, GPU, grafická karta, OpenSceneGraph, OpenGL, GLSL, texture buffer Keywords raytracing, GPU, graphics card, OpenSceneGraph, OpenGL, GLSL, texture buffer Citace Jiří Kantor: GPU raytracer pro OSG, bakalářská práce, Brno, FIT VUT v Brně, 2013
4 GPU raytracer pro OSG Prohlášení Prohlašuji, že jsem tuto bakalářskou práci vypracoval samostatně pod vedením pana Ing. Tomáše Starky Jiří Kantor 14. května 2013 c Jiří Kantor, Tato práce vznikla jako školní dílo na Vysokém učení technickém v Brně, Fakultě informačních technologií. Práce je chráněna autorským zákonem a její užití bez udělení oprávnění autorem je nezákonné, s výjimkou zákonem definovaných případů.
5 Obsah 1 Úvod 2 2 Použité technologie Popis zadání OpenGL Pojmy OpenSceneGraph Pojmy Výpočet na GPU Raytracing Hybridní raytracing Analýza a návrh Načtení scény a identifikace odrazivých objektů Úprava grafu scény Sběr dat scény a předání do GPU Raytracing na GPU Implementace Identifikace odrazivých objektů Úprava grafu scény Příprava dat pro GPU Formát dat Konverze dat Předání dat do GPU Postup v OpenGL Postup v OpenSceneGraphu Výpočty na GPU Osvětlovací shader Raytracovací shader Závěr 28 1
6 Kapitola 1 Úvod Počítačová grafika je dnes velice dynamicky se rozvíjející odvětví informačních technologií. Snaha o co nejlepší a nejrealističtější zobrazení, a tím pádem i nutnost stále většího množství výpočtů v krátkém čase, žene tvůrce grafického hadrware k výrobě co nejrychlejších a nejflexibilnějších karet a procesorů. V současné době již téměř nelze najít kartu, která by neobsahovala programovatelný grafický procesor, který umožňuje provádět výpočty osvětlení tak, jak si přeje aplikační programátor a nikoliv jak je to definováno obvody karty. Tyto grafické procesory, a vlastně grafické karty celkově, jsou vysoce optimalizovány jednak pro výpočty v pohyblivé řádové čárce, a jednak pro nejpoužívanější operace v grafice: sčítání, odčítání a násobení vektorů, matic, skalární součin, vektorový součin atd. Je tedy nasnadě tuto výpočetní sílu využít pro raytracing, kde jsou tyto operace využívány v hojné míře a je třeba je provádět mnohokrát opakovaně. V druhé kapitole se věnuji popisu zadání práce, použitým technologiím a návrhu aplikace. Ve třetí kapitole se věnuji popisu implementace. Závěrečná kapitola obsahuje zhodnocení dosažených výsledků a možná budoucí rozšíření. Na přiloženém CD najdete zdrojové kódy, několik ukázkových modelů, přeloženou Win32 aplikaci i s knihovnami a elektronickou verzi tohoto dokumentu. 2
7 Obrázek 1.1: Scéna vykreslená fixed pipeline Obrázek 1.2: Scéna vykreslená pomocí raytracing a osvětlovacího shaderu 3
8 Kapitola 2 Použité technologie V této kapitole se budu věnovat popisu zadání, použitým technologiím a návrhu aplikace. 2.1 Popis zadání Jelikož v samotném zadání není specifikace a cílová aplikace definována přesně, je nutné si říct, jak bude vlastně vypadat. Cílem této práce je vytvořit knihovnu, která bude spolupracovat s OpenSceneGraphem a bude umožňovat raytracing výpočtem na grafické kartě. Dále je cílem vytvořit demonstrační aplikaci, která bude bude umožňovat vykreslování reflexivních objektů (jako zrcadlo, pochromované objekty... ) Bude možno si zvolit, jak budou vykreslovány objekty: osvětlovací model může být počítán v OpenGL fixed pipeline nebo v shaderu a může se to aplikovat buď na všechny objekty nebo jen na odrazivé (samozřejmě, že pokud se aplikuje shader na nereflexivní objekty, tak tím nebudou reflexivní, ale jejich osvětlovací model může být počítán v shaderu). Tímto nám vznikají čtyři možnosti (tabulka 2.1) Osvětlovací model fixed pipeline Aplikace shaderů jen na odrazivé objekty Osvětlovací model fixed pipeline Aplikace shaderů všechny objekty Osvětlovací model shader Aplikace shaderů jen na odrazivé objekty Osvětlovací model shader Aplikace shaderů všechny objekty Tabulka 2.1: Shrnutí módů běhu programu 2.2 OpenGL OpenGL je multiplatformní API pro zobrazování 2D a 3D grafiky. Tento standard nespecifikuje jak se mají operace provádět, pouze které jsou k dispozici a co mají dělat. Je to jedno z nejrošířenějšíh API, které je používané v mnoha hrách a jiných grafických aplikacích. OpenGL je stavový stroj, což znamená, že veškerá prováděná volání jsou ovlivněna právě nastaveným stavem. Tyto stavy kontrolují naprosto vše a jsou klíčovým prostředkem pro ovlivňování vykreslování a vůbec operace OpenGL. Většina implementací využívá specializovaného hardware, který je optimalizován přímo pro operace používané při zobrazování grafiky (grafické karty). V tomto hardware jsou za 4
9 sebou napojené prvky, které tyto operace provádějí zřetězeně - těmto prvkům a způsobu, jak transformují 3D data do 2D rastrového obrazu, se dohromady říká rendering pipeline (jinak též graphics pipeline, zkráceně jen pipeline). Pipeline existují dva základní druhy fixed function pipeline a programmable pipeline. Fixed function pipeline provádí transformační a další grafické operace stále stejným způsobem, který je hardwarově implementován v grafické kartě a nelze jej změnit. Programmable pipeline naopak umožňuje, aby si programátor aplikace část těchto operací sám definoval. Tyto operace jsou definovány v programu pro GPU, kterému se říká shader a tento program je pro OpenGL psán v jazyce GLSL (OpenGL Shading Language) Pojmy Nyní si řekneme několik pojmů, které budeme používat v textu v souvislosti s OpenGL vertex bod v prostoru polygon soustava několika vertexů, které tvoří jednu plochu (samozřejmě, že obecně pro n bodů nemůžeme očekávat, že budou všechny ležet v jedné rovině) trojúhelník speciální případ polygonu o třech vertexech normála vektor, který má jednotkovou velikost a v nejjednodušší verzi je kolmý k polygonu, v praxi se častěji používají vertex normály, které jsou definované pro každý vertex a nejčastěji bývají průměrem, nebo něčím podobným, normál okolních polygonů fragment jsou to všechna data, která jsou potřebná pro výpočet konečné hodnoty pixelu (čili se jedná například o polohu vertexu, normálu, texturovací souřadnice, texturu... ) osvětlovací shader shader, který počítá osvětlovací model raytracing shader shader, který počítá odrazivost (v podstatě je osvětlovací a raytracing shader spojený, ale pro vysvětlování různých módu běhu programu bude jednodušší rozdělit si je) depth buffer oblast v paměti, kam se ukládají informace o hloubce jednotlivých fragmentů sampler nástroj, který OpenGL a shader používá k získání správného texelu z textury texel jednotka textury, typicky jeden pixel obrázku, který tvoří texturup texturovací jednotka naráz lze mít navázaný jen určitý počet textur, tento počet je limitován počtem texturovacích jednotek (dle specifikace je minimum 8), což jsou hardwarové komponenty v GPU, které se starají o uchování a zpracování textur framebuffer blok paměti, do kterého se ukládají vypočítané hodnoty pixelů (OpenGL nedefinuje jak se mají data zobrazovat, takže veškeré vykreslování je definováno do framebufferu) 5
10 2.3 OpenSceneGraph OpenSceneGraph je 3D grafická knihovna psaná v C++ a vytvořená jako nadstavba nad OpenGL, která využívá graf scény. Přidává množství funkcionality, která v OpenGL není jako například organizace vertexů do primitiv a objektů, počítání času, automatická správa paměti a jiné. Je možné do ní přidávat podporu dalších typů souborů (ať už obrázků nebo 3D objektů) pomocí zásuvných modulů a tím ještě více rozšířit už tak poměrně velké množství souborových formátů, které podporuje. Tato aplikace využívá OpenSceneGraph, a rozšiřuje jeho funkcionalitu, aby bylo možné uskutečnit výpočet raytracingu na GPU Pojmy Nyní si řekneme několik pojmů, které budeme používat v textu v souvislosti s OpenScene- Graphem Další info viz [5]. uzel (node) základní stavební jednotka grafu scény, je analogická s uzlem v obecné teorii grafů state attribute jedná se o stav OpenGL, například třída BlendFunc určuje chování při míchání a je ekvivalentní volání glblendfunc. state set množina state atributů, jeden uzel má jeden state set, ve kterém jsou združeny všechny stavy nastavované pro daný uzel drawable vykreslitelný objekt geode (geometry node) jedná se o uzel, jehož úkolem je seskupovat drawably a obvykle reprezentuje nějaký logický objekt (židle, lopata atd.) user data menší množství dat, které je připojeno k uzlu a dá se vložit například do souboru scény abychom např. poskytli dodatečné informace o objektech Výpočet na GPU Doba, kdy byla funkcionalita grafických karet dána jejich hardware je pryč. Dnes je grafická karta programovatelná a to nám otevírá možnosti pro výpočet nejen čistě k účelům zobrazování, ale i k počítání čehokoliv jiného. Navíc grafické procesory obvykle mívají více paralelních jader, takže na nich může probíhat více výpočtů současně, čímž se ještě zrychlí. Pokud chceme provádět pouze výpočty, můžeme použít technologie jako OpenCL a CUDA, které jsou na toto přímo specializované - umožňují provádět na grafické kartě běžné výpočty, které nemusí vůbec souviset se zobrazováním. Druhá možnost, jak počítat na grafické kartě, je použít shader, což je speciální program, který slouží k řízení jednotlivých částí grafické pipeline. Můžeme tedy pomocí něj řídit výpočet osvětlovacího modelu, dokonce i pozice vertexů. Shader se dělí na dva základní typy: fragment shader a vertex shader. Vertex shader pracuje s vertexy objektu. Jeho výstupem je poloha vertexu na obrazovce (respektive v souřadnicovém systému, jehož počátek je v levém spodním rohu obrazovky). Fragment shader pracuje s jednotlivými rasterizovanými pixely objektu jeho výstupem je barva pixelu. 6
11 Pokud tedy do fragment shaderu budeme schopni předat celou 3D scénu, budeme moci v této scéně hledat průsečíky objektů s paprsky a tím pádem provádět výpočet raytracingu. Toto se v této práci děje. 2.5 Raytracing Raytracing je metoda zobrazování 3D objektů, při níž sledujeme trasu paprsku vyslaného z kamery přes určitý pixel promítací plochy (tzv. primární paprsek) a zaznamenáváme, s jakými objekty se paprsek protne. Z těchto bodů poté můžeme vyslat další paprsky například stínové paprsky ke světlům, abychom určili, zda je bod osvětlen nebo ne, nebo můžeme vypočítat úhel odrazu a vyslat paprsek znova do scény abychom určili, co se bude v daném bodě odrážet (tzv. sekundární paprsky). Poté všechny tyto faktory shrneme a vypočítáme, jakou bude mít pixel na promítací ploše barvu. Tato metoda produkuje velmi kvalitní výsledky, protože je s její pomocí možné jednoduše vypočítat např. stíny nebo zrcadlové odrazy. Bohužel to ale je také jedna z nejpomalejších metod, protože pro každý pixel promítací plochy je potřeba projít celou scénu a spočítat, s kterým objektem se paprsek protne, což je časově dosti náročné (délka výpočtu samozřejmě závisí na složitosti objektu, který chceme vykreslit, efektech, kterých chceme dosáhnout, jako je např. lom nebo odraz, urychlovacích prostředcích pro vyhledávání objektu ve scéně atd.). Raytracing je velmi výhodné počítat na grafické kartě a to z toho důvodu, že většina algoritmů pro výpočet průsečíku trojúhelníku a paprsku využívá skalární a vektorové součiny a násobení, vše v plovoucí řádové čárce, na což je grafický procesor optimalizován Hybridní raytracing Protože raytracing je časově náročný, nelze si jím zobrazované objekty prohlížet v reálném čase, většinou dokonce ani interaktivně (tzn. že si nelze zobrazeným objektem otáčet apod. a přitom jej mít stále zobrazený pomocí raytracingu ). Nabízí se tedy myšlenka, zda by se nedalo raytracingem zobrazit jen takovou část scény, která by bez něj zobrazit nešla a zbytek vykreslit nějakou méně náročnou metodou. A to je přesně to, co budeme v této práci chápat jako hybridní raytracing. Scéna je z většiny vykreslená pomocí rasterizace polygonů (standardní způsob v OpenGL, ale samozřejmě lze výpočet osvětlovacího modelu nechat na shaderu) a odrazivé objekty jsou poté raytracovány. Ale ani ony nejsou raytracovány úplně. Stále necháváme OpenGL rasterizovat i je, ale odrazy poté počítáme v shaderu právě vrháním paprsků do scény a zjišťováním, co se v daném pixelu odráží. Tímto způsobem nám odpádá vrhání primárního paprsku. Z formálního hlediska jej sice pořád bereme v úvahu, ale odpadá nám časově náročná operace hledání průsečíku, protože ten zjistíme právě rasterizací. 7
12 Kapitola 3 Analýza a návrh Obrázek 3.1: Schéma běžného vykreslování Obrázek 3.2: Schéma vykreslování v této práci Je nutné si určit, co vlastně bude vstupem a výstupem aplikace. Vstupem bude soubor grafu scény, ve kterém budou označené ty objekty, které chceme vykreslit jako odrazivé. Výstupem potom bude tato scéna vykreslená i s odrazivými objekty. Mezi těmito dvěma body bude ležet několik kroků: 1. Načtení grafu scény 2. Identifikace odrazivých objektů 3. Posbírání dat scény pro raytracing 4. Úprava grafu scény pro dosažení správného vykreslení 5. Předání formátovaných dat scény do GPU 8
13 6. Vykreslení scény Tyto kroky si nyní popíšeme detailněji. 3.1 Načtení scény a identifikace odrazivých objektů Načtení grafu scény provede OpenSceneGraph. Graf scény poté projdeme a zjistíme, které objekty mají nastavenou user data reflectivecoefficient na nenulovou hodnotu. 3.2 Úprava grafu scény Ač je vykreslení odrazů pomocí hybridního raytracingu rychlejší než vykreslovat celou scénu pomocí klasického raytracingu, pořád to není tak rychlé jako prostá rasterizace. Navíc se velice jednoduše může stát, že pracně vyraytracujeme odrazivý objekt a potom nám jej kompletně překryje nějaký jiný, takže by vykreslování trvalo dlouho a všechny výpočty by byly k ničemu. Jak tento problém vyřešit? OpenGL standardně řeší viditelnost objektů pomocí depth testu. Pokud je nově vykreslovaný fragment hlouběji ve scéně (=dále od kamery) než nějaký jiný na tom stejném pixelu, je jasné, že onen nový neuvidíme, protože bude překryt tím, co už tam je. OpenGL tedy zbytečně nepočítá osvětlovací model a další věci nutné pro zobrazení a rovnou tento nový fragment zahodí. Mimo jiné se také stane to, že pro tento fragment není zavolán fragment shader. To je pro naše potřeby ideální. Pokud bude odrazivý objekt překryt jiným, nespustí se fragment shader a tím pádem se nebude ani provádět náročný výpočet raytracingu odrazu. Vykreslování tedy rozdělíme do dvou fází. V první fázi se vykreslí celá scéna i s odrazivými objekty, ale odrazy se nebudou vykreslovat. V druhé fázi se vykreslí odrazy a výsledek se smíchá s výsledkem první fáze. Správného smíchání se dosáhne nastavením OpenGL a správným nastavením alfa kanálu pixelů, ze kterých se skládá odraz. OpenGL tedy provede rasterizaci a test viditelnosti a poté pro jednotlivé fragmenty spustí fragment shader. V závislosti na vybraném módu programu se fragment shader spustí pro různé objekty. Osvětlovací model počítán ve fixed pipeline Raytracing shader aplikován jen na odrazivé objekty Fragment shader se spustí jen pro fragmenty odrazivých objektů a nebude se v něm počítat osvětlovací model, jen odraz. Raytracing shader aplikován na všechny objekty Fragment shader se spustí pro fragmenty všech objektů ve scéně, ale protože je osvětlovací model počítán ve fixed pipeline, neprovede se u neodrazivých objektů žádný výpočet. Osvětlovací model počítán shaderem Raytracing shader aplikován jen na odrazivé objekty Fragment shader se spustí jen pro fragmenty odrazivých objektů a počítá se odraz i osvětlovací model. 9
14 Raytracing shader aplikován na všechny objekty Fragment shader se spustí pro fragmenty všech objektů ve scéně, takže u odrazivých objektů se bude počítat osvětlovací model i odraz a u ostatních se bude počítat osvětlovací model. 3.3 Sběr dat scény a předání do GPU Abychom mohli počítat odrazy apod., potřebujeme vědět, jak vypadá scéna, kterou chceme vykreslit. Bohužel není žádný způsob jak se ze shaderu, který běží na grafické kartě, za běhu dostat do hlavní operační paměti počítače. Byla by to časově velice náročná operace, protože by se musela data přenáše přes sběrnici a tím pádem by se celé vykonávání shaderu velice zpomalilo. Naštěstí má grafická karta svou vlastní paměť, do které se ukládají textury, vertexy, normály, prostě vše, co je třeba pro vykreslení scény. Nicméně ze shaderu se obvykle můžeme dostat jen na informace o aktuálně kresleném vertexu nebo fragmentu. Předávání dat do GPU není tak jednoduché, jak by se mohlo na první pohled zdát. V shaderu sice můžeme z našeho programu nastavit hodnoty určitých proměnných (typu uniform), ale jejich maximální velikost je omezená (řádově desítky kb). Data, která mají značnou velikost a do shaderu se předávají naprosto běžně, jsou textury. Zdálo by se tedy, že naši scénu můžeme serializovat a předat do shaderu jako texturu. Bohužel, běžné textury v shaderu limitují svůj obsah na hodnoty 0.0, 1.0. Pro data o scéně, kde jsou např. pozice vertexů, které dozajista přesahují tyto limity, je to nevhodné. Řešení představuje texture buffer (nebo buffer texture). Je to jednorozměrná textura, která svá data bere z nějakého buffer objectu, což je kus paměti, ve kterém OpenGL ukládá větší množství dat a u kterého se počítá, že se bude přenášet do paměti grafické karty. Texture buffer svá data nijak neupravuje, čili v shaderu je přečteme taková, jaká jsme je do něj vložili v OpenGL. Avšak data, která se do shaderu předávají nejsou strukturovaná, tzn. že v nich nelze jednoduše vytvářet například hierarchické struktury. Musíme najít nějaký způsob, jak tuto hierarchičnost zploštit. Je nutné pro všechny objekty zjistit, jaké mají polygony, a převést je na trojúhelníky. Také je nutné zjistit, jaké mají objekty normály, texturovací souřadnice, texturu, materiál atd. Tyto informace je poté třeba zformátovat tak, aby se daly zapsat jako pole čísel s plovoucí řádovou čárkou. Toto pole poté předáme texture bufferu jako data. Pro OpenGL a shader to bude vypadat, jakoby se do shaderu předávala jednorozměrná textura. V shaderu poté použijeme speciální sampler, který data čtená z textury neomezuje do rozsahu 0.0, Raytracing na GPU Raytracing na GPU dělá to, že počítá barvů pixelů odrazivého objektu. U daného pixelu se podle pozice kamery vypočítá, v jakém směru leží objekt, který se v něm bude odrážet, a poté hledá, který objekt to vlastně je. Pokud najde další odrazivý objekt, je možné, aby sledoval další odražený paprsek a hledal, co se odráží v tomto odraženém objektu - toto se dá opakovat mnohokrát. Pro každý bod je samozřejmě normálním způsobem vypočtená barva a s odrazem je poté smíchána podle koeficientu odrazivosti. 10
15 Obrázek 3.3: Obrázek vlevo nahoře: Vykreslen osvětlovací model, obrázek vpravo nahoře: Raytracovaný odraz (modrá barva je jen pozadí a na výslednou barvu odrazu nemá vliv, protože výsledné pixely barvy odrazu se míchají rovnou s pixely osvětlovacího modelu) obrázek dole: Smíchané kroky 11
16 Kapitola 4 Implementace Práce je implementována částečně v jazyce C++ a částečně v jazyce GLSL (OpenGL Shading Language - jazyk pro psaní shaderů v OpenGL). Vývoj jsem prováděl pod Ubuntu Linuxem, ale jak OpenGL tak OpenSceneGraph jsou multiplatformní, takže není problém přeložit aplikaci jak na Windows tak na Linuxu. Jako vývojové prostředí jsem používal Eclipse. 4.1 Identifikace odrazivých objektů Odrazivé objekty jsou v soubou scény identifikovány pomocí tzv. UserData. Je to způsob, jak předat do grafu nějaké údaje, které můžeme poté v programu zpracovávat. Co se týče raytracingu v této práci, tak stačí do souboru typu.osgt (s.osg to nefunguje) k nějaké node přidat řádky UserDataContainer TRUE { osg : : DefaultUserDataContainer { UniqueID 25 UDC UserObjects 1 { osg : : FloatValueObject { UniqueID 26 Name R e f l e c t i o n C o e f f i c i e n t Value 0.95 } } } } kde Value je požadovaná hodnota koeficientu odrazivosti a UniqueID jsou unikátní identifikátory objektů pro OSG. Pokud máme vytvořený.osgt soubor a chceme některý soubor označit jako odrazivý, stačí se podívat, jaké UniqueID je nejvyšší a poté v UserData nastavit další (v ukázce bylo předtím nejvyšší 24). 4.2 Úprava grafu scény Abychom dosáhli požadovaného vykreslení, je nutné poněkud změnit graf scény (pro znázornění viz obrázek 4.1). V prvé řadě musíme vytvořit nový kořen grafu a jako potomka 12
17 Obrázek 4.1: Znázornění úpravy grafu scény (žlutý uzel reprezentuje odrazivý objekt) mu přidat původní graf scény. Jako druhého potomka mu přidáme zpracovaný graf scény odrazivý graf. Ten vytvoříme tak, že začneme s prázdným grafem a postupně do něj přidáváme všechny odrazivé objekty. OpenGL je stavový stroj a to znamená, že vykreslování je ovlivněno aktuálně nastaveným stavem. OpenSceneGraph tyto stavy ukládá pro každý uzel grafu v tzv. state atributech (třída StateAttribute, resp. její podtřídy) a při vykreslování prochází graf scény a nastavuje stavy podle toho, jak jsou nastaveny v uzlech. Standardně stavy platí pro daný uzel a celý podgraf, jehož je kořenem, ale vše záleží na nastavení konkrétního state atributu. Je tedy nutno nastavit několik state atributů. Jedná se o: Render bin (třída RenderBin) OpenSceneGraph má podporu pro vykreslování v několika průbězích, což je přesně to, co potřebujeme. Render bin má nastavené číslo a toto číslo určuje, kolikátý se bude daný podgraf vykreslovat. Našemu původnímu grafu tedy nastavíme Render bin na 1 a odrazivému grafu na 2. Depth test (třída Depth) OpenGL používá ke správnému vykreslení překrývajících se objektů depth test neboli hloubkový test. Kromě informace o barvě si uchovává u každého pixelu i informaci o hloubce, tj. vzdálenosti od kamery. Pokud nově rasterizovaný fragment má hloubku menší než ten, který už uložený je, znamená to, že nový fragment je blíže kameře než uložený a tím pádem bude nový viditelný, protože uložený překrývá, a tudíž je tento nový fragment poslán k výpočtu osvětlení atd. V základu je depth test nastaven na LESS, čili že nový fragment se vykreslí, když je blíž než uložený. Avšak my vykreslujeme dvakrát a potřebujeme, aby se vykreslil i podruhé. Depth test tedy musíme nastavit na LESS OR EQUAL (LEQUAL v OpenSceneGraphu), což znamená, že fragment bude poslán k výpočtu osvětlení i v případě, že už uložený fragment má stejnou hloubku jako nový. Odrazivému grafu tedy nastavíme depth test na LESS - OR EQUAL. Blending (třídy BlendEquation a BlendFunc) Samozřejmě, že u překrývajících se fragmentů není jediná možnost jeden z nich odstranit. Je možné jejich barvy také smíchat, čehož využijeme v této práci. 13
18 Pro dosažení takového míchání, jaké potřebujeme, je třeba nastavit dvě věci: jaký výpočet se vlastně bude provádět a odkud se berou váhové koeficienty. To, jaký výpočet se bude provádět, určíme nastavením blend equation na některou z hodnot v tabulce 4.1. Odrazivému grafu nastavíme BlendEquation na ADD. Odkud se berou váhové koeficienty se nastavuje zvlášť pro source a destination (source je označení pro nový fragment, destination pro uložený) a možných nastavení je mnoho. My si vybereme, že váha source fragmentu bude SOURCE ALPHA a destination fragmentu ONE MINUS SOURCE ALPHA. Tím pádem budeme moci nastavením alfa hodnoty fragmentu ve fragment shaderu regulovat, v jakém poměru se budou míchat, takže čím vyšší hodnotu bude mít alfa nastavená ve fragment shaderu, tím odrazivější bude objekt. Hodnota blend equation FUNC ADD FUNC SUBTRACT FUNC REVERSE SUBTRACT Prováděný výpočet C src W src + C dst W dst C src W src C dst W dst C dst W dst C src W src MIN min(c src, C dst ) MAX max(c src, C dst ) Tabulka 4.1: Možné hodnoty blend equation a odpovídající prováděné výpočty. C src je barva nového fragmentu, W src je váhový koeficient nového fragmentu, C dst je barva uloženého fragmentu a W dst je váhový koeficient uloženého fragmentu (source je označení pro nový fragment, destination pro uložený). Tabulka převzata ve zjednodušené formě ze specifikace OpenGL. Raytracing shader (třídy Program a Shader) OpenSceneGraph bere shader také jako state attribut. Je to logické, protože ho lze pro různé objekty zapnout nebo vypnout. Shader je program, takže je třeba jej přeložit a slinkovat jako každý jiný program. Pokud kompilace nebo linkování selže, OpenSceneGraph automaticky vypíše chybový záznam z OpenGL. Bližší popis shaderu je v sekci 4.5 Texture buffer (třída TextureBuffer) Texture buffer se ukázal být poněkud problémem, protože OpenSceneGraph zatím podporu texture bufferu neobsahuje, takže bylo nutné ji doimplementovat. Nebylo to úplně triviální a bylo třeba provést určité změny v samotném OpenSceneGraphu, aby se do něj dalo texture buffer nějak hladce zakomponovat. Nepovedlo se to úplně, ale po nějakých úpravách by asi bylo možno přidat jej do oficiálních zdrojových kódů OpenSceneGraphu. Třída je potomkem třídy Texture, která je potomkem třídy StateAttribute. Bližší popis v sekci 4.4. Textury objektů scény Textury všech objektů scény jsou v této práci předány jednoduchým, i když ne ideálním způsobem: v odrazivém grafu jsou navázány textury všech otexturovaných objektů najednou. Větší množství textur se takto samozřejmě předat nedá, ale minimum 14
19 texturovacích jednotek je 8, dle specifikace OpenGL, což pro menší scény postačuje. Lepší by tedy bylo textury předat také v texture bufferu, nicméně tak by bylo třeba počítat ručně který texel vybereme podle texturovacích souřadnic. Podle specifikace rozšíření je maximální velikost texture bufferu aspoň 128MB. S tímto limitem by tedy bylo třeba počítat, ačkoliv prakticky je to mnohem víc (často to bývá omezeno pouze velikostí texturovací paměti). 4.3 Příprava dat pro GPU Abychom mohli provádět na GPU raytracing, je nutné do GPU předat informace o tom, jak scéna vlastně vypadá Formát dat Texture buffer je jednorozměrná textura a v shaderu jsou hodnoty z něj vraceny jako čtyřprvkové vektory s prvky v plovoucí řádové čárce. Celou scénu je tedy nutno uložit do jednoho velkého pole čísel s plovoucí řádovou čárkou a tato data poté předat do texture bufferu a do GPU. V shaderu je poté nutno k datům přistupovat po čtveřicích. Z toho důvodu jsou také veškeré datové struktury v tomto poli zarovnané na 4 čísla. Samozřejmě by šlo toto zarovnání porušit a data zkomprimovat co nejvíce by to šlo. Například vertexy a normály by stačilo ukládat po 3 prvcích a ne po čtyřech (normála je vektor tak jako tak a s body v nekonečnu nepočítáme), struktury by také šlo poněkud zmenšit tím, že by se odstranily výplňové nuly. Nicméně v tomto projektu jsem i tak narazil na dost drobných chyb a nejasností, které jsem musel řešit a rozhodně jsem si nechtěl přidávat ještě další možné chyby v počítání toho, který vektor musím přečíst, abych se dostal na x-tý trojúhelník y-tého objektu. Aby v takovýchto datech nebyl chaos, je třeba jim samozřejmě dát nějakou strukturu. Ta je ukázána v tabulce 4.2. Světla Materiály Objekty Vertexy Normály Texturovací souřadnice Tabulka 4.2: Rozmístění dat v texture bufferu Každá ze sekcí reprezentuje část pole čísel v plovoucí řádové čárce. Jejich hranice jsou předány do shaderu jako uniform proměnné celočíselného typu, které určují na které čtveřici daný blok začíná a také kolik daný blok obsahuje prvků. materialsstartoffset udává start bloku materiálů drawablesstartoffset udává start bloku objektů vertexstartoffset udává start bloku vertexů normalstartoffset udává start bloku normál texcoordsstartoffset udává start bloku texturovacích souřadnic numlights udává počet světel (světla začínají na nule) nummaterials udává počet materiálů 15
20 numdrawables udává počet objektů Bloky jsou vlastně pole struktur, které reprezentují daný prvek. Struktury vypadají následovně (jedna buňka je jedno číslo v plovoucí řádové čárce): Ambientní složka Difuzní složka Spekulární složka Pozice CA LA QA zar. Obrázek 4.2: Struktura pro světlo. CA je constant attenuation, LA linear attenuation, QA quadratic attenuation a zar. je zarovnání na násobek 4 čísel Ambientní složka Difuzní složka Spekulární složka S Zarovnání Obrázek 4.3: Struktura pro materiál. S je shininess VO VC MI TI Pozice BS R TE barva TM TS Zarovnání Obrázek 4.4: Struktura pro objekt. VO je index prvního vertexu tohoto objektu v poli vertexů a normál, VC je počet vertexů a normál tohoto objektu, MI je index materiálu, TI je index textury, Pozice BS je pozice bounding sphere, R je její poloměr, TE barva je texture environment barva, která se využívá v některých módech k míchání materiálu a textury TM je mód míchání materiálu a textury a TS je index do prvního vertexu tohoto objektu v poli texturovacích souřadnic. Jelikož datové typy float a integer mají shodnou velikost (4 byty), je možné do datového pole zapsat jak jeden, tak i druhý. Má to tu výhodu, že informace, které mají větší smysl předávat jako celočíselné (indexy, počty), lze předat přímo jako integer. V C++ se zapsání celého čísla na místo čísla v plovoucí řádové čárce dá dosáhnout jednoduchým přetypováním ukazatele. V shaderu pak je k dispozici funkce floatbitstoint, která přijme jako argument číslo v plovoucí řádové čárce a vrátí celé číslo reprezentované stejnými byty. Vyhneme se tak nepříjemnostem pramenícím z nepřestnosti čísla v plovoucí řádové čárce. K tomuto opatření jsem přistoupil poté, co jsem nabyl silného dojmu, že to je to, co způsobuje problémy, které jsem měl. Posléze jsem zjistil, že jsou způsobeny něčím jiným, ale ze sémantického hlediska mi přišlo jako dobrý nápad to nechat takto. Pole vertexů, normál a texturovacích souřadnic jsou uložena po trojúhelnících. To znamená, že za sebou jdoucí trojice vždy reprezentují jeden trojúhelník. Tento způsob je sice poněkud náročnější na paměť, ale zase je o něco rychlejší, protože zde odpadá nutnost dvojího přístupu do texturovací paměti pro zjištění jednoho vertexu (tak jak to je je nutno přistoupit jen jednou a rovnou získáme vertex, kdežto při uložení trojúhelníků přes indexy 16
21 by bylo nutno přistoupit jednou pro zjištění indexu a podruhé pro zjištění vertexu samotného). Vertexy a normály jsou uloženy jako čtyřprvkové vektory, texturovací souřadnice jsou uloženy jako dvouprvkové, čili v každém čtyřprvkovém vektoru (z textury jde v shaderu číst jenom po čtyřprvkových vektorech) jsou uloženy dvě texturovací souřadnice Konverze dat Abychom si zjednodušili práci při serializaci scény, překonvertujeme si nejdříve data scény do vlastního tvaru. V OpenSceneGraphu jsou totiž data uložena za poměrně velkým množstvím struktur a navíc je nejlepší procházet grafem pomocí potomka třídy NodeVisitor, který postupně prochází všechny uzly a u každého zavolá metodu apply s odpovídajícím typem uzlu. Nás zajímají uzly typu Geode (to je uzel, který obsahuje uzly typu Drawable, které obsahují vertexy a polygony ) a LightSource. Projdeme tedy všechny uzly typu Drawable nalezené ve všech uzlech typu Geode a data v nich uložená konvertujeme do objektu třídy ProcessedDrawable. Abychom si vysvětlili jak tato třída zapadá do sběru dat, je nejprve nutné si vysvětlit, jak jsou data objektu v OpenSceneGraphu typicky uložena. OpenSceneGraph využívá klasický způsob uložení, kdy máme pole vertexů, normál, texturovacích souřadnic a polygony jsou uloženy jako soustava indexů do těchto polí. OpenSceneGraph navíc při načítání modelu tyto pole vytváří tak, že do pole vertexů, normál i texturovacíh souřadnic je stejný index. Chceme li projít všechna tato data po trojúhelnících, je vhodné použít třídu TriangleIndexFunctor. Tato třída je šablonová a ve třídě, která je jí předána volá metodu void operator()( const int i1, const int i2, const int i3 ) pro každý trojúhelník. Pokud se v objektu nachází nějaký polygon, který trojúhelníkem není, převede ho tato třída na několik trojúhelníků a pro každý zavolá výše uvedenou metodu. Tu je třeba implementovat ve třídě, kterou předáváme do šablony a i1, i2 a i3 jsou právě indexy do polí vertexů, normál a texturovacích souřadnic. Navíc TriangleIndexFunctor z předané třídy dědí, takže zároveň s ním je vytvořen objekt předané třídy. V této práci je předávána třída ProcessedDrawable, která ukládá data o objektu a poté je použita pro serializaci. Každý objekt musí mít nějaké body a také, jelikož uvažujeme vyrobitelné (manifold) objekty, normály, protože je nutno počítat osvětlovací model a to je bez normál nemožné. Ne každý objekt ale musí mít texturu a texturovací souřadnice. Pokud na takový narazíme, nemá pole texturovacích souřadnic a v serializovaných datech tím pádem nezabírá žádné místo. Jeden z problémů, nad kterými jsem si lámal hlavu bylo, že jsem si toto neuvědomil a indexy do pole texturovacích souřadnic jsem počítal, jakoby každý objekt měl stejně texturovacích souřadnic jako vertexů a normál. To se projevovalo tak, že některé objekty měly na celém svém povrchu texturovací souřadnice (0, 0) a tím pádem měl celý objekt barvu horního levého texelu. Potom, co jsem si to uvědomil, jsem změnil způsob počítání indexu a chybu opravil. V průběhu sběru dat je samozřejmě třeba zjistit i různé vlastnosti objektů materiály, jakou texturu používají apod. Tyto informace jsou uloženy ve StateSetu uzlů. Abychom ale získali plný state set, ve kterém jsou vzaty v úvahu i state attributy z vyšších uzlů, je nutné provést sloučení stavů. OpenSceneGraph k tomuto nabízí přímo metodu merge, která hierarchicky sloučí stavy dvou uzlů jeden, na kterém se volá, a druhý, který se jí předá jako argument. Není jedno, který je který, protože se potom počítá s různými nastaveními state attributů (OVERRIDE, PROTECTED apod.). 17
22 4.4 Předání dat do GPU K předání serializovaných dat o scéně do shaderu použijeme technologii zvanou texture buffer. Jedná se o jakýsi hybrid mezi texturou a buffer objectem v OpenGL. Z pohledu shaderu to je jednorozměrná textura, která může mít ve svých texelech uloženou jakoukoliv hodnotu. Z pohledu OpenGL to je jak buffer tak textura, protože pro jeho vytvoření je třeba alokovat jak buffer object tak texturu a pak je svázat a naplnit daty. Nejdříve si popíšeme postup v čistém OpenGL a poté v OpenSceneGraphu. OpenSceneGraph totiž kolem buffer objectů a textur vytváří ještě poměrně silnou vrstvu, ve které provádí vlastní management těchto zdrojů Postup v OpenGL Pro buffer 1. Zavolat metodu glgenbuffers, kterou knihovně řekneme, že chceme vytvořit unikátní identifikátor (popřípadě identifikátory, takto se dá generovat více buffer objectů najednou) a datové struktury pro buffer. 2. Pomocí glbindbuffer buffer navázat, čímž řekneme, že daný typ bufferu (což je první argument, který se funkci předá), který bude v tomto případě GL - TEXTURE BUFFER, je svázán s objektem, jehož identifikátor předáme jako druhý argument. V jeden okamžik může být pro jeden typ navázán jen jeden buffer. 3. Do bufferu předat data voláním glbufferdata, kterému předáme argumenty typ bufferu (GL TEXTURE BUFFER), velikost dat, ukazatel na data a použití, které umožňuje OpenGL optimalizovat přenosy dat apod. Pro texturu 1. Zavolat metodu glgentextures, kterou knihovně řekneme, že chceme vytvořit unikátní identifikátor (popřípadě identifikátory, takto se dá generovat více textur najednou) a datové struktury pro texturu. 2. Pomocí glbindtexture texturunavázat, čímž řekneme, že daný typ textury (což je první argument, který se funkci předá), který bude v tomto případě GL - TEXTURE BUFFER, je svázán s objektem, jehož identifikátor předáme jako druhý argument. V jeden okamžik může být pro jeden typ navázána jen jedna textura. 3. Svázat buffer a texturu pomocí metody gltexbuffer, které předáme typ (GL - TEXTURE BUFFER), způsob uložení dat (GL RGBA32F, tím řekneme, že chceme čtyřkanálovou texturu RGBA a že každý kanál má být 32bitové číslo v plovoucí řádové čárce 32F). Nakonec zavoláme glbindbuffer a glbindtexture a u obou na cíl GL TEXTURE BUFFER navážeme 0, čili žádný objekt, abychom neovlivňovali další zobrazování dokud to nebudeme chtít. Abychom poté dostali data do shaderu, stačí nám u vykreslování zavolat glbindtexture s identifikátorem vytvořené textury. Musíme si samozřejmě dát pozor, kterou máme aktivní texturovací jednotku. Abychom v shaderu měli na sampler, přes který chceme k texture bufferu přistupovat, navázanou správnou texturovací jednotku, je třeba předat do shaderu uniform celočíselnou 18
23 proměnnou, která se bude jmenovat stejně jako proměnná sampleru v shaderu, a jako hodnotu ji nastavit texturovací jednotku, ve které texture buffer je. Předání uniform proměnné do shaderu provedeme následujícím způsobem: 1. Zavoláme funkci glgetuniformlocation, které předáme id shaderu a jméno proměnné, jejíž umístění v programu chceme získat. Funkce nám vrátí identifikátor uniform proměnné. 2. Funkcí gluniform1i, které předáme identifikátor, který jsme získali v předchozím kroku, a hodnotu, kterou chceme do proměnné uložit, nastavíme sampleru správnou texturovací jednotku Postup v OpenSceneGraphu Nejdříve si popíšeme, jak v OpenSceneGraphu vytvoříme a svážeme texturu a buffer object. OpenSceneGraph si, podle všeho, textury a buffer objecty spravuje z velké části sám. Nasvědčuje tomu přítomnost tříd jako TextureObjectManager. Tato třída má statickou metodu, kterou je možné získat její instanci. Získáme tedy instanci TextureObjectManageru a požádáme jej o vygenerování nové textury (typu GL TEXTURE BUFFER). S buffer objectem je to trochu složitější. Bufferů je stejně jako textur několik typů. Texture buffer je jeden z nich, takže si musíme vytvořit novou třídu TextureBufferObject, která nám bude zajišťovat, že se buffer object vytvoří se správným typem (nastaví se v konstruktoru) a také, správu dat (metoda setdata) v tomto případě nebudeme věci komplikovat a uděláme to tak, že buffer object bude moct mít jen jeden spojitý blok dat a pokud se pokusíme přidat nějaká další data, tak se prostě ukazatel na data přepíše a místo starých dat bude texture buffer obsahovat nová data. Vytvoříme tedy nový TextureBufferObject a pomocí setdata mu nastavíme data, která chceme, aby předával. Zatím se v OpenGL ještě nic neděje. Poté na takto vytvořeném objektu zavoláme funkci getorcreateglbufferobject, která vygeneruje nový OpenGL buffer object (někdy v průběhu volání této funkce může být zavolána funkce glgenbuffers) nebo použije nějaký starý, již nepoužívaný (tuto funkcionalitu přidává právě OpenScene- Graph, který si toto sám spravuje) vznikne objekt třídy GLBufferObject. Na tomto objektu poté zavoláme funkci compilebuffer, která jednak buffer naváže na cíl (glbindbuffer) a předá do něj data (glbufferdata). Potom navážeme texture object zavoláním jeho funkce bind. Nyní zavoláme přímo metodu gltexbuffer a předáme ji stejné argumenty jako v OpenGL verzi. Poté stačí odvázat buffer object (zavolat glbindbuffer s identifikátorem 0), protože ten navázaný mít nepotřebujeme. Nyní si popíšeme, jak se tento postup do OpenSceneGraphu zakomponuje. Jeden z problémů je, že funkce gltexbuffer není v žádné třídě zapouzdřena, protože OpenSceneGraph texture buffer nepodporuje. Potřebujeme li funkci, která není v OpenGL základní specifikaci, ale je to rozšíření (naprosté minimum jen těch základních funkcí je v základní specifikaci, protože OpenGL se rozšiřuje tím, že některé rozšíření potvrdí a řekne, že jsou součástí OpenGL), je dobré to udělat standardním způsobem, jakým se to v OpenSceneGraphu dělá. To je tak, že ve třídě, která tyto funkce využívá, se vytvoří vnitřní třída (nested class) Extensions, která obsahuje ukazatele na funkce, které potřebujeme. Tyto ukazatele se získávají pomocí funkce setglextensionfuncptr, která různými způsoby načte dynamickou knihovnu OpenGL a zjistí ukazatel podle toho, na kterém operačním systému je spuštěna. My potřebujeme funkci gltexbuffer a proto ji předáme jako 19
24 první jméno. Jako druhé jméno (tzv. fallback pokud se nenajde funkce prvního jména, je proveden pokus o nalezení funkce druhého jména) předáme gltexbufferext, což je jméno té samé funkce, akorát ještě předtím, než byla uznána za součást OpenGl a bylo to pouze rozšíření. Texture buffer jako celek budeme dědit od třídy Texture, protože je jí ve značné míře podobný. Navíc budeme schopni přidat TextureBuffer jako state attribut k jakémukoliv uzlu. State attributy mají několik metod, které se volají při průchodech grafem scény. Dvě, které budeme potřebovat, jsou apply a compileglobjects. Metoda apply se volá pokaždé, když je třeba daný state attribut aplikovat, tedy když je třeba nastavit stav, který tento state attribut reprezentuje. V našem případě to znamená, že je třeba navázat texturu, abychom k ní měli v shaderu přístup. Metoda compileglobjects se volá na začátku provádění programu a je určena k tomu, aby se v ní vytvořily OpenGL objekty, které budeme potřebovat. V této funkci tedy provedeme výše uvedený postup vytvoření textury, buffer objectu a jejich svázání. S třídou TextureBuffer jsem narazil na několik problémů Jako svůj typ vrací GL TEXTURE BUFFER. Tento typ se někde uvnitř OpenSceneGraphu zjišťuje a předává do nějaké funkce OpenGL, ve které se ovšem jedná o neplatnou hodnotu. OpenSceneGraph totiž při každém vykreslení vypisuje OpenGL chybu invalid enumerant. Tuto chybu se mi nepodařilo vystopovat a odstranit, ale zdá se, že na běh aplikace nemá žádný vliv. State attributy se v OpenSceneGraphu dělí na texturní a ostatní. Při přidávání state attributů do state setu se kontroluje, zda se nepředává texturní argument přes funkci, která přidává ostatní nebo naopak (funkce setattributeandmodes a settextureattributeandmodes). Pokud ano, tak se vypíše varování a zavolá se druhá funkce. Zde nastávají dva problémy: 1. Ve funkci settextureattributeandmodes se provádní trohu jiné úkony, než v setattributeandmodes, takže pomocí setattributeandmodes se nedá přidat textura. 2. To, zda je zavolána správná funkce, se kontroluje a pokud je zavolána špatná, tak OpenSceneGraph vypíše varování a zavolá správnou funkci. U textur se kontroluje, zda jsou to skutečně textury a to pomocí jejich typu. To, zda daný typ je textura je definováno v OpenSceneGraphu ve třídě Texture- GLModeSet. Samozřejmě, že hodnota GL TEXTURE BUFFER tam není, protože se s ní v OpenSceneGraphu vůbec nepočítá a bohužel naprosto není způsob, jak za běhu programu do těchto definic něco dodat. Potřebujeme zavolat metodu settexture- AttributeAndModes, takže jediné řešení je ve zdrojových kódech OpenSceneGraphu danou definici dopsat a OpenSceneGraph znova zkompilovat. Konkrétně je nutno do souboru src/osg/stateset.cpp do konstruktoru třídy TextureGLModeSet nutno přidat řádek _texturemodeset. insert ( GL_TE XTURE_ BUFFER ); OpenSceneGraph používá vlastní definice konstant z OpenGL, ve kterých, opět, není GL TEXTURE BUFFER, takže je nutno provést další zásah do zdrojových kódu a to do souboru include/osg/texture přidat někde před namespace řádky 20
25 # ifndef GL_TE XTURE_ BUFFER # define GL_TEX TURE_B UFFER 0 x8c2a # define GL_MAX_TEXTURE_BUFFER_SIZE 0 x8c2b # define GL_TEXTURE_BINDING_BUFFER 0 x8c2c # define GL_TEXTURE_BUFFER_DATA_STORE_BINDING 0 x8c2d # define GL_TEXTURE_BUFFER_FORMAT 0 x8c2e # endif 4.5 Výpočty na GPU Shadery v této práci můžeme rozdělit na dva: osvětlovací shader a raytracing shader. Osvětlovací shader počítá Phongův osvětlovací model s Phongovým stínováním (pokud je tato možnost zapnuta) a raytracing shader může technicky vzato počítat cokoliv co se raytracingem počítat dá. V demo aplikaci počítá zrcadlové odrazy. Shadery jsou v této práci rozděleny vždy do dvou souborů. Osvětlovací shader je v souborech phong.vert (vertex shader) a phong.frag (fragment shader) a raytracovací shader je v souborech raytrace.vert (vertex shader) a raytrace.frag (fragment shader). Vertex shader je spouštěn pro každý vertex. Jako vstup má pozici vertexu v souřadnicích modelu (jsou mu vlastně přímo předány souřadnice, které jsou zadány v OpenGL) a jeho výstupem je pozice vertexu v souřadnicích framebufferu pozice pixelu ve framebufferu + hloubka. Ve fixed pipeline se tato transformace provede vynásobením modelovou, pohledovou a projekční maticí (OpenGL má modelovou a pohledovou spojenou do jedné.). Modelová matice transformuje souřadnice bodu z modelových souřadnic (počátek v počátku modelu) do světových souřadnic (počátek v absolutním počátku světa). Pohledová matice ze světových souřadnic do souřadnic oka (počátek v umístění kamery) a projekční aplikuje způsob promítání (perspektiva, volné rovnoběžné promítání... ) a transformuje souřadnice ze souřadnic oka do souřadnic framebufferu. V shaderu můžeme samozřejmě provést jakoukoliv transformaci chceme, ale pro správné zobrazení 3D objektů je dobré postupovat stejně jako v případě fixed pipeline. Vertex shader může také definovat varying proměnné. Tyto proměnné jsou automaticky interpolovány mezi jednotlivými vertexy a tyto interpolované hodnoty poté přichází do fragment shaderu. To je výhodné například pro interpolaci normál nebo texturovacích souřadnic Osvětlovací shader Osvětlovací shader využívá k výpočtu osvětlení objektů Phongovo stínování [2] a Phongův osvětlovací model. Stínování říká, jak se počítají normály objektu. Phongovo stínování je takový způsob, kdy se normály interpolují z vrcholů. Běžně se používá interpolace v trojúhelníku, na který se dají převést všechny složitější polygony. Tento způsob stínování vytváří dojem povrchu, který je oblý a nikoliv složený z mnoha plošek, jako vytváří například ploché stínování (pro celý polygon se bere jedna normála). Ilustraci phongova stínování můžeme vidět na obrázku 4.5. Efektu zaoblení povrchu se dá dosáhnout i Gouraudovým stínováním (u něj se ve vrcholech vypočítá barva a ta se poté interpoluje přes polygon), avšak to má poměrně značný problém s velkými polygony. Jako příklad si vezměme situaci na obrázku
26 Obrázek 4.5: Ilustrace Phongova stínování. Vlevo interpolace na trojúhelníku, vpravo interpolace v průřezu. Černé šipky jsou vertex normály, modré jsou interpolované přes polygon. Barva se vypočítá ve vertexech A a B. Vzhledem k tomu, že situace v obou je téměř stejná (úhel mezi normálou a světlem a vzdálenost ke světlu), bude vypočítaná barva u obou velice podobná. Při interpolaci barvy poté dojde k tomu, že polygon bude mít vlastně skoro celý stejnou barvu. Což ovšem není dobře, protože správně by měla být nejjasněji osvětlená oblast kolem středu úsečky AB. Toho dosáhneme pomocí Phongova stínování, které počítá osvětlovací model pro každý fragment zvlášť, takže úhel mezi normálou a světlem a vzdálenost od světla vezme v úvahu při každém pixelu. Je to sice výpočetně náročnější metoda, ale produkuje přesnější a estetičtější výsledky. V raytracovacím shaderu je použita stejná metoda pro výpočet osvětlení odrážejících se objektů. Pro interpolaci normál je velice výhodné použít varying proměnných. Stačí, aby vertex shader zapsal správné hodnoty normál a fragment shader je dostane již interpolované. Jen je třeba pamatovat na to, že při interpolaci není zaručeno, že normála bude mít správnou (jednotkovou) velikost. V každém fragmentu je tedy třeba normálu normalizovat Raytracovací shader Při raytracingu je klíčová a nejvíce časově náročná jedna operace nalezení průsečíku paprsku a trojúhelníku. Toto se totiž opakuje mnohokrát v průběhu výpočtu jednoho pixelu. Rychlost raytracingu proto ze značné části záleží právě na rychlosti tohoto algoritmu. V této práci jsou použity dva algoritmy algoritmus pro výpočet barycentrických souřadnic [1] a geometrický algoritmus. Základem pro oba algoritmy je vypočítat průsečík paprsku a roviny, ve které trojúhelník leží. Máme tedy parametrickou rovnici paprsku (jedná se o rovnici přímky, ale v případě paprsku nabývá l jen nezáporných hodnot ), x = p + l s kde x je bod na paprsku, p je počátek, s je směr a l je parametr, a rovnici roviny, n x + d = 0 22
27 Obrázek 4.6: Ilustrace chyby ve výpočtu osvětlení Gouraudovým stínováním. kde n je normála, x je bod ležící na rovině a d je číslo reprezentující, jak daleko je rovina od počátku souřadnic. Naším cílem je vypočítat l tak, abychom po dosazení do rovnice paprsku dostali bod ležící na rovině. x je tedy v obou rovnicích stejné takže můžeme dosadit n ( p + l s) + d = 0 n p + l s n + d = 0 l s n = d n p l = d n p s n l = d + n p s n Jedinou věcí, kterou nám zbyvá dopočítat v této rovnici je d, které jednoduše odvodíme z rovnice roviny d = n b kde b je libovolný bod roviny a n je normála. Už při výpočtu l můžeme vyloučit některé výsledky. Pokud vyjde n s 0, znamená to, že paprsek je s trojúhelníkem rovnoběžný (při 0) nebo prochází jeho zadní stranou (což v případě, kdy bereme v úvahu pouze vyrobitelné objekty, které nemohou mít nulovou tloušťku, nebudeme vykreslovat) a tedy se s trojúhelníkem neprotíná. Po výpočtu l můžeme eliminovat další situace a to sice pokud l < 0, tak trojúhelník leží na opačnou stranu od počátku, než je směr paprsku, takže jej paprsek neprotíná. Pokud nepočítáme s průhlednými objekty (což v této práci nebereme v úvahu), je nutno v tomto bodě zavést kontrolu hloubky, abychom počítali pouze s průsečíkem, jež je nejblíže počátku paprsku. Toho dosáhneme tím, že při hledání průsečíků si pamatujeme nejmenší l průsečíku a pokud je nalezené l větší než uložené, tak to znamená, že by nový průsečík ležel dále od počátku než nějaký již nalezený. Tím pádem pro tento vzdálenější 23
28 průsečík nemá ani cenu kontrolovat, jestli leží uvnitř trojúhelníku, protože by stejně byl zahozen, takže tímto způsobem můžeme urychlit výpočet. Dalším krokem pro zjištění, zda paprsek protíná trojúhelník, je tedy zjistit, zda průsečík, který leží ve stejné rovině jako trojúhelník, skutečně leží uprostřed trojúhelníku. Trojrozměrný problém jsme si zjednodušili na dvojrozměrný. Právě k řešení tohoto problému jsou použity výše uvedené algoritmy. Geometrický algoritmus U tohoto algoritmu bohužel naprosto nemám tušení, kdo je jeho autorem a jak se vlastně doopravdy jmenuje. Než jsem totiž začal hledat algoritmy pro průsečík paprsku a trojúhelníku na Google, vzal jsem si tužku a papír a přišel jsem na tento způsob. Až později, při hledání rychlejších řešení, jsem našel tento algoritmus popsán na [4]. Jeho princip je velice podobný Pinedovu algoritmu pro rasterizaci polygonu [3]. Pro kandidátní bod zjišťujeme, zda leží ve správné polorovině určené postupně každou stranou trojúhelníka. To, na které straně leží, zjišťujeme pomocí vektorového součinu. Vektory při něm totiž tvoří pravotočivou bázi, takže když máme vektor e AB, který směřuje od bodu A do bodu B trojúhelníka, a v A, který směřuje z bodu a do kandidátního bodu, jejich vektorový součin bude směřovat nahoru (pokud se díváme z bodu A směrem k bodu B), pokud bude kandidátní bod vlevo a dolů, pokud bude vpravo. Pokud po výpočtu pro všechny tři strany trojúhelníka dostaneme tři vektorové součiny, které míří stejným směrem, je bod uvnitř tohoto trojúhelníka. Pokud se některý z nich liší, je bod vně. Algoritmus je ilustrován na obrázku 4.7. Obrázek 4.7: Ilustrace geometrického algoritmu pro zjištění, zda bod leží v trojúhelníku nebo ne Nevýhodou tohoto algoritmu je, že je poté třeba ještě dopočítat barycentrické souřadnice, aby bylo možno interpolovat z vrcholů. Pokud bereme v úvahu jen jednostranné trojúhelníky, tak je možné algoritmus zrychlit tím, že po vypočítání každého vektorového součinu zkontrolujeme, zda má stejný směr jako normála trojúhelníku. Pokud je totiž opačný, znamená to, že bod leží na vnější straně poloroviny a tím pádem můžeme výpočet ukončit. 24
29 Výpočet barycentrických souřadnic Tento algoritmus není příliš efektivní provádět na CPU, protože je v něm počítáno mnoho skalárních součinů a navíc v plovoucí řádové čárce, se kterou CPU počítá jen pomalu. Na druhou stranu GPU je přesně na tyto operace optimalizováno, takže je výhodné tento algoritmus použít, protože rovnou dostaneme barycentrické souřadnice. V tomto algoritmu máme 3 vektory: u, což je vektor z bodu A do bodu B, v, což je vektor z bodu A do bodu C a w, což je vektor z bodu A do kandidátního bodu. Jako první vypočteme s souřadnici, která udává, nakolik je bod posunut podle vektoru u. s = ( u v)( w v) ( v v)( w u) ( u v) 2 ( u u)( v v) Jelikož pro hodnoty s a t platí určitá omezení, můžeme nyní zrychlit výpočet ukončením, pokud nebude s tyto podmínky splňovat (místo toho, abychom to kontrolovali až na konci výpočtu). V tuto chvíli je podmínka, že s 0, 1. Pokud je s mimo tyto meze, znamená to, že je mimo trojúhelník. Pokud je v mezích, můžeme přistoupit k výpočtu t. s = ( u v)( w u) ( u u)( w v) ( u v) 2 ( u u)( v v) Pro t platí stejná podmínka jako pro s a sice, že t 0, 1. Navíc platí, že s + t 0, 1, jinak bod leží mimo trojúhelník. Je možno si povšimnout, že oba zlomky mají stejný jmenovatel, což skýtá další možnost ke zrychlení výpočtu je možno si ho předpočítat a tím si ušetřit několik operací. Každý skalární součin se také ve výpočtu vyskytuje nejméně dvakrát, takže tyto si také můžeme předpočítat. Tímto algoritmem vypočteme souřadnice s a t, pomocí kterých můžeme potom dosazením do rovnice w = s u + t v vypočítat souřadnice, normálu, texturovací souřadnici nebo třeba barvu pro kterýkoliv bod v trojúhelníku. Nicméně rovnice, tak jak je, nám moc nevyhovuje, protože se v ní počítá s vektory, tedy s rozdíly mezi vrcholy, a my přitom máme přímo hodnoty ve vrcholech. Tuto rovnici si tedy můžeme upravit, abychom počítali skutečně barycentrické souřadnice. w = s u + t v P A = s(b A) + t(c A) P = A + sb sa + tc ta P = (1 s t)a + sb + tc A, B a C jsou vrcholy trojúhelníku, P průsečík. Číslo 1 s t nazveme třeba r a dostaneme tím pádem známou rovnici pro barycentrické souřadnice. P = ra + sb + tc 25
30 Obálková koule Samozřejmě, že mít rychlý algoritmus pro průsečík paprsku a trojúhelníku je základ, ale pokud je nutno pokaždé kontrolovat všechny trojúhelníky ve scéně, trvá vykreslení moc dlouho i s tím nejrychlejším algoritmem. Rozhodl jsem se proto implementovat jednoduchou heuristiku, která je však při scéně sestávající z navzájem nepropletených objektů poměrně účinná: obálková koule (bounding sphere). Pro každý objekt (Drawable v OpenSceneGraphu) je vypočítána obálková koule a je předána do shaderu spolu s dalšími informacemi o objektech. Algoritmus pro výpočet, zda paprsek protíná kouli je jednoduchý. Nepotřebujeme totiž znát průsečíky, takže nám stačí zjistit kolmou vzdálenost paprsku od středu koule a porovnat ji s poloměrem koule. Algoritmus je ilustrován na obrázku 4.8. Obrázek 4.8: Ilustrace algoritmu pro zjištění protnutí paprsku a koule cs Aby algoritmus fungoval, musí být vektor s normalizovaný. Pro zjištění vzdálenosti paprsku od středu musíme nejdříve spočítat polohu bodu X. To provedeme tak, že nejdříve vypočítáme parametr l parametrické rovnice paprsku a poté s jeho pomocí vypočítáme bod X. Parametr zjistíme vztahem l = c s Pro urychlení výpočtu můžeme už v tuto chvíli vyloučit protnutí, pokud je l < 0, protože to znamená, že paprsek míří směrem od koule. Je zde však jedna situace, kdy paprsek kouli protíná i v tomto případě: když začíná uvnitř koule a míří směrem od středu. Potom je nutné provést ještě kontrolu, zda vzdálenost P S je menší než poloměr. Pokud je, tak paprsek vychází zevnitř koule a tím pádem může obalovaný objekt samozřejmě protnout. Další možnost pro urychlení je neporovnávat délky, ale druhé mocniny délek. Vyhneme se tím výpočetně náročnějšímu odmocňování. Výpočet raytracingu Nyní si řekneme, jak vlastně probíhá výpočet v raytracovacím shaderu. 26
Fakulta informačních technologíı. IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 1 / 38
IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL Tomáš Milet Ústav počítačové grafiky a multimédíı Fakulta informačních technologíı Vysoké učení technické Brno IZG cvičení 6. - Zobrazování 3D scény
Android OpenGL. Pokročilé shadery
Android OpenGL Pokročilé shadery Struktura programu Reálná aplikace zpravidla obsahuje více než jeden shader Kód pro inicializaci shaderu je dobré mít ve třídě (méně opisování stejného kódu) Shadery není
ANALYTICKÁ GEOMETRIE LINEÁRNÍCH ÚTVARŮ V ROVINĚ
ANALYTICKÁ GEOMETRIE LINEÁRNÍCH ÚTVARŮ V ROVINĚ Parametrické vyjádření přímky v rovině Máme přímku p v rovině určenou body A, B. Sestrojíme vektor u = B A. Pro bod B tím pádem platí: B = A + u. Je zřejmé,
Připravil: David Procházka. Vertex Buffer Objects
30. září 2013, Brno Připravil: David Procházka Vertex Buffer Objects Počítačová grafika 2 Obsah přednášky Strana 2 / 22 Obsah přednášky 1 Obsah přednášky 2 Vertex Buffer Objects 3 Příklady 4 Shrnutí Obsah
Lingebraické kapitolky - Analytická geometrie
Lingebraické kapitolky - Analytická geometrie Jaroslav Horáček KAM MFF UK 2013 Co je to vektor? Šipička na tabuli? Ehm? Množina orientovaných úseček majících stejný směr. Prvek vektorového prostoru. V
7.5.3 Hledání kružnic II
753 Hledání kružnic II Předpoklady: 750 Pedagogická poznámka: Tato hodina patří mezi vůbec nejtěžší Není reálné předpokládat, že by většina studentů dokázala samostatně přijít na řešení, po čase na rozmyšlenou
Android OpenGL. Práce s texturami
Android OpenGL Práce s texturami Textura Obrázek, který jsme schopní nanášet na 3D objekty S použitím shaderů mnohem víc než to Může obsahovat jiné vlastnosti povrchu, než jen barvu (reliéf, lesklost,
GIS Geografické informační systémy
GIS Geografické informační systémy Obsah přednášky Prostorové vektorové modely Špagetový model Topologický model Převody geometrií Vektorový model Reprezentuje reálný svět po jednotlivých složkách popisu
Zobrazování těles. problematika geometrického modelování. základní typy modelů. datové reprezentace modelů základní metody geometrického modelování
problematika geometrického modelování manifold, Eulerova rovnost základní typy modelů hranový model stěnový model objemový model datové reprezentace modelů základní metody geometrického modelování těleso
Co je grafický akcelerátor
Co je grafický akcelerátor jednotka v osobním počítači či herní konzoli přebírá funkce hlavního procesoru pro grafické operace graphics renderer odlehčuje hlavnímu procesoru paralelní zpracování vybaven
Rasterizace je proces při kterém se vektorově definovaná grafika konvertuje na. x 2 x 1
Kapitola 4 Rasterizace objektů Rasterizace je proces při kterém se vektorově definovaná grafika konvertuje na rastrově definované obrazy. Při zobrazení reálného modelu ve světových souřadnicích na výstupní
Reprezentace 3D modelu
Ing. Jan Buriánek (ČVUT FIT) Reprezentace 3D modelu BI-MGA, 2010, Přednáška 8 1/25 Reprezentace 3D modelu Ing. Jan Buriánek Katedra softwarového inženýrství Fakulta informačních technologií České vysoké
14. přednáška. Přímka
14 přednáška Přímka Začneme vyjádřením přímky v prostoru Přímku v prostoru můžeme vyjádřit jen parametricky protože obecná rovnice přímky v prostoru neexistuje Přímka v prostoru je určena bodem A= [ a1
PŘÍMKA A JEJÍ VYJÁDŘENÍ V ANALYTICKÉ GEOMETRII
PŘÍMKA A JEJÍ VYJÁDŘENÍ V ANALYTICKÉ GEOMETRII V úvodu analytické geometrie jsme vysvětlili, že její hlavní snahou je popsat geometrické útvary (body, vektory, přímky, kružnice,...) pomocí čísel nebo proměnných.
Rovnice přímky vypsané příklady. Parametrické vyjádření přímky
Rovnice přímky vypsané příklady Zdroj: Vše kromě příkladu 3.4: http://kdm.karlin.mff.cuni.cz/diplomky/jan_koncel/rovina.php?kapitola=parametrickevyjadre ni Příklady 3.5 a 3.7-1 a 3: http://kdm.karlin.mff.cuni.cz/diplomky/jan_koncel/rovina.php?kapitola=obecnarovnice
Vektory a matice. Obsah. Aplikovaná matematika I. Carl Friedrich Gauss. Základní pojmy a operace
Vektory a matice Aplikovaná matematika I Dana Říhová Mendelu Brno Obsah 1 Vektory Základní pojmy a operace Lineární závislost a nezávislost vektorů 2 Matice Základní pojmy, druhy matic Operace s maticemi
11 Zobrazování objektů 3D grafiky
11 Zobrazování objektů 3D grafiky Studijní cíl Tento blok je věnován základním algoritmům zobrazení 3D grafiky. Postupně budou probrány základní metody projekce kolmé promítání, rovnoběžné promítání a
GIS Geografické informační systémy
GIS Geografické informační systémy Obsah přednášky Prostorové vektorové modely Špagetový model Topologický model Převody geometrií Vektorový model Reprezentuje reálný svět po jednotlivých složkách popisu
Hierarchický model. 1995-2013 Josef Pelikán CGG MFF UK Praha. pepca@cgg.mff.cuni.cz http://cgg.mff.cuni.cz/~pepca/ 1 / 16
Hierarchický model 1995-2013 Josef Pelikán CGG MFF UK Praha pepca@cgg.mff.cuni.cz http://cgg.mff.cuni.cz/~pepca/ 1 / 16 Hierarchie v 3D modelování kompozice zdola-nahoru složitější objekty se sestavují
Vyhodnocení 2D rychlostního pole metodou PIV programem Matlab (zpracoval Jan Kolínský, dle programu ing. Jana Novotného)
Vyhodnocení 2D rychlostního pole metodou PIV programem Matlab (zpracoval Jan Kolínský, dle programu ing. Jana Novotného) 1 Obecný popis metody Particle Image Velocimetry, nebo-li zkráceně PIV, je měřící
Osvětlování a stínování
Osvětlování a stínování Pavel Strachota FJFI ČVUT v Praze 21. dubna 2010 Obsah 1 Vlastnosti osvětlovacích modelů 2 Světelné zdroje a stíny 3 Phongův osvětlovací model 4 Stínování 5 Mlha Obsah 1 Vlastnosti
13 Barvy a úpravy rastrového
13 Barvy a úpravy rastrového Studijní cíl Tento blok je věnován základním metodám pro úpravu rastrového obrazu, jako je např. otočení, horizontální a vertikální překlopení. Dále budo vysvětleny různé metody
2. úkol MI-PAA. Jan Jůna (junajan) 3.11.2013
2. úkol MI-PAA Jan Jůna (junajan) 3.11.2013 Specifikaci úlohy Problém batohu je jedním z nejjednodušších NP-těžkých problémů. V literatuře najdeme množství jeho variant, které mají obecně různé nároky
Programátorská dokumentace
Programátorská dokumentace Požadavky Cílem tohoto programu bylo představit barevné systémy, zejména převody mezi nejpoužívanějšími z nich. Zároveň bylo úkolem naprogramovat jejich demonstraci. Pro realizaci
7.2.12 Vektorový součin I
7 Vektorový součin I Předpoklad: 708, 7 Při násobení dvou čísel získáváme opět číslo Skalární násobení vektorů je zcela odlišné, protože vnásobením dvou vektorů dostaneme číslo, ted něco jiného Je možné
27. listopadu 2013, Brno Připravil: David Procházka
27. listopadu 2013, Brno Připravil: David Procházka Texturování Počítačová grafika 2 Obsah přednášky Strana 2 / 37 Obsah přednášky 1 Obsah přednášky 2 Texturování 3 Multum In Parvo 4 Modulace textury ve
Výhody a nevýhody jednotlivých reprezentací jsou shrnuty na konci kapitoly.
Kapitola Reprezentace grafu V kapitole?? jsme se dozvěděli, co to jsou grafy a k čemu jsou dobré. rzo budeme chtít napsat nějaký program, který s grafy pracuje. le jak si takový graf uložit do počítače?
Tabulkový procesor. Základní rysy
Tabulkový procesor Tabulkový procesor je počítačový program zpracovávající data uložená v buňkách tabulky. Program umožňuje použití vzorců pro práci s daty a zobrazuje výsledné hodnoty podle vstupních
Barvy a barevné modely. Počítačová grafika
Barvy a barevné modely Počítačová grafika Barvy Barva základní atribut pro definici obrazu u každého bodu, křivky či výplně se definuje barva v rastrové i vektorové grafice všechny barvy, se kterými počítač
DUM 06 téma: Tvorba makra pomocí VBA
DUM 06 téma: Tvorba makra pomocí VBA ze sady: 03 tematický okruh sady: Tvorba skript a maker ze šablony: 10 Algoritmizace a programování určeno pro: 4. ročník vzdělávací obor: 18-20-M/01 Informační technologie
Data v počítači. Informační data. Logické hodnoty. Znakové hodnoty
Data v počítači Informační data (elementární datové typy) Logické hodnoty Znaky Čísla v pevné řádové čárce (celá čísla) v pohyblivé (plovoucí) řád. čárce (reálná čísla) Povelová data (instrukce programu)
Návod k použití softwaru Solar Viewer 3D
Návod k použití softwaru Solar Viewer 3D Software byl vyvinut v rámci grantového projektu Technologie a systém určující fyzikální a prostorové charakteristiky pro ochranu a tvorbu životního prostředí a
( ) ( ) ( ) Tečny kružnic I. Předpoklady: 4501, 4504
7.5.5 Tečny kružnic I Předpoklady: 451, 454 Pedagogická poznámka: Následující dvě hodiny jsou na gymnázium asi početně nejnáročnější. Ačkoliv jsou příklady optimalizované na co nejmenší početní obtížnost,
Souřadnicové prostory
Prostor objektu Tr. objektu Tr. modelu Prostor scény Souřadnicové prostory V V x, y z x, y z z -z x, y Tr. objektu V =V T 1 T n M Tr. modelu Tr. scény x, y Tr. pohledu Tr. scény Tr. pohledu Prostor pozorovatele
ANALYTICKÁ GEOMETRIE V ROVINĚ
ANALYTICKÁ GEOMETRIE V ROVINĚ Analytická geometrie vyšetřuje geometrické objekty (body, přímky, kuželosečky apod.) analytickými metodami. Podle prostoru, ve kterém pracujeme, můžeme analytickou geometrii
Projekt Obrázek strana 135
Projekt Obrázek strana 135 14. Projekt Obrázek 14.1. Základní popis, zadání úkolu Pracujeme na projektu Obrázek, který je ke stažení na http://java.vse.cz/. Po otevření v BlueJ vytvoříme instanci třídy
Matematika (CŽV Kadaň) aneb Úvod do lineární algebry Matice a soustavy rovnic
Přednáška třetí (a pravděpodobně i čtvrtá) aneb Úvod do lineární algebry Matice a soustavy rovnic Lineární rovnice o 2 neznámých Lineární rovnice o 2 neznámých Lineární rovnice o dvou neznámých x, y je
VEKTORY. Obrázek 1: Jediný vektor. Souřadnice vektoru jsou jeho průměty do souřadných os x a y u dvojrozměrného vektoru, AB = B A
VEKTORY Vektorem se rozumí množina všech orientovaných úseček, které mají stejnou velikost, směr a orientaci, což vidíme na obr. 1. Jedna konkrétní orientovaná úsečka se nazývá umístění vektoru na obr.
1 Projekce a projektory
Cvičení 3 - zadání a řešení úloh Základy numerické matematiky - NMNM20 Verze z 5. října 208 Projekce a projektory Opakování ortogonální projekce Definice (Ortogonální projekce). Uvažujme V vektorový prostor
Závěrečná práce. AutoCAD Inventor 2010. (Zadání D1)
Závěrečná práce AutoCAD Inventor 2010 (Zadání D1) Pavel Čurda 4.B 4.5. 2010 Úvod Tato práce obsahuje sestavu modelu, prezentaci a samotný výkres Pákového převodu na přiloženém CD. Pákový převod byl namalován
1. Vektorové algoritmy jejich výstupem je soubor geometrických prvků, např.
Kapitola 5 Řešení viditelnosti Řešit viditelnost ve scéně umí většina grafických programů. Cílem je určit ty objekty, resp. jejich části, které jsou viditelné z určitého místa. Tyto algoritmy jsou vždy
Uživatelský manuál. Aplikace GraphViewer. Vytvořil: Viktor Dlouhý
Uživatelský manuál Aplikace GraphViewer Vytvořil: Viktor Dlouhý Obsah 1. Obecně... 3 2. Co aplikace umí... 3 3. Struktura aplikace... 4 4. Mobilní verze aplikace... 5 5. Vytvoření projektu... 6 6. Části
Úvod do lineární algebry
Úvod do lineární algebry 1 Aritmetické vektory Definice 11 Mějme n N a utvořme kartézský součin R n R R R Každou uspořádanou n tici x 1 x 2 x, x n budeme nazývat n rozměrným aritmetickým vektorem Prvky
K OZA SE PASE NA POLOVINĚ ZAHRADY Zadání úlohy
Koza se pase na polovině zahrady, Jaroslav eichl, 011 K OZA E PAE NA POLOVINĚ ZAHADY Zadání úlohy Zahrada kruhového tvaru má poloměr r = 10 m. Do zahrady umístíme kozu, kterou přivážeme provazem ke kolíku
Projekt OPVK - CZ.1.07/1.1.00/ Matematika pro všechny. Univerzita Palackého v Olomouci
Projekt OPVK - CZ.1.07/1.1.00/26.0047 Matematika pro všechny Univerzita Palackého v Olomouci Tematický okruh: Geometrie Různé metody řešení Téma: Analytická geometrie v prostoru, vektory, přímky Autor:
Třída DrawingTool. Obrázek 1: Prázdné okno připravené pro kreslení
Třída DrawingTool strana 1 1. Základ Třída DrawingTool Třída DrawingTool je určena k jednoduchému kreslení pomocí několika základních příkazů do grafického okna zadaných rozměrů (nastavení v konstruktoru),
8 Třídy, objekty, metody, předávání argumentů metod
8 Třídy, objekty, metody, předávání argumentů metod Studijní cíl Tento studijní blok má za cíl pokračovat v základních prvcích jazyka Java. Konkrétně bude věnována pozornost třídám a objektům, instančním
Fotonové mapy. Leonid Buneev
Fotonové mapy Leonid Buneev 21. 01. 2012 Popis algoritmu Photon mapping algoritmus, který, stejně jako path tracing a bidirectional path tracing, vyřeší zobrazovací rovnice, ale podstatně jiným způsobem.
Reporting. Ukazatele je možno definovat nad libovolnou tabulkou Helios Orange, která je zapsána v nadstavbě firmy SAPERTA v souboru tabulek:
Finanční analýza Pojem finanční analýza Finanční analýza umožňuje načítat data podle dimenzí a tyto součty dlouhodobě vyhodnocovat. Pojem finanční analýza není nejpřesnější, protože ukazatele mohou být
Reflections, refractions, interreflections
:: gs Reflections, refractions, interreflections Odrazy a lomy světla Grafické systémy David Sedláček 2004 :: fyzika Zákon odrazu Lom světla Snellův zákon Fresnelova rovnice poměr prošlého a odraženého
StatSoft Jak vyzrát na datum
StatSoft Jak vyzrát na datum Tento článek se věnuje podrobně možnostem práce s proměnnými, které jsou ve formě datumu. A že jich není málo. Pokud potřebujete pracovat s datumem, pak se Vám bude tento článek
Parametrická rovnice přímky v rovině
Parametrická rovnice přímky v rovině Nechť je v kartézské soustavě souřadnic dána přímka AB. Nechť vektor u = B - A. Pak libovolný bod X[x; y] leží na přímce AB právě tehdy, když vektory u a X - A jsou
M - Kvadratické rovnice a kvadratické nerovnice
M - Kvadratické rovnice a kvadratické nerovnice Určeno jako učební tet pro studenty dálkového studia. VARIACE 1 Tento dokument byl kompletně vytvořen, sestaven a vytištěn v programu dosystem - EduBase.
1 Linearní prostory nad komplexními čísly
1 Linearní prostory nad komplexními čísly V této přednášce budeme hledat kořeny polynomů, které se dále budou moci vyskytovat jako složky vektorů nebo matic Vzhledem k tomu, že kořeny polynomu (i reálného)
VZOROVÝ TEST PRO 3. ROČNÍK (3. A, 5. C)
VZOROVÝ TEST PRO 3. ROČNÍK (3. A, 5. C) max. 3 body 1 Zjistěte, zda vektor u je lineární kombinací vektorů a, b, je-li u = ( 8; 4; 3), a = ( 1; 2; 3), b = (2; 0; 1). Pokud ano, zapište tuto lineární kombinaci.
Zobrazování a osvětlování
Zobrazování a osvětlování Petr Felkel Katedra počítačové grafiky a interakce, ČVUT FEL místnost KN:E-413 na Karlově náměstí E-mail: felkel@fel.cvut.cz S použitím materiálů Bohuslava Hudce, Jaroslava Sloupa
Text úlohy. Která barva nepatří do základních barev prostoru RGB? Vyberte jednu z nabízených možností: a. Černá b. Červená c. Modrá d.
Úloha 1 Která barva nepatří do základních barev prostoru RGB? a. Černá b. Červená c. Modrá d. Zelená Úloha 2 V rovině je dán NEKONVEXNÍ n-úhelník a bod A. Pokud paprsek (polopřímka) vedený z tohoto bodu
IB112 Základy matematiky
IB112 Základy matematiky Řešení soustavy lineárních rovnic, matice, vektory Jan Strejček IB112 Základy matematiky: Řešení soustavy lineárních rovnic, matice, vektory 2/53 Obsah Soustava lineárních rovnic
Výpočet vržených stínů
Výpočet vržených stínů 1996-2016 Josef Pelikán CGG MFF UK Praha pepca@cgg.mff.cuni.cz http://cgg.mff.cuni.cz/~pepca/ Shadows 2016 Josef Pelikán, http://cgg.mff.cuni.cz/~pepca 1 / 18 Metody vícenásobný
Jak v Javě primitivní datové typy a jejich reprezentace. BD6B36PJV 002 Fakulta elektrotechnická České vysoké učení technické
Jak v Javě primitivní datové typy a jejich reprezentace BD6B36PJV 002 Fakulta elektrotechnická České vysoké učení technické Obsah Celočíselný datový typ Reálný datový typ Logický datový typ, typ Boolean
1 Analytická geometrie
1 Analytická geometrie 11 Přímky Necht A E 3 a v R 3 je nenulový Pak p = A + v = {X E 3 X = A + tv, t R}, je přímka procházející bodem A se směrovým vektorem v Rovnici X = A + tv, t R, říkáme bodová rovnice
Matice přechodu. Pozorování 2. Základní úkol: Určete matici přechodu od báze M k bázi N. Každou bázi napíšeme do sloupců matice, např.
Matice přechodu Základní úkol: Určete matici přechodu od báze M k bázi N. Každou bázi napíšeme do sloupců matice, např. u příkladu 7 (v ) dostaneme: Nyní bychom mohli postupovat jako u matice homomorfismu
Teorie informace a kódování (KMI/TIK) Reed-Mullerovy kódy
Teorie informace a kódování (KMI/TIK) Reed-Mullerovy kódy Lukáš Havrlant Univerzita Palackého 10. ledna 2014 Primární zdroj Jiří Adámek: Foundations of Coding. Strany 137 160. Na webu ke stažení, heslo:
Téma: Vektorová grafika. Určete pravdivost následujícího tvrzení: "Grafická data jsou u 2D vektorové grafiky uložena ve voxelech."
Téma: Vektorová grafika. Určete pravdivost následujícího tvrzení: "Grafická data jsou u 2D vektorové grafiky uložena ve voxelech." Téma: Vektorová grafika. Určete pravdivost následujícího tvrzení: "Na
5.2.3 Duté zrcadlo I. Předpoklady: 5201, 5202
5.2.3 Duté zrcadlo I Předpoklady: 520, 5202 Dva druhy dutých zrcadel: Kulové zrcadlo = odrazivá plocha zrcadla je částí kulové plochy snazší výroba, ale horší zobrazení (pro přesné zobrazení musíme použít
Programujeme v softwaru Statistica
Programujeme v softwaru Statistica díl druhý Newsletter Statistica ACADEMY Téma: Programování, makra, skripty Typ článku: Návody V tomto článku si ukážeme další možnosti při psaní maker v softwaru Statistica.
Mgr. Tomáš Kotler. I. Cvičný test 2 II. Autorské řešení 7 III. Klíč 15 IV. Záznamový list 17
Mgr. Tomáš Kotler I. Cvičný test 2 II. Autorské řešení 7 III. Klíč 15 IV. Záznamový list 17 VÝCHOZÍ TEXT A OBRÁZEK K ÚLOZE 1 Je dán rovinný obrazec, v obrázku vyznačený barevnou výplní, který představuje
3.2. ANALYTICKÁ GEOMETRIE ROVINY
3.2. ANALYTICKÁ GEOMETRIE ROVINY V této kapitole se dozvíte: jak popsat rovinu v třídimenzionálním prostoru; jak analyzovat vzájemnou polohu bodu a roviny včetně jejich vzdálenosti; jak analyzovat vzájemnou
Slučování tabulek. Sloučení dvou tabulek
Slučování tabulek Newsletter Statistica ACADEMY Téma: Příprava dat Typ článku: Návody Máte informace ve více tabulkách a chcete je sloučit dohromady? Pak je tento článek právě pro Vás. Vysvětlíme, jaké
A[a 1 ; a 2 ; a 3 ] souřadnice bodu A v kartézské soustavě souřadnic O xyz
1/15 ANALYTICKÁ GEOMETRIE Základní pojmy: Soustava souřadnic v rovině a prostoru Vzdálenost bodů, střed úsečky Vektory, operace s vektory, velikost vektoru, skalární součin Rovnice přímky Geometrie v rovině
1.5.1 Číselné soustavy
.. Číselné soustavy Předpoklady: základní početní operace Pedagogická poznámka: Tato hodina není součástí klasické gymnaziální sady. Upřímně řečeno nevím proč. Jednak se všichni studenti určitě setkávají
CVIČNÝ TEST 15. OBSAH I. Cvičný test 2. Mgr. Tomáš Kotler. II. Autorské řešení 6 III. Klíč 15 IV. Záznamový list 17
CVIČNÝ TEST 15 Mgr. Tomáš Kotler OBSAH I. Cvičný test 2 II. Autorské řešení 6 III. Klíč 15 IV. Záznamový list 17 I. CVIČNÝ TEST VÝCHOZÍ TEXT K ÚLOZE 1 Je dána čtvercová mřížka, v níž každý čtverec má délku
Geekovo Minimum. Počítačové Grafiky. Nadpis 1 Nadpis 2 Nadpis 3. Božetěchova 2, Brno
Geekovo Minimum Nadpis 1 Nadpis 2 Nadpis 3 Počítačové Grafiky Jméno Adam Příjmení Herout Vysoké Vysoké učení technické učení technické v Brně, v Fakulta Brně, Fakulta informačních informačních technologií
Lekce 12 Animovaný náhled animace kamer
Lekce 12 Animovaný náhled animace kamer Časová dotace: 2 vyučovací hodina V poslední lekci tohoto bloku se naučíme jednoduše a přitom velice efektivně animovat. Budeme pracovat pouze s objekty, které jsme
1.5.2 Číselné soustavy II
.. Číselné soustavy II Předpoklady: Př. : Převeď do desítkové soustavy čísla. a) ( ) b) ( ) 4 c) ( ) 6 = + + + = 7 + 9 + = a) = 4 + 4 + 4 = 6 + 4 + = 9 b) 4 = 6 + 6 + 6 = 6 + 6 + = 6 + + = 69. c) 6 Pedagogická
Číselné soustavy a převody mezi nimi
Číselné soustavy a převody mezi nimi Základní požadavek na počítač je schopnost zobrazovat a pamatovat si čísla a provádět operace s těmito čísly. Čísla mohou být zobrazena v různých číselných soustavách.
2. přednáška z předmětu GIS1 Data a datové modely
2. přednáška z předmětu GIS1 Data a datové modely Vyučující: Ing. Jan Pacina, Ph.D. e-mail: jan.pacina@ujep.cz Pro přednášku byly použity texty a obrázky z www.gis.zcu.cz Předmět KMA/UGI, autor Ing. K.
INFORMATIKA MS WORD TVORBA VLASTNÍHO STYLU
Škola: Autor: DUM: Vzdělávací obor: Tematický okruh: Téma: Masarykovo gymnázium Vsetín Mgr. Petr Koňařík MGV_VT_SS_1S3-D10_Z_WORD_VL_STYL.docx Informatika MS Word Styly, tvorba vlastního stylu INFORMATIKA
My si nyní takovou sestavu vytvoříme na příkladu jednoduché kanceláře. Začneme vytvořením takové kanceláře.
Sestavy Sestavy (angl. Reports) slouží ve Visiu k rychlému vytvoření přehledného souhrnu informací o objektech na výkresu. Visio umí tyto stručné sestavy vytvářet jako sešit programu Excelu, ve formátu
Pascal. Katedra aplikované kybernetiky. Ing. Miroslav Vavroušek. Verze 7
Pascal Katedra aplikované kybernetiky Ing. Miroslav Vavroušek Verze 7 Proměnné Proměnná uchovává nějakou informaci potřebnou pro práci programu. Má ve svém oboru platnosti unikátní jméno. (Připadne, musí
Relační DB struktury sloužící k optimalizaci dotazů - indexy, clustery, indexem organizované tabulky
Otázka 20 A7B36DBS Zadání... 1 Slovníček pojmů... 1 Relační DB struktury sloužící k optimalizaci dotazů - indexy, clustery, indexem organizované tabulky... 1 Zadání Relační DB struktury sloužící k optimalizaci
02. HODINA. 2.1 Typy souborů a objektů. 2.2 Ovládací prvky Label a TextBox
02. HODINA Obsah: 1. Typy souborů a objektů 2. Ovládací prvky Label a TextBox 3. Základní příkazy a vlastnosti ovládacích prvků 4. Práce s objekty (ovládací prvky a jejich vlastnosti) 2.1 Typy souborů
Čtvrtek 3. listopadu. Makra v Excelu. Obecná definice makra: Spouštění makra: Druhy maker, způsoby tvorby a jejich ukládání
Čtvrtek 3. listopadu Makra v Excelu Obecná definice makra: Podle definice je makro strukturovanou definicí jedné nebo několika akcí, které chceme, aby MS Excel vykonal jako odezvu na nějakou námi definovanou
0.1 Úvod do lineární algebry
Matematika KMI/PMATE 1 01 Úvod do lineární algebry 011 Lineární rovnice o 2 neznámých Definice 011 Lineární rovnice o dvou neznámých x, y je rovnice, která může být vyjádřena ve tvaru ax + by = c, kde
0.1 Úvod do lineární algebry
Matematika KMI/PMATE 1 01 Úvod do lineární algebry 011 Vektory Definice 011 Vektorem aritmetického prostorur n budeme rozumět uspořádanou n-tici reálných čísel x 1, x 2,, x n Definice 012 Definice sčítání
příkladů do cvičení. V textu se objeví i pár detailů, které jsem nestihl (na které jsem zapomněl) a(b u) = (ab) u, u + ( u) = 0 = ( u) + u.
Několik řešených příkladů do Matematiky Vektory V tomto textu je spočteno několik ukázkových příkladů které vám snad pomohou při řešení příkladů do cvičení. V textu se objeví i pár detailů které jsem nestihl
Programování v C++ 3, 3. cvičení
Programování v C++ 3, 3. cvičení úvod do objektově orientovaného programování 1 1 Fakulta jaderná a fyzikálně inženýrská České vysoké učení technické v Praze Zimní semestr 2018/2019 Přehled Dokončení spojového
Operační systémy 2: Zápočtové úkoly
Operační systémy 2: Zápočtové úkoly 18. listopad 2010 1 Paralelní Mergesort Implementujte paralelní verzi algoritmu Merge sort, který bude řadit celá čísla uložená v textovém souboru. Program bude mít
Semestrální práce 2 znakový strom
Semestrální práce 2 znakový strom Ondřej Petržilka Datový model BlockFileRecord Bázová abstraktní třída pro záznam ukládaný do blokového souboru RhymeRecord Konkrétní třída záznamu ukládaného do blokového
Základy 3D modelování a animace v CGI systémech Cinema 4D C4D
EVROPSKÝ SOCIÁLNÍ FOND Základy 3D modelování a animace v CGI systémech Cinema 4D C4D PRAHA & EU INVESTUJEME DO VAŠÍ BUDOUCNOSTI Mgr. David Frýbert 2013 CGI systémy Computer - generated imagery - aplikace
2D transformací. červen Odvození transformačního klíče vybraných 2D transformací Metody vyrovnání... 2
Výpočet transformačních koeficinetů vybraných 2D transformací Jan Ježek červen 2008 Obsah Odvození transformačního klíče vybraných 2D transformací 2 Meto vyrovnání 2 2 Obecné vyjádření lineárních 2D transformací
Algoritmus pro hledání nejkratší cesty orientovaným grafem
1.1 Úvod Algoritmus pro hledání nejkratší cesty orientovaným grafem Naprogramoval jsem v Matlabu funkci, která dokáže určit nejkratší cestu v orientovaném grafu mezi libovolnými dvěma vrcholy. Nastudoval
Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody
Pokročilé programování v jazyce C pro chemiky (C3220) Operátory new a delete, virtuální metody Dynamická alokace paměti Jazyky C a C++ poskytují programu možnost vyžádat si část volné operační paměti pro
Profilová část maturitní zkoušky 2013/2014
Střední průmyslová škola, Přerov, Havlíčkova 2 751 52 Přerov Profilová část maturitní zkoušky 2013/2014 TEMATICKÉ OKRUHY A HODNOTÍCÍ KRITÉRIA Studijní obor: 78-42-M/01 Technické lyceum Předmět: TECHNIKA
5.2.3 Duté zrcadlo I. Předpoklady: 5201, 5202
5.2.3 Duté zrcadlo I Předpoklady: 5201, 5202 Dva druhy dutých zrcadel: kulové = odrazivá plocha zrcadla je částí kulové plochy snazší výroba, ale horší zobrazení (aby se zobrazovalo přesně, musíme použít
Odvození středové rovnice kružnice se středem S [m; n] a o poloměru r. Bod X ležící na kružnici má souřadnice [x; y].
Konzultace č. 6: Rovnice kružnice, poloha přímky a kružnice Literatura: Matematika pro gymnázia: Analytická geometrie, kap. 5.1 a 5. Sbírka úloh z matematiky pro SOŠ a studijní obory SOU. část, kap. 6.1
( ) ( ) ( ) ( ) Skalární součin II. Předpoklady: 7207
78 Skalární součin II Předpoklady: 707 Pedagogická poznámka: Hodina má tři části, považuji tu prostřední za nejméně důležitou a proto v případě potřeby omezuji hlavně ji Na začátku hodiny je důležité nechat
5. Lokální, vázané a globální extrémy
5 Lokální, vázané a globální extrémy Studijní text Lokální extrémy 5 Lokální, vázané a globální extrémy Definice 51 Řekneme, že f : R n R má v bodě a Df: 1 lokální maximum, když Ka, δ Df tak, že x Ka,
Úvod do programování 7. hodina
Úvod do programování 7. hodina RNDr. Jan Lánský, Ph.D. Katedra informatiky a matematiky Fakulta ekonomických studií Vysoká škola finanční a správní 2015 Umíme z minulé hodiny Syntax Znaky Vlastní implementace
Kontingenční tabulky v MS Excel 2010
Kontingenční tabulky v MS Excel 2010 Autor: RNDr. Milan Myšák e-mail: milan.mysak@konero.cz Obsah 1 Vytvoření KT... 3 1.1 Data pro KT... 3 1.2 Tvorba KT... 3 2 Tvorba KT z dalších zdrojů dat... 5 2.1 Data