PŘÍRODOVĚDECKÁ FAKULTA UNIVERZITY PALACKÉHO KATEDRA INFORMATIKY DIPLOMOVÁ PRÁCE. Optimalizace vykreslování voxelové grafiky Bc.

Rozměr: px
Začít zobrazení ze stránky:

Download "PŘÍRODOVĚDECKÁ FAKULTA UNIVERZITY PALACKÉHO KATEDRA INFORMATIKY DIPLOMOVÁ PRÁCE. Optimalizace vykreslování voxelové grafiky. 2013 Bc."

Transkript

1 PŘÍRODOVĚDECKÁ FAKULTA UNIVERZITY PALACKÉHO KATEDRA INFORMATIKY DIPLOMOVÁ PRÁCE Optimalizace vykreslování voxelové grafiky 2013 Bc. Pavel Procházka

2 Anotace Voxelová grafika je zobecněním rasterové grafiky do třetí dimenze, představuje tak alternativu k častěji používané polygonové grafice. Voxelová grafika přináší výhody v podobě teorericky vysoké obrazové kvality, avšak za cenu vysoké paměťové a časové náročnosti. Existují však dobré komprimační metody, které dokážou značně zredukovat velikost běžných modelů a čas nutný pro jejich vykreslení. K tomuto účelu se nejčastěji používá metoda dělení prostoru, známá jako oktalový strom octree a jeho varianty. Text srovnává několik metod z hlediska výkonu i obrazové kvality za použití softwarového vykreslování. Dalším výstupem je řádně napsaná programová knihovna VoXen, která umožňuje vykreslování různých voxelových formátů s použitím jednoduchého nasvětlování.

3 Poděkování patří zejména mému vedoucímu práce panu Mgr. Eduardu Bartlovi, Ph.D., který mně aktivně a profesionálně pomáhal při řešení problémů, s výběrem vhodné literatury a s opatřením dat. Dále děkuji pracovníkům nemocnice U svaté Anny v Brně za pořízení a poskytnutí dat z magnetické rezonance, jmenovitě zejména paní Janě Nahodilové. Konečně také děkuji své rodině za podporu, která mi byla projevována.

4 Obsah 1. Úvod 8 2. Polygonová grafika Metoda rasterizace Metody sledování paprsku Voxelová grafika Rasterizace DDA a Bresenhamův algoritmus Raytracing Způsoby reprezentace voxelových modelů Naivní raw kódování Run-length kódování a.vxl formát Oktalový strom octree Operace v octree Test optimality a optimalizace octree Vyplňování oblasti Odebrání prvku Rychlá kompilace a voxelový blitting Techniky adresace a procházení octree Algoritmus kd-restart Algoritmus kd-backtrack Algoritmus kd-shortstack Neighbor search Procházení octree podél přímky N 3 strom Vlastní optimalizační úvahy adaptive octree Knihovna VoXen Architektura Systém souřadnic Elementární datové typy Objektový systém VoXen Rozhraní obrazového povrchu Objekt ovladače a proces inicializace Matice transformace Rozhraní obecného modelu Kamera a generátor paprsků Implementace raw formátu Implementace octree formátu

5 Sestavení octree Cube clipping algoritmus vlastní myšlenky Algoritmy procházení octree Nasvětlování a stínování Poznámky k optimalizacím softwarového vykreslování Akcelerující techniky Vícevláknové vykonávání Dosažené výsledky Sada testů knihovny VoXen Testovací aplikace Konverzní utilita Poznámky ke kompilaci a ke kompatibilitě Testování, spuštění a známé chyby Dokumentace knihovny VoXen Licence a kopírování Obrazové podklady Srovnání Srovnání paměťové náročnosti Srovnání časové náročnosti Srovnání obrazové kvality Diskuze Srovnání s jinými projekty Možnosti využití dosažených výsledků Možnosti dalšího rozšíření knihovny VoXen Omezení knihovny Závěr 64 Conclusions 65 Reference 66 A. Obsah přiloženého DVD 67 5

6 Seznam obrázků 1. Princip raytracingu (pohled z boku) Organizace souřadnic v knihovně VoXen Mapování indexů na potomky octree Obrázek získaný z magnetické rezonance Vykreslený model hlavy Model z testovací aplikace knihovny VOXLAP (od Kena Silvermana) Pohled na mapu ze hry Voxelstein Jednoduchý testovací model Rozdíl v kvalitě raycastingu mezi syrovým modelem (velvo) a octree modelem (vpravo) Obrazový výstup ze článku GigaVoxels Obrazový výstup z práce Kristofa Römische

7 Seznam tabulek 1. Tabulka srování velikosti souborů podle modelů Tabulka kompresního poměru Tabulka srování počtu všech uzlů octree s počtem listových uzlů Tabulka srování průměrných FPS v softwarové implementaci vzhledem k různým algoritmům a pouze s ambientním osvětlením Tabulka průměrných hodnot FPS s jedním dynamickým světlem Tabulka nejhorších a nejlepších časových výsledků (v milisekundách), údaje jsou bez dynamických světel

8 1. Úvod Existuje několik hlavních způsobů reprezentace třídimenzionálního světa, jak ho známe, ovšem jen málokterá reprezentace je tak blízko skutečnosti jako právě reprezentace voxelová. Z toho plynou četné výhody v oblasti zpracování výstupů z výpočetní tomografie, ve strojírenských oborech a také v počítačových hrách. Ve všech těchto oblastech jsou zvýšené nároky na výkon, konkrétně je velmi vhodné, aby se výstup zobrazoval v reálném čase. Na první pohled se může zdát, že zobecnění rastrové grafiky do 3D je ta nejpřímější a také nejvíce duchaprostá varianta. Ihned je patrné, že jakékoliv operace nad voxelovými modely budou extrémně náročné, nehledě na spotřebu paměti. S pomocí jistých optimalizačních technik se však lze dostat na velmi přijatelnou časovou i paměťovou složitost a zajistit tak solidní rychlost vykreslování. Výhodou voxelového vykreslování pak jistě může být velmi vysoká kvalita výstupu a skutečná hloubka, ale také velký potenciál v podobě neomezené úrovně detailů. Nevýhoda voxelové grafiky, zejména oproti polygonové, spočívá v manipulaci s objekty, především jde o animace a afinní transformace. Obecně lze říci, že nevýhody a výhody jsou úplně stejné jako u analogických reprezentací ve 2D. Voxelové modely lze reprezentovat různými způsoby. Nejsnadněji lze voxelový model reprezentovat trojrozměrnou maticí, což je ale současně nejvíce naivní způsob reprezentace, neboť paměťová náročnost zjevně přímo roste s třetí mocninou. Tento formát může být výstupem některých přístrojů pro snímání trojrozměrných objektů. Analogicky k rastrové grafice, lze i voxelové modely komprimovat metodou run-length, která je založena na přeskakování delších úseků stejné barvy. Zcela jiný přístup představuje reprezentace pomocí oktalového stromu, ten umožňuje efektivní procházení, ale za jistých okolností i nižší využití paměti. Jeho optimalizovanou variantou je pak N 3 strom, který dosahuje vyššího výkonu nebo lepšího kompresního poměru v závislosti na volbě programátora. Otázkou však zůstává, jakým způsobem vykreslovat modely. V případě voxelových formátu je nejefektivnější použít raycasting, případně raytracing, přímá rasterizace by vyžadovala zcela jinou reprezentaci. I když i přímá rasterizace se ve výjimečných případech používá. Nejdůležitějším výstupem mé práce je obecná knihovna VoXen, která implementuje některé modely a metody vykreslování. A to jak pomocí softwarového vykreslování, tak výhledově i za použití GPGPU výpočtů na platformě OpenCL. Současně je nad touto knihovnou napsán program pro testování funkcionality ale také výkonu, dále sada testů a konverzní utilita. Knihovna je napsána s ohledem na vysoký požadovaný výkon v jazyce C99, jako zobrazovací knihovna je použita SDL, případně lze dopsat vlastní backend nebo využít přímou rasterizaci do syrového pole pomocí NULLDrv ovladače. Zejména v softwarové části knihovny je použito mnoho zajímavých optimalizačních technik včetně využití vícevláknového vykonávání. První část práce se zabývá teorií a metodami zobrazování grafiky obecně. Ať 8

9 už je to metoda založená na rasterizaci nebo metoda trasování paprsku. Jsou zde shrnuty výhody a nevýhody obou přístupů s ohledem na rychlost, spotřebu paměti, ale také obrazovou kvalitu výstupů. Čtenář se zde dozví základní pojmy, které jsou nezbytné zejména pro pochopení metody trasování paprsku a pojmy související s 2D rastrovou grafikou. Následují kapitoly, které se zabývají metodami ukládání voxelových dat a operacemi nad takovými modely, zde je vždy uvedena zejména časová i paměťová složitost a porovnání jejich reálného výkonu vzhledem k typickým vstupním datům. Následně shrnuji nevýhody metod dělení prostoru a v hrubých obrysech navrhuji vlastní optimalizační techniku (adaptive octree), která nezhorší paměťovou složitost a zlepší složitost časovou. Dál se text zabývá implementací knihovny VoXen, což je jedna ze ztěžejních částí mé práce. Zde je pouze přehledově zmíněno API knihovny a její pseudo-objektový systém, hlavní důraz je kladen zejména na optimalizační detaily, které tato knihovna obsahuje. Nad knihovnou VoXen jsou pak napsány tři doprovodné programy, které mohou sloužit jako rozsáhlejší tutoriálové příklady, zejména konverzní utilita má však také praktické využití. Závěrem je uvedeno shrnutí výkonu jednotlivých modelů při softwarovém vykreslování a při GPGPU vykreslování. Dále uvádím srovnání kvality obrazových výstupů a doplňuji možnosti využití knihovny, jakož i její případná omezení. Nakonec je v diskuzi má implementace srovnána s jinými podobnými prácemi a výsledky. Pro orientaci v tomto textu je nezbytná alespoň orientační znalost rastrové grafiky na úrovni porozumění pojmu pixel, barevná hloubka, barvová paleta, aliasing, mipmapping apod. 9

10 2. Polygonová grafika Počítačová trojrozměrná grafika se začala široce studovat v 60. letech v Utahu, kde byly položeny základy dnešních běžně používaných metod pro rychlé zobrazování polygonové grafiky. Jako jsou metody vykreslování přímek, kružnic nebo vyplňování mnohoúhelníků. Základním objektem polygonové grafiky je mnohoúhelník, jehož všechny vrcholy leží v jedné rovině. V počítačové grafice se však nejčastěji používá trojúhelník, případně čtyřúhelník. Důvodem je hlavně harwarová podpora. Polygonová grafika je někdy označována jako povrchová (hraniční) reprezentace. Neumožňuje totiž zachytit vnitřek objektů narozdíl od voxelové grafiky. K promítání na obrazový výstup se nejčastěji používá tzv. perspektivní zkreslení, což je jev, který intuitivně velmi dobře známe. Perspektivní zkreslení, neformálně řečeno, vyjeví vzdálenější objekty menší, než objekty bližší. Existuje několik formalizmů, které tento jev popisují, text se jedním podrobně zabývá v kapitole o metodě trasování paprsků na voxelových modelech Metoda rasterizace Jedná se v současnosti o nejpoužívanější a současně hardwarově podporovanou metodu zobrazování 3D polygonové grafiky, tudíž může být velmi rychlá. Příkladem softwarových knihoven, které ji využívají je OpenGL a DirectX. Principielně se tento přístup skládá z několika problémů, které se jako celek nazývají grafická pipeline. Hlavními úkoly grafické pipeline jsou tyto po sobě jdoucí úkoly [4]: transformace, ořezání, scan konverze. V prvním kroku se vypočítá perspektivní zkreslení všech viditelných polygonů jejich vrcholů. Poté dojde k ořezání polygonů, které zasahují mimo obrazovku mimo tzv. ořezávací pyramidu. Zde je třeba řešit patrně výpočetně nejnáročnější problém, tím je určení viditelných polygonů tzv. visibility problem. Hledáme tedy ty polygony, které jsou pro pozorovatele viditelné. Nejjednodušším, ale také současně nejpomalejším algoritmem je tzv. malířův algoritmus, který kreslí polygony odzadu, vzhledem k pozorovateli (kameře). Malířův algoritmus má zjevně lineární časovou složitost vzhledem k počtu polygonů, na počátku je ovšem ještě třeba setřídit objekty podle vzdálenosti od kamery, což lze docílit pomocí známých třídících algoritmů, které pracují nejlépe v čase O(nlog(n)). Jisté vylepšení co do počtu překreslených pixelů, nikoli však navštívených polygonů, je tzv. Z- buffer. Z-buffer je jednoduché obrazové pole, které odpovídá velikosti obrazovky a nese informaci o vzdálenosti posledního vykresleného pixelu, na začátku je vyplněno hodnotami. Při pokusu o vykreslení polygonu se navíc testuje, zda je 10

11 právě vykreslovaný pixel blíže pozorovateli. Pokud není, nic se nevykreslí. Použitím Z-bufferu se navíc eliminuje nutnost setřídění polygonů podle vzdálenosti vzhledem ke kameře, což je podstatný přínos, pokud se kamera pohybuje. K rychlejšímu nalezení nejbližších polygonů se používá například BSP-strom, případně jiné strukutry dělící prostor (kd-stromy, R-stromy, octree). K tomu, abychom polygon vykreslili, navíc potřebujeme algoritmus na vyplňování polygonů barvou, případně texturou obrázkem. Těmito algoritmy se text podrobněji nezabývá. Implementací předchozích algoritmů vykreslíme pouze nepřirozeně vypadající modely vlivem chybějícího osvětlení. Rozlišujeme několik základních technik nasvětlování. Nejpřirozenější je zřejmě tzv. flat shading ploché stínování. Intenzita stínu je pak vypočtena na základě odchylky normálového vektoru polygonu od světelného paprsku. Čím větší odchylka je, tím je polygon temnější. Výsledkem plochého stínování jsou jasně patrné hrany polygonů, tento nedostatek částečně řeší Goraudovo stínování nebo relativně výpočetně náročné Phongovo stínování. Tyto metody osvětlování však řeší pouze osvětlení, ale nikoli stíny vržené jinými objekty, které jsou k reálnému pocitu z 3D scény nezbytné. První metodou je metoda přímého nasvětlování direct illumination, která počítá s paprsky jdoucí přímo ze zdroje světla. Druhá, výpočetně náročná metoda, je metoda globálního nastvětlování global illumination, která počítá s odrazy paprsků. Detaily konkrétních implementací nejsou pro pochopení textu ztěžejní. Další technikou ještě zlepšující vizuální dojem se nazývá radiozita. Radiozita pracuje s myšlenkou vyzařování světla ve směru od nasvícených objektů do prostoru. Toto je intuitivně dobře známý jev, který je dobře patrný zejména u matných předmětů. Moderní grafické karty jsou již osazeny plnohodnotnými výpočetními jednotkami GPU, které spadají do klasifikace SIMD. Grafické karty umožňují díky svému obecnému návrhu programovat další grafické efekty s využitím masivní paralelizace. Současné grafické karty spadající do nejvyššího segmentu jsou osazeny řádově 10 3 výpočetními jádry. V počítačové grafice se často objevuje pojem shader. Shader je krátký program, který se paralelně spouští na GPU a umožňuje tak uživatelsky programovat grafickou pipeline. Podle určení se rozlišují různé typy shaderů. Na úrovni polygonového modelu jsou to vertex shadery, což jsou jednoduché programy transformující všechny body scény například simulace vln na vodě. Vylepšením vertex shaderů jsou geometry shadery, které navíc umí přidávat nebo odebírat polygony ze scény, často se tak vytváří třeba travnatý povrch, nebo naopak mohou redukovat počet vzdálenějších polygonů. Pixel (fragment) shadery naopak transformují jednotlivé výstupní body výsledného obrazu. Lze jimi docílit například efektu šumu, ale často se pomocí pixel shaderů implementuje velká část rasterizačního procesu, včetně efektů jako je třeba bump mapping (dojem hloubky díky zvláštnímu nanesení textury). Pomocí fragment shaderů lze také implementovat raytracing [9]. Aktuální etapou vývoje grafických karet je cesta k univerzální programovatelnosti. V současnosti existují tři softwarová prostředí, která to až na jistá omezení 11

12 umožňují. Jedná se o CUDA, DirectCompute a OpenCL. CUDA i DirectCompute jsou prostředí vyvíjená firmou NVIDIA resp. Microsoft, což je omezující. Naopak OpenCL je prostředí nezávislé na výrobci, každý výrobce může vyvíjet svoji implementaci standardu OpenCL pro své zařízení. Díky tomu může být OpenCL provozováno na grafických kartách, výpočetních kartách i na běžných procesorech. Hlavní omezení těchto technologií je fakt, že nelze definovat rekurzivní funkce a nelze pracovat s ukazately na funkce (to již neplatí pro technologii CUDA provozovanou na grafických kartách řady Fermi) Metody sledování paprsku Implementace metody sledování paprsku je z algoritmického hlediska oproti rasterizaci výrazně elegantnější, nicméně málo výkonná. Princip sledování paprsku ray tracing vychází z fyzikálního principu šíření světla, jen je tento proces obrácený. Paprsek se totiž nevysílá ze zdrojů světla, nýbrž z kamery. Tím se docílí výrazné úspory počtu paprsků při zachování stejné kvality. Program implementující ray tracing vysílá paprsek z ohniska kamery přes obrazovku dále do scény [4]. Jakmile paprsek narazí na povrch nějakého polygonu, buď skončí pak se jedná o ray casting, anebo vyšle další paprsky ke každému zdroji světla, případně může raytracing implementovat další optické zákony, jako je zákon lomu nebo odrazu pro různé materiály. Velkou výhodou je také možnost efektivní paralelizace a to i na grafických kartách. 3. Voxelová grafika Pixel si obvykle představujeme jako čtverec vyplněný stejnou barvou nebo jako bod na monitoru [4]. Formálněji se na něj lze dívat jako na nejmenší adresovatelný prvek rastru. V případě přirozených obrazů (fotografií) se na něj díváme jako na jistou diskrétní interpretaci jinak spojitého obrazu[11]. Velmi podobně se díváme i na pojem voxel, pouze s tím rozdílem, že představuje trojrozměrnou krychli v prostoru. Cílem vykreslování by měla být schopnost pracovat v reálném čase, to jest přibližně 25 snímků za sekundu (FPS). Pro vykreslování voxelové grafiky je třeba navrhnout interpretaci, která bude mít co možná nejnižší nároky na paměťové zdroje v řídkých modelech, nebo lépe ve všech modelech. Pojem řídkého modelu bohužel žádný dostupný zdroj formálně nedefinuje, jeho interpretace tak vychází z intuice. Řídké modely splňují tu vlastnost, že obsahují rozsáhlé prázdné oblasti nebo rozsáhlé oblasti stejné barvy. Současně však musí být možné rychle adresovat voxely modelu a maximálně využít řídké povahy modelů k rychlému přeskakování prázdných oblastí. Navíc by model měl umožňovat předcházet aliasingu obrazu, aniž by to mělo nežádoucí dopad na výkon. Formálně lze dvojdimenzionální obraz považovat za zobrazení I : R R 0, 1, na výpočetních strojích je však možné reprezentovat pouze diskrétní mno- 12

13 žiny. Tudíž se prakticky obraz uvažuje jako zobrazení I : Z w Z h Z 256 3, který může být získán diskretizací ze spojité předlohy (například fotoaparátem). Analogicky můžeme zavést i trojrozměrný obraz R R R 0, 1, respektive Z w Z h Z d Z pro nějaká w, d, h N, kde w je šířka obrazu, h je výška a d je hloubka. Pixel je pak výraz I(x, y) pro jeden bod x, y, obdobně i voxel. Poznamenejme, že množina Z představuje prostor všech true-color barev tak, jak se v počítačové rastrové grafice běžně používají Rasterizace Jednou z možností, jak vykreslit voxely, je možnost reprezentovat je jako jednotkové krychle sestavené z polygonů. A poté je zobrazit nějakým běžným rasterizačním softwarem typu OpenGL. To je však nemožné pro velké objekty. Reprezentujeme-li voxely pomocí trojúhelníků, dostáváme 12 trojúhelníků na voxel. Což i pro malé modely ( ) činí řádově 10 6 trojúhelníků a to je pro rasterizační metody příliš. Tento způsob se používá v případech, pokud chceme zobrazovat voxelová data extrémně přiblížená, jako je tomu například ve hře Minecraft v tomto případě se navíc na povrch voxelů nanáší textura DDA a Bresenhamův algoritmus DDA (Digital differential analyzer) je scan-conversion algoritmus pro vykreslení přímky do mřížky. Jinými slovy se jedná o lineární interpolaci na jistém intervalu. DDA princip je klíčový pro metody sledování paprsku ve voxelových modelech, což jsou třírozměrné mřížky. Vstupem DDA algoritmu jsou dva body. Počáteční bod A = x 1, y 1 a koncový bod B = x n, y m. Pro každé x i, které splňuje x 1 < x i <= x n spočítáme hodnoty x i, y i takto kde hodnota s vzniká výrazem x i = x i s y i = y i 1 + s, s = y m y 1 x n x 1. Hodnoty x i a y i reprezentují pozice pixelů. Na první pohled nelze pomocí takto zapsané posloupnosti vykreslit svislou přímku, protože nelze dělit nulou. To lze vyřešit buď předefinováním výrazu s = y m y 1 0 na s = 1 a předefinováním výrazu 1 na hodnotu 0. Anebo v dané implementaci s nejprve porovnat hodnoty y m y 1 a x n x 1. Řídící osou se pak stane ta osa, 13

14 ve které nabývají tyto výrazy y m y 1 a x n x 1 vyšší hodnotu. V případě, že to bude osa y zvolíme výraz s = x n x 1. y m y 1 Samotný algoritmus však nepočítá obě hodnoty, ale pouze jednu. To, kterou hodnotu bude algoritmus počítat, se rozhodne na základě hodnoty s. V případě, že platí s <= 1 nastavíme krok dx = 1 a x i budeme počítat x i = x i 1 + dx a y i = y i 1 + s. V případě s > 1 klademe dy = 1, y i = y i 1 + dy a x i = x i s V konkrétní implementaci je pak třeba ještě řešit problém se záporným sklonem, který lze elegantně vyřešit například prohozením koncové a počáteční souřadnice nebo výpočtem znaménka. DDA <- function( A = <x1, y1>, B = <x2, y2> ){ dx = x2 - x1; dy = y2 - y1; if( dx!= 0 && (s = dy/dx) <= 1.0 ){ dx = (dx > 0.0? 1.0 : -1.0); y = y1 for( x = x1 ; x <= x2 ; x += dx ){ draw_point( x, y ); y += s; else { dy = (dy > 0.0? 1.0 : -1.0); s = dx/dy; for( y = y1 ; y <= y2 ; y += dy ){ draw_point( x, y ); x += s; Algoritmus DDA je zejména vhodný pro harwarovou implementaci, lze totiž dobře optimalizovat pro paralelní vykonávání, lze jej ale také implementovat pomocí celočíselné aritmetiky a techniky známé jako fixed point aritmetika. Z algoritmu DDA vychází Bresenhamův algoritmus, který je v současnosti široce implementován v grafických knihovnách a na grafických čipech pro svoji jednoduchost a eleganci. Bresenhamův algoritmus lze rovněž implementovat pomocí celočíselné aritmetiky, ale obvykleji se využívá floating point implementace. Principem floating point verze je spočítání sklonu v obou směrech a následné přičítání sklonu k příslušným složkám. 14

15 Bresenham <- function( A = <x1, y1>, B = <x2, y2> ){ x = x1; y = y1; xlen = x1 - x2; ylen = y1 - y2; len = abs((abs(ylen) > abs(xlen)? ylen : xlen)); stepx = xlen / len; stepy = ylen / len; for( i = 0 ; i < len ; i++ ){ draw_point( x, y ); x -= stepx; y -= stepy; 3.3. Raytracing Metody trasování paprsku jsou mnohem přímočařejší, než rasterizační metody. Navíc do značné míry odpovídají skutečnému fyzikálnímu modelu šíření světla, což má také pozitivní vliv na vzhled výsledných scén. Někdy se dokonce metody trasování paprsku označují (nesprávně) jako fotorealistické zobrazování. Sledování paprsku vychází z fyzikálního pojetí světla. Respektive vychází z představy světla jako částice, zanedbává však vlnovou podstatu světla. Tím pádem však nemůžeme tuto metodu považovat za fotorealistickou, neboť v současné fyzice existuje jistý rozpor mezi částicovým pojetím světla a vlnovým pojetím. Některé jevy totiž fyzika umí vysvětlit pouze pomocí částicové teorie (fotoelektrický jev), jiné zase pouze pomocí vlnové teorie (Youngův dvojštěrbinový experiment). Na světlo jako na částice se dívali již starověcí řečtí myslitelé pocházející z Pythagorejské školy. Skutečný formalizmus pohledu na světlo jako částici přinesl až Albert Einstein a Max Planck v první polovině 20. století. Z pohledu částicové teorie je světlo pouze diskrétní tok fotonů, které jsou emitovány oscilujícími ionty (zdroj světla) a šíří se po přímce, zanedbáme-li jev zakřivení světla vlivem gravitace. Samotný obrazový vjem je pak ta část fotonů, která dorazí do oka pozorovatele nebo do kamery. Fotonů, které ovšem dorazí až k pozorovateli je jen zanedbatelný zlomek z celkového počtu fotonů ve scéně. Princip sledování paprsku tento jev obrací a trasuje fotony od pozorovatele směrem do scény a následně ke zdrojům světla tak, jak to ukazuje obrázek 1. Z algoritmického hlediska je zapotřebí mechanizmus zvaný generátor paprsků, který bude vysílat paprsky z kamery do scény. Nejčastějším generátorem paprsků je princip vycházející z perspektivního promítání, jehož hlavní myšlenkou je podobnost trojúhelníků. Jeden vrchol trojúhelníka tvoří ohnisko kamery a zbylé dva jsou počáteční a koncový bod obrazovky buď na ose x nebo y. Vzdálenost d 15

16 Zdroj sv tla Ohnisko Projek ní rovina Objekt scény Obrázek 1. Princip raytracingu (pohled z boku). ohniska od roviny obrazovky se obvykle klade d = x max x min. 2 Poloha ohniska se pak klade f = d, y max y min, 0. 2 Obvyklé hodnoty x min a y min jsou 0. Poznamenejme, že hodnota x min, x max je minimální x souřadnice, respektive maximální x souřadnice obrazovky, stejná konvence platí pro osu y, navíc uvažujeme souřadný systém, kde osa z ubíhá dále od pozorovatele (konvence levé ruky). Samotný generátor paprsků perspektivního promítání je zobrazení Rg : N N R R R tak, že Rg(x, y) = x, y, d f. Někdy je výhodné generované paprsky normalizovat Rg(x, y) Rg(x, y). Případně se k nim přičítá vektor 1 2, 1 2, 0, aby se zajistilo, že procházejí středem pixelu. Generátor paprsků je však obecný princip, tudíž lze toto zobrazení definovat i jiným způsobem. Například jím lze docílit efektu rybího oka, případně lze jiným způsobem deformovat obraz (efekt rychlé jízdy). Nejjednodušším příkladem promítání je pak pravoúhlé promítání, tehdy bude zobrazení Rg(x, y) = 0, 0, 1, ale ohnisko pak nebude jedno a bude ležet na rovině kamery. Výstupy generátoru paprsků trojrozměrné vektory je pak nutné ještě vynásobit transformační maticí, kterou může definovat uživatel. Obvykle však slouží k rotaci kamery. Pak následuje trasování takto získaných vektorů z počátečního bodu kamery, který může být libovolně umístěn do scény. Algoritmus trasování paprsku lze obecně shrnout do následujícího pseudo-kódu, který byl inspirován zdrojem [4]. draw_camera <- function( camera ){ 16

17 for( y <- 0 ; y <- y_max ; y++ ){ for( x <- 0 ; x <- x_max ; x++ ){ ray <- Rg( x, y ); ray <- ray * camera.matrix; color <- do_ray( camera.position, ray )[1]; set_pixel( x, y, color ); do_ray <- function( pos = <x, y, z>, ray = <xr, yr, zr> ){ min_distance <- INFINITY; intersection <- NIL; out_object <- NIL; /* nelezení nejbližšího průniku s objektem */ foreach( object in scene ){ intersection <- object.intersect( pos, ray ); if( intersection ){ dist <- vector_length( intersection - pos ); if( min_distance > dist ){ min_distance <- dist; out_object <- object; if(!object ){ return <NIL, FILLING_COLOR>; if( object.type == LIGHT ){ return <object, object.color>; /* uživatelsky definované sekundární paprsky */ secondary_rays <- object.emit_secondary_rays( intersection ); scolor <- 0 foreach( ray in secondary_rays ){ scolor <- add_color( scolor, do_ray( intersection, ray )[1]); 17

18 /* vyšle paprsky ke všem zdrojům světla */ lcolor <- 0 foreach( light in camera.lights ){ out <- do_ray( intersection, light.position - pos ) if( out[0].type == LIGHT ){ lcolor <- add_color( color, out[1] ); color <- mul_color( object.color, scolor, lcolor ); return <object, color>; Funkce draw_camera vysílá pro všechny body kamery paprsky do scény a před tím je transformuje maticí. Výsledek trasovací funkce do_ray pak zapíše do framebufferu. Funkce do_ray pak provádí samotné trasování. Nejprve nalezne průsečík s nejvýše jedním objektem (v případě voxelové grafiky je každý objekt krychle) a paprskem tak, aby průsečík ležel nejblíže kameře ze všech jiných průsečíků. V případě, že průsečík nenalezne žádný, tato funkce vrátí smluvenou barvu FILLING_COLOR, obvykle je to černá. Poznamenejme, že každý objekt musí nést funkci intersect, která vrací průsečík paprsku a daného objektu. Objekt může být například krychle, polygon, koule a další, pokud se nejedná o voxelovou grafiku. V případě, že takto nalezený objekt je typu LIGHT, vrací se ihned jeho barva. V opačném případě se vyšlou sekundární paprsky dále směrem do scény a jejich výsledky se nakonec sečtou po složkách s barvou objektu. Sekundární paprsky jsou generovány v pseudo-kódu uživatelskou funkcí emit_secondary_rays, která může například implementovat ohyb nebo odraz světla v závislosti na materiálu. Nakonec se vyšlou paprsky směrem ke zdrojům světla, pokud ke světlu dorazí smíchá se barva světla s barvou objektu. Výsledná barva se pak vrací do vykreslování kamery. Často se navíc ještě používá tzv. ambientní (rozptýlené světlo), které se smíchá se všemi barvami, které vznikly průsečíkem s nějakým objektem, tehdy však nikdy nedojde k vykreslení zcela černého stínu. V konkrétní implementaci by jistě také bylo vhodné opatřit každý paprsek váhou, která by měla vliv při mixování. Nejnáročnější částí algoritmu je zjevně první smyčka, která prochází všemi objekty ve scéně a provádí časově náročné výpočty průniku. K minimalizaci počtu procházených objektů a s tím spojených výpočtů průniků se používají techniky založené na nelineárních datových strukturách (R-tree, kd-tree, octree) nebo na metodě obalování objektů tzv. bounding boxy. Což jsou jednodušší modely než ty, které obalují. Tímto se docílí lacinějších testů průniků, zejména při použití metody tzv. slabů [8]. V případě voxelové grafiky stačí implementovat testování průsečíků s jednotkovými krychlemi, které jsou obvykle zarovnány do 18

19 souřadnicového systému. 4. Způsoby reprezentace voxelových modelů V současnosti existuje velmi málo standardních formátů pro reprezentaci voxelové grafiky, výjimku tvoří snad jen medicínský fromát DICOM, který ovšem nenese voxelové modely, nýbrž jen řezy zakódované pomocí několika vybraných rastrových komprimačních metod. Další de-facto standard pro voxelovou grafiku v počítačových hrách je vox a vxl formát, použitý v několika hrách postavených na enginech Kena Silvermana, tento formát však nese pouze informace o povrchu modelu. Další zdokumentovaný formát pochází z populární hry Minecraft, ten však má nepříjemná omezení na rozměry modelu. Zbylé formáty jsou obvykle ad-hoc nezdokumentovaná řešení. Přestože neexistuje mnoho zdokumentovaných formátů, existuje několik obecných reprezentací. Přirozeným cílem každého rozumného modelu, by měl být maximální ohled na spotřebu paměti a na rychlost procházení modelu podél přímky Naivní raw kódování Raw (syrové) kódování je pouze uložení jednotlivých voxelů do třírozměrné matice podobně, jako například 2D rastry ve formátu bmp. Z hlediska uložení na disku je nejefektivnější uložit voxely do jednorozměrného pole p délky w h d b bajtů, kde w je šířka, h výška, d hloubka modelu a b je počet bajtů na barvu. Adresace voxelu na souřadnici x, y, z je pak možná v konstantním čase přístupem do pole p: voxel(x, y, z) p((zhw + yw + x)b). V konkrétní implementaci se navíc přikládá hlavička s informacemi o modelu, jako je velikost, barevný formát, případně kontrolní součet. Barevné formáty lze použít stejné jako u běžné rastrové grafiky včetně podpory průhlednosti. Jednoduchou úvahou je zřejmé, že paměťová složitost takto zakódovaného modelu je O(N 3 ), kde N = max {w, h, d. Tato konvence je použita v celém textu. Navíc dolní asymptotický odhad je také kubický, tedy je z Ω(N 3 ). Mámeli tedy model velikosti v true-color (1 bajt na kanál) kvalitě, dostáváme 3GB velký model, což už je na hranici adresovatelnosti na 32-bitových hardwarových platformách. Obrazová kvalita však ani při takové velikosti není závratná, v současnosti považujeme rastry velikosti za málo kvalitní. Nevýhodou však není jen vysoká paměťová složitost, nýbrž i vysoký střední počet kroků při průchodu řídkých modelů. Naivní model lze zřejmě procházet podél přímky v lineárním čase pomocí DDA nebo Bresenhamova algoritmu, které však zhoršují vizuální kvalitu. Lepší je použít algoritmus procházení mřížky pro korektní výstupy [2]. V raw formátu se nelze snadno zbavit aliasingu tak, aby se 19

20 nezhoršila časová složitost procházení. Řídkost modelu nemá žádný pozitivní ani negativní vliv na výkon Run-length kódování a.vxl formát Princip run-length kódování spočívá v uložení stejně zbarvených voxelů jdoucích za sebou do jedné struktury, která nese informaci o počtu voxelů a této stejné barvě. V případě, že to není výhodné, ukládají se samostatné voxely, před ně se pak musí umístit informace kolik jich je. Ve voxelových modelech formátu.vxl se run-length princip aplikuje na sloupce hloubky. To znamená, že ukládá 2D obrázek, který nese místo informace o barvě první hlavičku run-length kódování (v implementaci.vxl je to číslo udávájící počet prázdných prvních voxelů). Tato metoda je vysoce účinná, v případě řídkých modelů. Naopak v modelu s náhodnými voxely je run-length metoda nevýhodná a vykazuje zápornou komprimaci. Nicméně paměťová složitost je stále v řádu O(N 3 ). V nejhorším případě, je potřeba uchovávat navíc informaci o nejednotnosti za sebou jdoucích barev. Toto však vede pouze ke zvýšení multiplikativní konstanty. Ve formátu.vxl je omezení na velikost modelu, to je Adresace voxelu v této metodě je zvlášť neúčinná, její časová složitost je O(N). Proto se tato reprezentace výhradně používá jako relativně úsporná reprezentace pro ukládání na pevný disk. Formát.vxl je použit v herním voxelovém enginu Voxlap, který napsal Ken Silverman tvůrce slavného Build enginu (Blood, Duke Nukem 3D, Shadow Warrior). Zde Ken Silverman přikládá pseudokód vycházející z jazyka C pro načítání formátu.vxl [13]. unsigned char * v = load_file(); for( int y = 0 ; y < 1024 ; y++ ){ for( int x = 0 ; x < 1024 ; x++ ){ int z = 0; while( 1 ){ for( int i = z; i <= v[1] ; i++ ){ m->set_voxel( m, x, y, i, 0x0 ); for( z = v[1] ; z <= v[2] ; z++ ){ VX_uint32 clr = *(VX_uint32*)&v[(z-v[1]+1) * 4]; m->set_voxel( m, x, y, z, clr ); if(!v[0] ){ break; 20

21 z = v[2] - v[1] - v[0] + 2; v += v[0]*4; for( z += v[3] ; z < v[3] ; z++ ){ VX_uint32 clr = *(VX_uint32*)&v[(z-v[3]) * 4]; m->set_voxel( m, x, y, z, clr ); v += ((VX_uint32)v[2] - (VX_uint32)v[1] + 2) * 4; 4.3. Oktalový strom octree Oktalový strom (octree) je rekurzivní stromová datová struktura založená na myšlence dělení prostoru skrze středový bod. Každý uzel představuje krychli v prostoru a má 8 potomků. Každý potomek rovnoměrně dělí tuto krychli na jednu osminu tak, že sjednocení všech potomků tvoří krychli rodiče. Listový uzel nemá potomky a nese informaci o barvě voxelu, velikost hrany krychle je pak větší nebo rovna hodnotě 1. Díky znalosti velikosti a polohy kořenové krychle už není nutné explicitně udržovat informace o poloze krychlí potomků, ty se totiž dají snadno zjistit i pomocí celočíselné aritmetiky, bez vlivu na výkon. Boundingbox celého octree má vždy velikost 2 h 2 h 2 h, kde h je výška zcela naplněného stromu, jinak by nešel octree podle definice sestavit. Pro octree stromy se budeme dále držet zavedené konvence, symbol N tedy bude znamenat velikost hrany octree. Vztah hodnot N a h je pak dán výrazem h = log 2 N. Výška octree stromu je O(log 2 N), paměťová složitost se však drží stále pod odhadem O(N 3 ). Argument pro to je jednoduchý, nejhorším případem octree je strom, který je zcela zaplněn. To znamená, že v každé úrovni l {0, 1,... má octree 8 l prvků. Celkový počet uzlů takového stromu je pak tedy log 2 N ze součtu prvních n prvků geometrické posloupnosti tedy plyne l=0 8 l 1 8 log 2 N prvků. Víme však, že 8 log 2 N = N 3 jelikož v poslední úrovni leží v plném stromu samé jednotkové listové uzly, tudíž 8N 3 1 O(N 3 ). Octree má také velkou výhodu ve snadném odstraňování aliasingu. V každém uzlu totiž lze dopředu spo- 7 čítat průměrnou barvu jeho potomků. Další velkou výhodou octree je teoreticky 21

22 nekonečná úroveň detailů, které se dá docílit pomocí techniky zvané instancing a rekurzivními odkazy, pomocí kterých lze implementovat například fraktály nebo definovat strukturu různých obecných materiálů (například kámen) s významnou úsporou paměti Operace v octree Jako každá rozumná datová struktura, tak i octree definuje základní operace pro manipulaci s daty uvnitř stromu Test optimality a optimalizace octree Oktalový strom můžeme nejsnadněji vytvořit tak, že vytvoříme tolik listových uzlů, kolik je ve voxelovém obrazu jednotkových voxelů a vybudujeme oktalový strom podle definice, ale tento strom bude plný. Taková struktura bude zjevně také splňovat definici oktalového stromu, nicméně nepřinese žádný benefit, ba naopak, povede k nižšímu výkonu, než podává běžný raw model, protože adresace bude stát přesně O(log 2 N), zatímco adresace v syrovém modelu je prováděna v konstantním čase, navíc nebude vykonávat žádné přeskočení prázdné oblasti. Abychom dostali octree do kýženého optimálního stavu, je potřeba v každém sestavení uzlu provést kontrolu, zda nelze všechny jeho potomky slít do jednoho. Slití potomků je možné buď tehdy, mají-li všichni potomci stejnou barvu a současně jsou-li to listy, anebo jsou-li všichni potomci prázdní. Aplikujeme-li tuto slévací proceduru post-order, dostaneme oktalový strom, který už nelze zlepšit. Protože, pokud by šel zlepšit beze ztráty informace, pak by musel existovat uzel, který podmínku nesplňuje, což ale není možné, protože po rekurzivní aplikaci slévání na všechny neoptimální uzly jsou již všechny optimální. optimal_p <- function( node ){ if( each( node->childs, function( child ){ return child == NULL; ) ) return EMPTY; if( each( node->childs, function( child ){ return (child->leaf_p && (child->color == node->childs[0]->color)); )) { return SAME; 22

23 return FALSE; optimize <- function( node ){ for( i = 0 ; i < 8 ; i++ ){ optimize( node->childs[i] ); switch( optimal_p( node ) ){ case SAME: node->color = node->childs[0]->color; memset( node->childs, NULL ); return node; break; case EMPTY: return NULL; break; default: return node; Vyplňování oblasti K vyplňení oblasti potřebujeme na vstupu informaci o kvádru v prostoru, označíme ho C = x 1, y 1, z 1, x 2, y 2, z 2 a barvu c z barvového prostoru modelu. Algoritmus pracuje rekurzivně. V každém uzlu se testuje, zda se vstupní oblast C překrývá s tímto uzlem. V případě, že celá oblast uzlu je obsažena ve vstupní oblasti C, pak uvolníme všechny následníky uzlu, nastavíme jej jako listový a nastavíme mu barvu c. V případě, že C oblast uzlu jen zčásti překrývá, pak průnik těchto dvou oblastí označíme C a rekurzivně sestupujeme do všech následníků a při návratu z nich se provede test optimality a případné slití. V případě, že oblast C nepřekrývá vůbec oblast uzlu, pak se pouze vrátí ukazatel na tento uzel. Tento algoritmus je pochopitelně funkční i pro vstupní oblasti velikosti Odebrání prvku Odebírání konkrétního prvku uzlu nemá v octree smysl, v případě nutnosti vymazat jistou oblast lze použít algoritmus pro vyplňování oblasti s průhlednou barvou na vstupu. 23

24 Rychlá kompilace a voxelový blitting Kompilací mám na mysli převod libovolného modelu na octree. Jedním přístupem je postupně procházet všechny pozice vstupního modelu a postupně je přidávat do octree. Tento přístup je však velmi neefektivní. Potom připadá v úvahu metoda zdola-nahoru, podobně jako při stavbě R-stromů, to však vyžaduje ještě o nějakou konstantu vyšší spotřebu paměti. Na začátku se totiž z každého jednotkového voxelu udělá uzel a vzniklé osmice se rekurzivně předávají nahoru a slévají. Tento přístup může být nejrychlejší, ovšem za cenu vyšší paměťové náročnosti, v prvním kroku je potřeba alespoň O(N 3 ) paměti, což opět může snadno narážet na limity adresace paměti. Poslední možností je kompilovat z vrchu dolů rekurzivním sestupem. Zde se postupuje až na nejmenší (jednotkové voxely), což je limitní podmínka rekurze. Jednotkové voxely vytvoří listové uzly, které jsou předány jako návratové hodnoty, při zpětném chodu rekurze se provede optimalizace. Paměťová složitost je zde evidentně svázána s velikostí zásobníku, který je v každé výpočetní větvi dlouhý nejvýše O(log 2 (N)) časová složitost kompilace je pak O(N 3 ), argument je pro to stejný jako při určování počtu uzlů v plném octree. Pojem blittingu má velký význam v rastrové grafice, stejně tak je rozumné ho zavádět i v grafice voxelové. Princip blittingu je jednoduché zkopírování oblasti jednoho obrazu do oblasti stejné velikosti jiného obrazu. Tato operace musí být velice rychlá, neboť se pracuje obvykle s velkými daty a používá se často k zobrazování animací v reálném čase už od dob prehistorie počítačů. V případě rastrové grafiky je tato operace již dlouhá léta hardwarově podporovaná na grafických čipech, zde se však vždy pracuje s obrazem v syrové podobě. V případě octree modelu pro relativně rychlý blitting je třeba skombinovat algoritmus pro kompilaci a vyplňování oblastí Techniky adresace a procházení octree Jelikož octree představuje obraz, musíme implementovat obrazové zobrazení I tak, aby dávalo stejné výsledky jako syrový model. V případě, že navíc chceme získat informaci o velikosti listové oblasti, musíme tuto informaci vracet také. Poslední otázkou zústává, jak uchovávat efektivně reference na potomky. Jednou z možností je uchovávat potomky v trojrozměrném poli, což je ale maximálně neefektivní, vzhledem k režii vícerozměrných polí. Jednoduchou úvahou však lze dospět k lineární interpretaci trojrozměrného pole o osmi prvcích. V mé implementaci se používá mapování definované jako bijektivní zobrazení GetChild : {0, 1 {0, 1 {0, 1 {0,..., 8 tak, že GetChild(x, y, z) = x + 2y + 4z, inverzní zobrazení pak odpovídá výrazu GetChild 1 (n) = n mod 2, (n mod 4) mod 2, ((n mod 8) mod 4) mod 2. Zobrazení GetChild lze implementovat pomocí logické aritmetiky následují- 24

25 cím způsobem. GetChild <- function( x, y, z ){ return x y << 1 z << 2; Inverzní zobrazení pak můžeme opět s úspěchem přepsat pomocí logické aritmetiky. GetChild^-1 <- function( n ){ return < n & 0x1, (n & (0x1 << 1)) >> 1, (n & (0x1 << 2)) >> 2 >; Algoritmus kd-restart Ve skutečnosti se nejedná přímo o algoritmus známý z kd-stromů, ale je této technice velice příbuzný a asi proto jej různé zdroje [9] takto nazývají. Tento algoritmus je patrně nejintuitivnější technikou adresace v octree, která pracuje od kořene dolů v čase O(log 2 N) s relativně nízkou multiplikativní konstantou. Principem této techniky je ověření do které oblasti daný bod spadá a následné rukurzivní zanoření do této oblasti. Ukončovací podmínkou rekurze je listová oblast stromu. Krátkým pseudokódem by šel algoritmus kd-restart vyjádřit následovně. kd_restart <- function( node, cube = <x,y,z,w>, inpoint ){ if( node->leaf_p ){ return <node, cube>; midpoint <- < cube.x + cube.w/2, cube.y + cube.w/2, cube.z + cube.w/2 >; path <- < inpoint.x >= midpoint.x, inpoint.y >= midpoint.y, inpoint.z >= midpoint.z >; return kd_restart( GetChild( path.x, path.y, path.z ), < cube.x + path.x*(w/2), cube.y + path.y*(w/2), cube.x + path.z*(w/2) >, inpoint ); 25

26 Efektivněji lze tento algoritmus přímočaře napsat pomocí cyklu, v takovém případě odpadá nutnost práce se zásobníkem Algoritmus kd-backtrack Algoritmus kd-backtrack pracuje s předpokladem, že je často nutné adresovat sousední listové oblasti stromu. Sousední listové oblasti stromu mají tu vlastnost, že k nim vede za jistých okolností podobná cesta, existují však patologické případy, kdy to neplatí vůbec. Tyto případy se vyskytují ve středové části celého octree. Například máme-li zcela zaplněný oktalový strom velikosti , pak dojde k úplnému selhání této metody v bodě x, x, 255 a následně v bodě x, x, 256. Tehdy je třeba se vrátit až do kořenového uzlu octree. Algoritmus vyžaduje navíc paměť velikosti O(log 2 (N)), ve které uchovává předchozí známou cestu. Samotný algoritmus pak dostává předchozí známou cestu jako parametr a postupně se vrací po cestě zpět, dokud nenalezne tzv. restart node (uzel restartu). Restart node je nalezen, jestliže současný adresovaný bod spadá do bounding boxu tohoto uzlu. Po nalezení restartovacího uzlu se pokračuje běžným kd-restart algoritmem vpřed a ukládá se cesta Algoritmus kd-shortstack Je jednoduchou variantou algoritmu kd-backtrack. Algoritmus kd-shortstack pouze pracuje s kratším zásobníkem. V případě, že narazí na dno zásobníku při zpětném chodu, vezme se kořenový uzel jako restart node. Toto redukuje patologické případy, ale zčásti i ty výhodné. Triviálním případem kd-shortstack algoritmu je kd-restart, tehdy je délka zásobníku nulová. Algoritmus kd-backtrack je speciálním případem, kdy volba délky zásobníku je rovna výšce stromu Neighbor search Další metoda spočívá v udržování ukazatelů na sousední prvky v každém uzlu, které jsou větší nebo stejně velké jako daná oblast. Tato metoda však potřebuje navíc 6 ukazatelů pro každou stěnu krychle, což velmi razantně zvýší multiplikativní konstantu paměťové složitosti. Procházení pak probíhá tak, že se stane uzlem restartu soused, do kterého míří paprsek. Jelikož je jeho bounding box větší nebo roven současnému uzlu je potřeba ještě provést adresaci směrem k listovým uzlům, což v nejhorším případě může stát opět O(log 2 N) kroků. Tento případ je však málo pravděpodobný, tudíž je tato metoda rozhodně nejrychlejší ovšem za cenu velmi objemných modelů Procházení octree podél přímky V současnosti jsou popsány dvě metody trasování paprsku v octree. Prvním přístupem je procházet strom od spodu. V tomto případě se paprsek trasuje 26

27 přes listové oblasti stromu, přičemž k adresaci listových oblastí stromu se používá předchozích adresačních algoritmů, které vracejí bounding-box této oblasti. V každém kroku se provede test, zda právě testovaný uzel je prázdný. Pokud prázdný není, vrací se barva nalezené listové oblasti. V případě, že prázdný je, vypočítá se bod, ve kterém paprsek opouští bounding-box. Toto se provádí tak dlouho, dokud paprsek neopustí model nebo nenarazí na vyplněnou listovou oblast. ray_traverse <- function( root, ray_position = <x1, y1, z1>, ray_vect = <x2, y2, z2> ){ <color, bbox> = address( root, bounding_box( root ), ray_position ); if( color!= OPACITY ){ return color; return ray_traverse( root, box_out_point( ray_position, ray_vect, bbox ), ray_vect ); Funkce address z pseudokódu může odpovídat některému z předchozích uvedených algoritmů nebo obecně to může být libovolná funkce, která implementuje zobrazení I. Funkce bounding_box vrací bounding box uzlu. Funkce box_out_point vypočítá výstupní bod paprsku z krychle. Funkce ray_traverse lze pochopitelně velice snadno přepsat do nerekurzivní formy. Toto procházení lze samozřejmě použít i pro implementaci dynamického světla, tehdy se paprsek po dopadu na povrch trasuje ke světlu. Limitní podmínka úspěchu je pak střet s bounding boxem, ve kterém se nachází zdroj světla nebo opuštění modelu. Tento algoritmus je výhodný pro paralelizaci. Lze totiž celý implementovat iterativním způsobem a nepotřebuje tudíž práci se zásobníkem. Práce se zásobníkem je zejména na grafických kartách vysoce neefektivní. Naopak u běžných výpočetních procesorů (CPU) je práce se zásobníkem velmi běžná a dobře optimalizovaná činnost. Zde je naopak vhodnější použít rekurzivní algoritmus, který pracuje zhora a podle článku [5] má časovou složitost O(M), kde M je počet listových uzlů kd-stromu. V případě octree existuje analogie rekurzivního procházení kd-stromu v podobě výsledku nazvaného HERO (A Hardware Enhancer for Ray-tracing Octrees) [1], což je vysoce optimalizovaný způsob procházení octree, který pracuje rekurzivně. Časová složitost je však stále O(N logn), ovšem nalezení uzlu restartu je lacinější vzhledem k algoritmům založeným na principu kd-shortstack, ještě o málo výhodnější je metoda udržování sousedních uzlů, avšak za cenu vysoké paměťové náročnosti. Zde si totiž explicitně udržujeme uzly restartu. 27

28 Počet kroků procházení podél přímky zcela naplňeného octree je zjevně O(N), v nejhorším případě totiž trasujeme paprsek po diagonále a nedojde k žádné kolizi. Adresace v každém kroku stojí O(logN) času pro algoritmy založené na technice kd-shortstack, tudíž celková časová náročnost algoritmu trasování paprsku je O(NlogN). U řídkých modelů je však trasování paprsku ve výsledku mnohem rychlejší než v případě syrového modelu N 3 strom Tento typ stromu je zobecněním octree a přináší optimalizaci v jiném pohledu na listové uzly, čímž omezuje zápornou komprimaci. Každý uzel N 3 stromu obsahuje N 3 následníků, kteří rovnoměrně dělí prostor svého rodiče [3], stejně jako u octree. Octree je speciální případ N 3 stromu, kde N = 2. N 3 strom dále dělí uzly stromu na tři druhy. Prvním druhem je běžný uzel s N 3 potomky, dále je to listový uzel, který nemá žádného potomka a nese pouze informaci o barvě, třetím druhem je pak tzv. brick. Což je krychle o straně velikosti M, která představuje malý raw model, opatřený mip-mapou. U octree je M = 1. Podle článku [3] se hodnoty N a M volí před kompilací do N 3 stromu. Nízká volba N způsobí dobrou spotřebu paměti, ale zvýší časové nároky při průchodu díky velké hloubce stromu, naopak volbou vysokého N se docílí dobrého výkonu při procházení za cenu redukovaného komprimačního poměru. Tento model je vhodný pro GPGPU výpočty, jelikož použití bricků způsobí efektivnější paměťovou komunikaci mezi procesorem a GPU. Adresační metody i odvození složitosti je analogické octree stromům, tudíž nejsou již redundantně zmíněny. 5. Vlastní optimalizační úvahy adaptive octree V této kapitole nastíním vlastní pohled na alternativní model, který považuji alespoň podle dostupné literatury za unikátní. Model adaptive octree je jakýsi kompromis mezi octree a raw modely, oproti octree modelu zlepšuje jak paměťovou složitost (zejména u hustých modelů), tak i časovou složitost procházení. Adaptive octree přebírá dobrou vlastnost z oktalových stromů a tou je možnost přeskočení velkých prázdných oblastí a efektivní uložení velkých homogenních oblastí. Z raw modelů adaptive octree přebírá efektivní uložení komplexních oblastí a jejich efektivní procházení. V modelu adaptive octree pracujeme opět s technikou bricků, jejichž hrana je vždy velká 2 B, pro nějaké B N, které se adaptivně volí dle jistého klíče. Adaptive octree rozlišuje tři druhy uzlů. První je listový uzel bez potomků nesoucí pouze barvu. Druhý typ je běžný octree uzel, který nese 8 potomků. Poslední typ uzlu je brick, což je raw model. Uzel typu brick se volí tehdy a jen tehdy, je-li to výhodné z hlediska spotřeby paměti (lze uvažovat i jiná hlediska). To nastává tehdy, když paměť spotřebovaná octree podstromem 28

29 je vyšší než paměť, která by byla zapotřebí pro reprezentaci pomocí raw modelu. Připomeňme, že počet uzlů podstromu plného octree velikosti hrany N je přesně. S(N) = log 2 N l=0 8 l = 1 8log 2 N+1 7 Počet uzlů jiného než plného octree je třeba individuálně spočítat pro každý podstrom jeho projitím. Velikost podstromu adaptive octree tedy zjistíme tímto triviálním algoritmem. octree_memory_sz <- function( root ){ if( leaf_p( root ) ) return sizeof( root ); if( raw_p( root ) ) bbox = root.bounding_box; return bbox.w * bbox.h * bbox.w * root.bytes_per_pixel; sum = 0; for( i = 0 ; i < 8 ; i++ ){ sum += octree_memory_sz( root.childs[i] ); return sum; Kompilace raw formátu do adaptive octree formátu je pak téměř stejná jako kompilace do běžného octree. Pouze se před návratem z rekurze provede výpočet velikosti podstromu v bajtech. Jestliže je octree podstrom náročnější na spotřebu paměti, než raw model, provede se převod této oblasti na raw model a ten se vrátí. Upravený pseudokód již uvedené optimalizace pak vypadá takto. optimal_p <- function( node ){... optimize <- function( node ){ for( i = 0 ; i < 8 ; i++ ){ optimize( node->childs[i] ); 29

30 switch( optimal_p( node ) ){ case SAME: node->color = node->childs[0]->color; memset( node->childs, NULL ); return node; break; case EMPTY: return NULL; break; default: break; if( octree_memory_sz( node ) > node.bbox.w^3*sizeof(argb32_color) ){ /* převede podstrom octree na ekvivalentní raw model */ return octree_to_raw( node ); return node; Věta 1. Paměťová složitost adaptive octree není horší, než paměťová složitost raw modelu až na malou aditivní konstantu. Důkaz. Předpokládejme, že existuje ve stromě neoptimální podstrom. To ovšem není možné, protože algoritmus při optimalizaci navštíví všechny uzly stromu ve smyslu post-order a zkontroluje jejich optimálnost. V případě neoptimálnosti je zoptimalizuje tak, že podstrom převede na raw model, tudíž každý podstrom je již optimální ve smyslu optimálnosti adaptive octree. Důsledkem věty 1 je skutečnost, že paměťová náročnost adaptive octree nezáleží na tom, jestli je daný adaptive octree řídký nebo ne. V nejhorším případě totiž může dokonce zdegenerovat v běžný raw model. Tato reprezentace je zjevně výhodná pro ukládání na pevný disk, neboť velikost adaptivního oktalového stromu nikdy nepřeroste velikost raw modelu (až na malou aditivní konstantu způsobenou vynucenou hlavičkou). V případě řídkého modelu si ale zachová dobré vlastnosti běžného oktalového stromu a navíc redukuje počet hlubokých octree uzlů. Tudíž adaptive octree není paměťově nikdy horší než běžný octree strom. Nevýhodou této smíchané struktury je špatně implementovatelný mipmapping. Mipmapping lze dělat pouze u octree uzlů, v případě raw uzlů by bylo potřeba spočítat mipmappingovou pyramidu, což ale stojí přesně 30

31 tolik paměti co podstrom octree stejné velikosti. Toto může být stále výhodné v případě řídkých modelů. Věta 1. Časová složitost procházení adaptive octree podél přímky pomocí algoritmů kd-shortstack je O(N logn), kde N je velikost hrany adaptive octree. Důkaz. Adresace listových uzlů octree stojí zjevně stále O(log 2 N), ty se totiž nacházejí v nejhůře v hloubce O(log 2 N). Další analogií adaptive octree by mohla být stejná struktura s jinak definovanou funkcí octree_memory_sz, například tak, aby strom bylo možné vždy projít podél přímky v lineárním čase za pomocí kd-shortstack algoritmů, to by znamenalo nalézt mez, kdy se ještě vyplatí zjemňovat octree uzel, a kdy už je lepší místo dlouhé cesty k němu projít přímo raw model, který má záruku procházení podél přímky v lineárním čase. 31

32 6. Knihovna VoXen Measuring programming progress by lines of code is like measuring aircraft building progress by weight. (Bill Gates) Knihovna VoXen the VoXel engine představuje obecné, výhledově multiplatformní rozhraní pro vykreslování voxelové grafiky. Knihovna je psána v jazyce C99 z důvodu minimalizace režie při softwarovém vykreslování a z důvodu nativní podpory OpenCL pro tento jazyk. VoXen umožňuje používání různých vykreslovacích back-endů, v současnosti je implementováno vykreslování pomocí multiplatformní knihovny SDL určeného pro běžné účely a NULLDrv ovladač, který je určen pro další využití výstupu z knihovny VoXen, například v OpenGL. Výstup je však také možno realizovat pomocí libovolné grafické knihovny dopsáním příslušného ovladače. Knihovna VoXen implementuje základní raw model a octree, včetně několika různých technik procházení tohoto modelu. Implementace knihovny se zaměřuje na optimalitu kódu. Některé kritické části kódu jsou volitelně implementovatelné v OpenCL. Knihovna VoXen podporuje vícevláknové vykonávání kódu pro softwarové vykreslování na procesoru. Cílem návrhu rozhraní knihovny je také maximální možná jednoduchost a snadná pochopitelnost bez nutné znalosti vnitřních implementačních detailů, jakož i možnost snadného propojení s jinými vysokoúrovňovými programovacími jazyky, například Common Lispem nebo jazyky Lua, Python, Ruby atd Architektura Architektura knihovny VoXen se nesnaží být pouze jednoduchá, ale i dostatečně silná tak, aby umožňovala doimplementování nových modelů a ovladačů, což umožňuje portaci na libovolnou současnou i budoucí platformu. Tento návrh je podobný jako v případě velmi úspěšného enginu Quake 3 od firmy idsoftware. Knihovna není psána čistě objektově, nicméně poskytuje rozhraní pro několik stěžejních objektů, to se ale netýká grafických primitiv, protože zde objektový přístup zbytečně zvyšuje režii Systém souřadnic Systém souřadnic jsem zvolil běžný, pouze hodnoty na ose z se zvyšují dále od pozorovatele. Podle zdroje [4] se jedná o konvenci levé ruky. Důvodem je intuitivnější adresace v oktalovém stromě, který je povinně zarovnán do počátku souřadnicového systému. Pro lepší představu viz obrázek Elementární datové typy Knihovna VoXen pracuje s trojrozměrným affiním prostorem a k tomu potřebuje primitiva, jako je bod, vektor, matice, kvádr apod. Kvůli dokonalému 32

33 y z Obrázek 2. Organizace souřadnic v knihovně VoXen. oddělení knihovny od ostatních knihoven, na kterých VoXen závisí, jsou všechna primitiva znovu nadefinována. Navíc v knihovně používám často dvojí přístup k primitův. Lze s nimi pracovat buď jako s poli prvků daného typu, nebo jako se strukturami podle toho, který přístup je právě elegantnější. Knihovna redefinuje také základní typy s cílem, aby byl zachován stejný počet bajtů na všech platformách, to může být důležité například při načítání modelu ze souboru nebo při práci s barevnými kanály. Výčet přepsaných základních typů je následující: VX byte bezznaménkový bajt, VX int16 znaménkový integer délky 2 bajty, VX uint16 bezznaménkový integer délky 2 bajty, VX int32 integer délky 4 bajty, VX uint32 bezznaménkový integer délky 4 bajty. Důležité struktury nesoucí základní grafická primitiva vypadají následovně: X,Y,Z je přejmenování indexů 0, 1, 2 na souřadnice, VX TYPEpointDIMENSION je obecný tvar pro bod, nebo vektor v prostoru, položka TYPE může nabývat hodnot d = double, f = float, i = integer a položka DIMENSION může nabývat hodnot 2 nebo 3 podle dimenze, pro jakou je vektor či bod určen. Tyto struktury jsou přetypovatelné na pole o dvou nebo třech prvcích daného typu. Knihovna VoXen například často používá výraz float vector [3] = (float*)(&p), kde prvek p je typu VX_fpoint3. Přístup k například x-ové složce je pak možný pomocí výrazu vector[x], VX cube obsahuje prvky x, y, z, které představují minimální souřadnici krychle, w představuje velikost hrany krychle. Zbylá primitiva lze nalézt v hlavičkovém souboru vx_fundamental.h, který navíc obsahuje některá konverzní makra. 33 x

34 6.4. Objektový systém VoXen I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (Alan Kay) Pro udržení konzistence API a možnosti doporogramování funkcionality beze změny základního kódu je knihovna VoXen psána částečně objektově. Objekty jsou použity pouze tam, kde to nemá vliv na výkon. Jazyk C99 sice nemá vestavěnou podporu objektového programování, nicméně ji lze poměrně jednoduše přidat beze změny syntaxe jazyka. V knihovně VoXen je každá třída definována jako běžná struktura, která na některých pozicích nese ukazatele na funkce metody a na některých pozicích jsou sloty. Metody povinně musí splňovat volací konvenci, kdy jako první argument je ukazatel na zpracovávaný objekt, doporučený název je self (v jazyce C++ se nazývá this). Princip dědění tříd v tomto objektovém systému, lze implementovat díky pevnému řazení prvků ve strukturách v jazyce C. Zděděný objekt se pak deklaruje jako kopie metod a slotů původního objektu a za něj se přidají další sloty a metody. Konstruktory tříd jsou běžné funkce, které vracejí daný objekt a inicializují jej, a to včetně tabulky metod. V knihovně VoXen používám konvenci pro pojmenování konstruktorů ve tvaru VX_CLASSNAME_new, kde CLASSNAME je jméno třídy. Pro ilustraci dědení objektů přikládám následující příklad. #define MAMMAL_BODY \ int size; \ char gender; \ void (*live)( struct MAMMAL * ); \ typedef struct MAMMAL{ MAMMAL_BODY MAMMAL; typedef struct CAT{ MAMMAL_BODY void (*bite)( struct CAT * ); int mouses_eaten; CAT; /* přetypování CAT na MAMMAL je bezpečné */ CAT k; MAMMAL * m = (MAMMAL*)&k; 6.5. Rozhraní obrazového povrchu Obrazový povrch (surface) slouží k uchování rastrového obrazu v paměti počítače. Knihovna VoXen deklaruje surface takto. 34

35 typedef struct VX_surface{ /* Vtbl */ void (*free)( struct VX_surface * ); VX_uint32 (*get_pixel)( struct VX_surface *, VX_uint32 x, VX_uint32 y); void * (*lock_surface)( struct VX_surface * ); void (*unlock_surface)( struct VX_surface * ); void (*set_pixel)(struct VX_surface * self, VX_uint32 x, VX_uint32 y, VX_uint32 color ); /* data */ VX_uint32 w,h; /*... */ VX_surface; Metoda free zajišťuje korektní uvolnění prostředků zabraných povrchem. Metoda get_pixel vrací barvu pixelu. Dvojice metod lock_surface a unlock_surface slouží k uzamykání a odemykání obrazového povrchu, toto se používá pro znemožňení čtení nebo zápisu do nekonzistentního povrchu. K nekonzistenci může dojít při přesunu povrchu mezi systémovou pamětí a pamětí grafické karty Objekt ovladače a proces inicializace Knihovna VoXen může pracovat s ovladači, což jsou objekty implementující rozhraní definované takto. typedef struct VX_machine{ /* Vtbl */ int (*init)( struct VX_machine * self, VX_rect resolution, VX_uint32 flags ); int (*quit)( struct VX_machine * self ); VX_surface * (*make_surface)( VX_uint32 w, VX_uint32 h ); void (*redraw)( struct VX_machine * self ); /* data */ VX_rect resolution; VX_uint32 flags; VX_surface * native_surface; int cores_count; /* user data */ 35

36 void * custom_dta; VX_machine; Metoda init musí implementovat inicializaci stroje self s rozlišením resolution a příznaky flags, navrací 0 při úspěchu, 1 při selhání. Metoda quit uvolňuje prostředky, návratové hodnoty mají totožný význam jako u metody init. Metoda make_surface vytváří na daném ovladači obrazový povrch. Metoda redraw překresluje obrazový povrch zařízení. Slot resolution uchovává informaci o rozlišení, slot flags uchovává příznaky předané při inicializaci, slot native_sruface je výstupní povrch ovladače (například povrch monitoru), slot cores_count nese informaci o počtu procesorů zařízení. Samotná inicializace knihovny je velmi jednoduchá. VX_init( VX_DRV_sdl, 640, 480, VX_FULLSCREEN ); Tento kód zinicializuje ovladač VX_DRV_sdl (ovladač knihovny SDL) s rozlišením a se zapnutým celoobrazovkovým režimem. Přístup k metodám ovladače je pak jedině možný přes globální objekt VX_lib Matice transformace Knihovna VoXen pracuje s maticemi velikosti 4 4, přičemž knihovně samotné by stačila matice pouze velikosti 3 protože modely jsou povinně zarovnány do počátku, tudíž nemusíme uvažovat translace jako v běžném afinním prostoru. Nicméně z důvodu možného vestavění do jiných programů je zvolen tento přístup. Knihovna také poskytuje funkce, které násobí dvě matice 4 4 mezi sebou VX_matrix4_multiply, zde může kompilátor díky záruce velikosti obou matic provést optimalizaci ve formě linearizace kódu s následným využitím specializovaných instrukcí (SSE na platformě Intel). Stejně tak je ve VoXen definována funkce na vynásobení vektoru maticí VX_fvector4_multiply. Knihovna dále definuje několik dalších funkcí pro práci s maticemi, které jsou vyčteny v souboru matrix.h, jedná se o jednotkovou matici, rotační matice, sčítání matic a jejich inspekce Rozhraní obecného modelu Aby bylo možné pracovat s rozdílnými modely voxelové grafiky a provádět na nich měření, aniž by to poznal uživatel programátor, zavedl jsem rozhraní, které musí implementovat každý model. V knihově VoXen jsou implementovány dva základní formáty. První je syrový model se zjednodušeným procházením podél paprsku, který navíc neimplementuje nasvětlování a ořez paprsků (opustí-li kamera raw model, nic se nevykresluje). Druhý model je octree, který je kompletně implementován. Rozhraní obecného modelu je definováno následovně (zmíněny jsou pouze veřejné položky). 36

37 typedef struct VX_model{ VX_block dim_size; int (*compile)(struct VX_model * self, struct VX_model * m ); int (*dump)(struct VX_model * self, const char * file ); void (*inspect)(struct VX_model * self); VX_byte* (*get_voxel)(struct VX_model * self, VX_uint32 x, VX_uint32 y, VX_uint32 z, int * lod ); void (*set_voxel)(struct VX_model * self, VX_uint32 x, VX_uint32 y, VX_uint32 z, VX_uint32 color ); VX_uint32 (*ray_voxel)( struct VX_model * self, float * position, float * norm_vect, int lod ); void (*present)( struct VX_model * self, VX_camera *, VX_rect clip_rect ); int (*load)(struct VX_model * self, const char * path ); void (*free)(struct VX_model * self ); VX_model; Členská proměnná dim_size nese bounding-box celého modelu, který začíná povinně v počátku. Metoda compile provede převod z libovolného modelu m na model self, přičemž zařídí všechny nutné alokace a dealokace a reinicializaci objektu self na nové hodnoty. Metoda dump uloží model self do souboru file. Metoda inspect provede inspekci objektu a zjištěné údaje vytiskne na standardní výstup v člověku čitelné formě. Dvojice metod get_voxel, set_voxel přečte, respektive zapíše voxel barvy color do modelu self na souřadnici x, y, z, argument lod omezuje rozlišení voxelu a slouží také k navrácení informace o poslední hodnotě, kterou nabýval před navrácením barvy. Funkce ray_voxel vrací barvu konvertovanou do 32-bitového ARGB formátu, která byla získána paprskem s počátkem v position a vektorem norm_vect, argument lod omezuje úroveň detailu. Metoda present slouží k rychlému vrhání paprsků a zápisu výsledků do povrchu kamery, camera je ukazatel na kameru, clip_rect obdélníková oblast výstupního obrazu kamery, pro kterou se mají počítat paprsky, tato funkcionalita musí být řádně implementována pro správnou funkčnost vícevláknového vykonávání. Metoda load načte do objektu self model ze souboru path, navrací 0 v případě úspěchu, cokoli jiného se považuje za chybu. Metoda free provede uvolnění modelu self, tento ukazatel je pak již neplatný. 37

38 6.9. Kamera a generátor paprsků Kamera je objekt, který vysílá paprsky ze svého ohniska do scény a výsledky ukládá do framebufferu knihovny. Kamera je navíc implementována tak, že je schopná pracovat na paralelních procesorech v případě, že pracuje se softwarovým vykreslováním. Tehdy rozdělí obraz na tolik přibližně stejně velkých oblastí jako je procesorů a paprsky pro tyto oblasti se zpracují paralelně. Při paralelním vykonávání je zaručeno, že vykreslovací funkce bude blokovat program v místě, kde bylo vykreslení zavoláno. Kamera nese transformační matici, kterou se násobí vektory jednotlivých paprsků a také nese informaci o své pozici. Dalším mechanizmem, který je s kamerou spjat, je generátor paprsků (ray generator). Tento pojem už byl zmíněn v kapitole o metodě sledování paprsku. V knihovně je zaveden podobně, pouze má navíc za úkol transformovat paprsky podle transformační matice kamery. Kameru je možné zinicializovat pomocí této funkce. VX_camera * VX_camera_new( VX_surface * surf, VX_fpoint3 (*ray_generator)( VX_camera * self, VX_uint32 x, VX_uint32 y ), int cpus_count ); Argument surf vyžaduje platný ukazatel na existující surface, ray_generator je ukazatel na funkci generující paprsky, může být NULL, tehdy se použije vestavěné perspektivní promítání. Posledním argument je cpus_count, což je počet vláken, které mají obraz zpracovávat, přípustné jsou i hodnoty menší než 1. To vede na vykonávání v tolika vláknech, kolik je zjištěno procesorů na hostitelském stroji. Vykreslení kamery do povrchu dojde zavoláním metody void (*draw)( VX_camera * self, VX_model * model ). Objekt kamery se uvolňuje metodou destroy Implementace raw formátu Raw formát je implementován spíše jako referenční model, než model, který by byl prakticky příliš použitelný. Nicméně lze ho používat ke konverzi syrových dat do jiných rozumnějších formátů a ke srovnávacím testům s octree, případně s dalšími uživatelskými modely. Ukládání raw formátu je uděláno obdobně, jako v teoretické kapitole o raw formátu. Celý obraz je tedy zlinearizován do jednorozměrného pole a voxely se adresují pomocí již uvedeného vzorce 4.1. Procházení raw formátu podél přímky je uděláno přímočarým zobecněním Bresenhamova algoritmu do třetí dimenze, což sice nezaručuje zcela správné procházení modelu, nicméně obraz je deformován jen nepatrně, zcela správné a relativně rychlé procházení nabízí například algoritmus ze článku [2]. Syrový model dále neimplementuje trasování paprsku ke zdrojům dynamického světla ani ambientní světlo. 38

39 Důvodem je nízká rychlost vykreslování i bez použití světla, v případě trasování paprsku ke světlu by došlo k dalšímu razantnímu propadu počtu snímků za sekundu. Jediný případ, kdy může být vykreslování raw modelu rychlejší, než vykreslování octree modelu je situace, kdy je kamera velmi přiblížená složitému povrchu. Tehdy totiž stačí jen málo kroků k nalezení povrchu objektu. Vytvoření, načtení a inspekci raw modelu ukazuje následující krátký příklad. VX_model * raw_model = VX_model_raw_new( &FMT_255, (VX_block){0, 0, 0, 224, 256, 300 ); raw_model->load( raw_model, "skeleton.bin" ); raw_model->inspect( raw_model ); Konstruktor raw formátu bere jako první parametr formát obrazu a jako druhý argument velikost obrazu. Tyto informace jsou nezbytné protože raw formát nemá žádnou hlavičku Implementace octree formátu Octree je ztěžejní model vestavěný přímo do knihovny VoXen a jeho efektivní implementaci bylo věnováno nejvíce času. Z tohoto důvodu zmíním zajímavé implementační momenty. Jelikož je struktura octree stromová, musí být ztěžejní strukturou uzel. V mé implementaci uvažuji dva druhy uzlů. Prvním druhem uzlu je běžný octree uzel definovaný následujícím způsobem. typedef struct VX_oct_node{ VX_uint32 flags; VX_uint32 color; struct VX_oct_node * childs[8]; VX_oct_node; Položka flags je čtyřbajtová struktura, která v prvním bytu nese informace o svých sousedech. V případě, že je i-tý pointer nenulový, pak je také i-tý bit nenulový. Jedná se o listový uzel, právě když je první bajt položky flags prázdný. Zbylé bajty flags jsou prázdné s výhledem do budoucnosti by mohly být použity jako indexy do pole s materiály. Položka color je povinná i pro nekoncové uzly, neboť se do ní počítá průměrná ARGB barva podstromu, což pak dále může sloužit pro implementaci úrovně detailů. Pole childs je pole ukazatelů na následníky, jejichž umístění odpovídá obrázku 3. Jelikož je v octree obvykle nejvíce listových uzlů, vyplatí se listové uzly ukládat jiným způsobem. V knihovně VoXen se ukládájí v podobě. typedef struct VX_oct_node_leaf{ VX_uint32 flags; VX_uint32 color; VX_oct_node_leaf; 39

40 Obrázek 3. Mapování indexů na potomky octree. Díky tomuto zápisu je možné běžný uzel bezpečně přetypovávat na VX_oct_node_leaf, v prvním bytu položky flags je povinně hodnota 0. Tato implementační drobnost snížila paměťovou režii u různých modelů zhruba o 30%. Problém, který bylo dále třeba vyřešit, je ukládání stromové struktury do souboru. To je vyřešeno rekurzivním projitím octree a zápisem uzlů do streamu s přepočtem ukazatelů na odsazení, které je zakódováno jako 32-bitový integer. Hlavička souboru je představována touto strukturou. struct VX_OCT_header{ VX_block dim_size; VX_uint32 control_size; ; Prvních 24 bajtů je zabráno pro informaci o rozměrech. Následuje kontrolní součet, který vznikl výrazem vynásobením rozměrů modelu a přičtením magické konstanty 0xBEAF. Důvod pro to je alespoň základní ochrana před načítáním nevyhovujících souborů. Kořenový uzel stromu je vždy poslední uzel v souboru. Konvencí pro příponu takto vzniklých souborů s oktalovými stromy je.oct Sestavení octree Sestavení octree je implementováno metodou compile. Funguje principem rekurzivního sestupu. Důvodem je nízká spotřeba paměti tak, jak bylo uvedeno v kapitole o kompilaci octree. Při sestavování octree se navíc počítají průměrné ARGB barvy podstromu uzlu. To je důležité pro implementaci LOD. Průměr se vypočítá po složkách z barev potomků Cube clipping algoritmus vlastní myšlenky Jedná se o algoritmus hledání průsečíků přímky s kvádrem. V knihovně Vo- Xen je tento problém rozdělen na dva. První (málo využívaný problém) nachází 40

41 vstupní průsečík s kvádrem. Druhý problém hledá výstupní průsečík z kvádru. Hledání výstupního průsečíku z kvádru je klíčová funkcionalita při procházení octree, vstupní průsečík stačí nalézt pouze jednou. Při procházení octree podél přímky je totiž nutné vypočítávat výstupní body z bounding boxů. Jelikož kroků k projití octree může být zapotřebí až O(N) vzhledem k velikosti hrany octree, bylo nezbytné zaměřit se na maximální výkon takto kritické části. V první řadě jsem vyvinul heuristiku, která nejprve setřídí vektor paprsku podle velikosti složek v jednotlivých směrech. Permutace vzniklá tříděním se pak využívá k určení prioritního testování výstupních stěn krychle. Výpočet permutace provádím přečtením hodnot z lookup tabulky, která obsahuje všechny možné permutace vzhledem k porovnání. Vznik tabulky PERM_LOOKUP lze ilustrovat následovně. for( zy_cmp = 0 ; zy_cmp < 2 ; zy_cmp++ ){ for( yx_cmp = 0 ; yx_cmp < 2 ; yx_cmp++ ){ for( zx_cmp = 0 ; zx_cmp < 2 ; zx_cmp++ ){ tmp_y = Y << (8*(zy_cmp +(1-yx_cmp))); tmp_x = X << (8*(yx_cmp + zx_cmp)); tmp_z = Z << (8*((1-zy_cmp) + (1-zx_cmp))); PERM_LOOKUP[zy_cmp][yx_cmp][zx_cmp] = tmp_z tmp_y tmp_x; Jedná se tedy o třírozměrnou tabulku velikosti 2 2 2, která je jakýmsi rozhodovacím stromem. Permutaci setřízení dostaneme z tabulky takto. vector_sort <- function( v = <x,y,z> ){ return PERM_LOOKUP[ v.z < v.y ][ v.y < v.x ] [ v.z < v.x ]; Výhoda lookup tabulky spočívá v zamezení větvení kódu, které jinak vede k redukci výkonu. Výpočet permutace se však počítá pro každý paprsek jednou, tudíž není tato skutečnost zcela zásadní. Samotné testování výstupního průsečíku probíhá tak, že je definována jednorozměrná lookup tabulka, která nese na indexech odpovídajících osám x, y, z ukazatele na výpočetní funkce pro dané stěny. Stěny jsou zarovnány podél souřadnicového systému, tudíž je výpočet průsečíku s danou stěnou velmi jednoduchý. Uvažujme obecnou rovnicí ax + by + cz + d = 0 roviny, kde vektor a, b, c je normálový vektor k rovině, d se dopočítá dosazením libovolného bodu ležícího na rovině. Mějme přímku zadanou bodem P l = p x, p y, p z a vektorem v = v x, v y, v z. O průsečíku P p víme, že leží na přímce, tudíž splňuje následující rovnost pro nějaké c. P p = P l + c v 41

42 Dosazením do obecné rovnice po složkách lze již snadno vyjádřit konstantu c. Ze znalosti konstanty c lze pak už snadno dopočítat P p. V algoritmu však pracujeme s rovinami zarovnanými na roviny souřadnic. Tudíž lze většinu položek výpočtu eliminovat a dostáváme následující výraz c = (o p i) v i. Kde i {x, y, z a volí se podle orientace právě počítané stěny. Hodnota o je odsazení od počátku ve směru, který právě počítáme. Při výpočtu průsečíku stačí provést dvě násobení, podle orientace stěny a zbylá souřadnice je dána přímo polohou roviny. Tím se tedy redukuje výpočet na jedno reálné dělení a dvě násobení pro jednu rovinu. Což je pravděpodobně nejefektivnější možný výpočet vůbec. Následně se ještě musí zkontrolovat, zda nalezený bod skutečně leží na stěně kvádru. Pseudokód pro osu z vypadá takto. z_axis <- function( d, cam = <x,y,z>, ray = <rx,ry,rz>, box = <lx,ly,lz,ux,uy,uz> ) { c = (d - z) / rz; out_pt[3]; out_pt[x] = x + (rx*c); out_pt[y] = y + (ry*c); out_pt[z] = d; return <(out_pt[x] < ux) && (out_pt[x] >= lx) && (out_pt[y] < uy) && (out_pt[y] >= ly), out_pt> Funkce pro jednotlivé osy jsou v knihovně generovány makrem pro zamezení redundance kódu a pro maximalizaci propustnosti. Samotná funkce pro nalezení výstupního průsečíku z kvádru je už velmi jednoduchá. Stačí projít permutaci setřídění vektoru paprsku a kontrolovat, dokud nebude výsledek pravdivý alespoň pro jednu stěnu nebo nepravdivý pro všechny stěny. Poznamenejme skutečnost, že stačí testovat pouze tři stěny podle znaménka, protože nemá smysl testovat stěnu, ke které paprsek ani nesměřuje. Obdobně se implementuje i funkce pro hledání vstupního bodu do kvádru. Dalším zlepšením by mohlo být cachování výsledků dělení nebo jejich předpočítání pro každý paprsek Algoritmy procházení octree Algoritmus kd-restart je primární volbou pro implementaci metody get_voxel. Důvod je ten, že zde není možné očekávat předání žádné předchozí 42

43 informace, tudíž se zde musí pracovat vždy od kořene. Algoritmus je na rozdíl od uvedeného pseudokódu v iterativní podobě a je napsán s důrazem na optimalitu, která byla docílena nástrojem callgrind. Knihovna dále implementuje algoritmy kd-backtrack a kd-shortstack. Opět s velkým ohledem na výkon, ale také s ohledem na možnost spravedlivého srovnání výkonu. Samotné algoritmy procházení octree podél paprsku jsou vždy těsně spjaty s jednotlivými variantami kd-shortstack tak, aby mohl tyto algoritmy kompilátor dobře analyzovat a přeložit. Výkon těchto algoritmů má totiž zdaleka největší dopad na počet vykreslených snímků za sekundu Nasvětlování a stínování V knihovně VoXen jsou v současnosti implementovány dva základní typy světel. První typ je tzv. ambientní (rozptýlené světlo), jehož barva se vynásobí po složkách s každou barvou modelu, druhým typem světla je dynamické bodové světlo. Při trasování paprsku za přítomnosti bodového dynamického světla je třeba při střetu paprsku s objektem vyslat další paprsek směrem ke světlu, které je reprezentováno jedním bodem. V případě, že k němu paprsek dorazí sečte se barva světla a barva objektu po složkách s tím, že se zamezuje přetečení hodnoty 255 (tzv. aditivní míchání). Z hlediska programového rozhraní se pracuje se světly pomocí následujících funkcí. void VX_ambient_light_set( VX_uint32 color ); VX_uint32 VX_ambient_light(); int VX_light_dynamic_add( VX_light * l ); void VX_light_remove( int idx ); void VX_lights_clear(); VX_uint32 VX_lights_count(); VX_light * VX_lights_enumerate(); Struktura pro dynamické světlo je zavedena potom takto. typedef struct VX_light{ float pos[3]; VX_uint32 clr; VX_light; Poznámky k optimalizacím softwarového vykreslování Dokonalosti je dosaženo nikoli ve chvíli, kdy už není co dodat, ale ve chvíli, kdy už není nic, co by se dalo vypustit. (Antoine de Saint- Exupéry) 43

44 Výkon současných procesorů silně zaostává za výkonem výpočetních a grafických čipů. Z toho důvodu je legitimní zabývat se optimalitou kódu zejména v grafických úlohách, které jsou extrémně závislé na propustnosti systému. Během programování knihovny jsem použil několik zajímavých technik, které omezují selhání výpočetní pipeline procesoru a tím zvyšují množství teoreticky provedených instrukcí za takt. Na výslednou rychlost programu má také nezandebatelný vliv kompilátor a nastavení jeho optimalizačních voleb. Knihovnu kompiluji pomocí kompilátorů gcc a clang Akcelerující techniky První podmínkou pro dobrý výkon programu je zamezení redundance výpočtů uvnitř funkcí, protože redundance znemožňuje vícenásobné použití již vypočtených výsledků. Dobrou praxí je tedy vytváření vazeb ve vhodném prostředí na známé výsledky operací, pokud víme, že budou potřeba na více místech. Tyto neduhy však za dobré konstelace může odhalit sám kompilátor a provést nápravu za programátora. Příklad špatně napsaného kódu může vypadat takto. int spatna_fce( int a, int b ){ int c = 0; while( c < 100 ){ c += (a*b); return c; Další technikou je používání klíčového slova static pro funkce a globální proměnné a klíčové slovo inline pro funkce. Používání klíčového slova static vede k omezení platnosti globálního názvu pouze na oblast zdrojového souboru, což opět může znamenat výhodu pro kompilátor, zejména podporuje-li tzv. link time optimalizaci. Kompilátor může například statickou proměnnou obsadit nějaký registr, pokud ví, že daná funkce s takovou proměnnou často pracuje. V případě funkcí je klíčové slovo static výhodné, protože funkce pak nemusí splňovat standardní volací konvenci. Další výhodou, spíše estetickou, je skutečnost, že ABI (application binary interface) programu je méně rozsáhlé. Klíčové slovo inline se používá zejména pro krátké procedury a funkce, u kterých je předpoklad, že zavolání představuje nemalou část celkové délky podprogramu. Velké funkce a procedury nemá obvykle cenu opatřovat klíčovým slovem inline, protože to obvykle vede ke špatné alokaci registrů. Všechny významné soudobé procesory podporují tzv. pipelining. To je technika, která umožňuje procesorům provádět v jednom taktu více operací najednou a zaměstnávat tak co možná nejvíce svých subsystémů. Slabina této techniky tkví ve špatné součinnosti s větvením kódu. Při větvení kódu totiž nelze s jistotou odhadnout, kterou větví se program vydá. V případě, že se vykonávání programu 44

45 vydá neočekávanou větví, je nutné zahodit výsledky z této větve a vydat se tou správnou, což samozřejmě stojí instrukce navíc. Z hlediska programu je tedy vhodné se co nejvíce větvení vyhýbat. Řešením u výpočetních úloh je často převod větvení na nějaký aritmetický výraz, který může být ve výsledku rychlejší než větvení. Rozsáhlé if-else výrazy lze také často převést na výrazy typu switch, které může dále kompilátor převést na lookup tabulku skoků. Dobrou praxí je také seřadit if-ifelse-else výrazy podle očekávané pravděpodobnosti splnění podmínky. Tím se program vyhne ve většině případů zbytečnému testování a zbytečným skokům. V podmínkách if výrazů se také často používá tzv. short-circuiting technika (používání výrazů a && místo a &), což je syntaktický cukr, který může přispět k složitějšímu větvení, pokud tomu však nezamezí kompilátor. Větvení naopak může být výhodné použít, zamezuje-li včas složitějšímu výpočtu (early termination). Další diskutabilní záležitostí je používání ukazatelů. U procesorů, které používají virtuální adresní prostor, může být práce s ukazately poměrně drahá. Předávání argumentů pomocí pointerů se obecně považuje za výhodné tehdy, pokud by předání zásobníkem stálo příliš kroků. Tudíž obecně nemá smysl předávat hodnoty typu int, float ukazatelem (není-li na tom jiný zájem). Naopak struktury, hlavně ty rozsáhlé, má smysl předávat ukazatelem vždy. Nakonec ještě zmíním rychlost výpočtů s celými čísly ve srovnání s čísly s plovoucí čárkou. Výkon FPU (floating point unit) se může lišit podle výrobce a podle cenového segmentu daného výrobku. Nicméně v současnosti obecně platí, že FPU výpočty jsou srovnatelně rychlé s celočíselnými výpočty. Navíc díky SIMD rozšířením typu SSE a AVX jsou moderní procesory schopné provádět několik FPU výpočtů současně. Při použití těchto specializovaných instrukcí jsou výsledné programy i několikanásobně rychlejší než jejich celočíselné nebo fixed-point alternativy. Velký podíl na finálním výkonu má kompilátor, případně ruční přepis do assembleru. Knihovnu VoXen kompiluji svobodnými kompilátory gcc a clang. Oba používají přibližně stejné parametry. Parametry, které mají zásadní vliv na výkon jsou O0, O1,..., O3. Přičemž nejvyšší úroveň optimalizací (kompilace také trvá nejdéle) je O3. Tato úroveň je použita i pro účely kompilace knihovny Vo- Xen. Důležitými volbami jsou dále ty, které specifikují cílovou platformu a typ použité FPU jednotky. Volba -march způsobí zpětnou kompatibilitu kódu až k uvedenému typu procesoru nebo architektuře, knihovna VoXen je kompilována standardně jako i686 kompatibilní. Nejrychlejší a současně nejvíce omezující volbou je native, kdy kompilátor může využít všech instrukcí a registrů stroje, na kterém se kompiluje za cenu nekompatibility s jinými procesory. S volbou -march souvisí také volba -mtune, která nemění kompatibilitu, ale pokouší se o specifické optimalizace pro danou architekturu i s ohledem na organizaci pipeline, nejrychlejší volba je opět native. Výběr FPU jednotky je možný volbou -mfpmath, knihovna VoXen ji používá pouze volitelně kvůli zpětné kompatibilitě. Pro účely softwarového provozování knihovny VoXen je vysoce doporučeno zapnout nativní 45

46 volby nebo alespoň provozovat sestavení s podporou SSE instrukcí Vícevláknové vykonávání Současné procesory již řadu let nezaznamenávají prakticky žádný nárůst frekvence, produkční pokoření hranice 5GHz je stále v nedohlednu. Vývoj se tedy ubírá směrem navyšování počtu procesorových jader. Což sice přináší jisté navýšení výkonu, avšak za cenu složitějšího kódu a výhledově omezení v podobě Amdahlova zákona (od jisté hranice již navýšení počtu procesorů nepřinese žádný nárůst výkonu). Výhodou raytracingu je jeho přímočarý přepis do paralelní podoby, vždyť právě proto má smysl raytracing provozovat na grafických kartách, které jsou velmi silné ve výpočtech krátkých paralelních programů nad velkými daty. V softwarové části knihovny VoXen je vybudován blokující mechanizmus, který vytvoří jen tolik vláken, kolik je skutečně zapotřebí. Když předá uživatel t vláken, ve skutečnosti má smysl vytvořit t 1 vláken a jednu část vykonávat v tom vlákně, které způsobilo vytvoření zbylých vláken. Výhoda spočívá jednak v tom, že nedojde ke zpomalení na jednojádrových systémech a jednak nevytvoříme víc vláken, než je potřeba. Tím zbytečně nezatěžujeme plánovač systému a omezíme přepínání kontextů. V knihovně VoXen již vytvořená vlákna existují až do explicitního ukončení, protože vytváření vláken je pro algoritmy pracující v reálném čase příliš drahé. Třída pro práci s vlákny je definována takto. typedef struct VX_field{ int peasants_count; int destroy_p; VX_peasant * workers; void (*enter)(struct VX_field*, void ** params, void (*funcs[])(void *) ); void (*destroy)(struct VX_field*); VX_field; VX_field * VX_field_new( int peasants_count ); Konstruktor VX_field_new vytvoří peasants_count-1 vláken, které čekají na práci, hodnota menší než 1 má nedefinované chování. Metoda enter spustí výpočet nad params, což jsou parametry pro jednotlivá vlákna a toto pole musí obsahovat právě peasants_count položek, pole funkcí funcs musí mít stejnou délku jako pole parametrů params. Položky pole func jsou ukazatele na jednotlivé funkce, které mají být provedeny ve zvláštních vláknech. Po zavolání této funkce dojde k paralelnímu výpočtu funkcí a po návratu z metody je zajištěno, že všechny funkce již byly vypočítány a vlákna čekají na další práci. Metoda destroy provede ukončení běhu vláken a korektně uvolní objekt. 46

47 7. Dosažené výsledky Za hlavní výstup této práce považuji knihovnu VoXen, která představuje dobrý základ pro produkční použití v různých oborech informatiky. Tato kapitola se zabývá třemi aplikacemi, které jsou vybudovány nad knihovnou VoXen a mohou sloužit jako tutoriálové příklady dokumentující funkcionalitu knihovny. Kapitola se dále zabývá spuštěním a základním používáním těchto aplikací. Kompletní návod k použití je pak vždy součástí jednotlivých aplikací formou nápovědy vytištěné na standardní výstup. Dále jsou zde zmíněny technické detaily sestavení aplikací i knihovny, softwarové požadavky a je zmíněna licence, pod kterou jsou šířeny jednotlivé soubory. Nakonec jsou uvedena různá kvalitativní srovnání v různých ohledech Sada testů knihovny VoXen Pro udržení konzistentního chování knihovny jsem implementoval sadu několika testů klíčových vlastností knihovny VoXen. Krátké testovací algoritmy se zaměřují zejména na testování základních výpočtů, jako je maticové násobení, správné nacházení průsečíků a operace s bounding boxy. Dále se zaměřuje na ověření správnosti reprezentace obrazu pomocí různých modelů, zde je otestována správnost kompilace obrazu, čtení a zápis voxelů a ukládání do souboru. Sada testů dál ověřuje funkčnost dvou implementovaných ovladačů VX_DRV_sdl a VX_DRV_null, zde sleduje jejich korektní vytvoření, ukončení a správnou manipulaci s obrazovými povrchy. Poslední objekt, který je otestován je kamera provádějící raytracing, zejména se zde sleduje její korektní vytvoření, ukončení a možnost provést vykreslení. Samotný program je pak jen nástroj pro příkazovou řádku, který nebere žádné argumenty a vypisuje na standardní výstup informace o provedených testech, případně velmi podrobně vypisuje chyby. Použití programu je jednoduché na testovacím stroji s povolenou knihovnou OpenCL dopadne spuštění knihovny následujícím způsobem. $./testvoxen VoXen tests... ms_block( 0, 0, 0, 256, 256, 256 ) ms_block( 64, 64, 64, 128, 128, 128 ) info: initializing NULL_Drv driver info: initializing SDL driver Raw model stats: total B used: info: stack-top: Octree info: size 32 x 32 x 32 Octree stats: nodes total B used: leaf: octree size: 32 info: initializing NULL_Drv driver 47

48 platform count: 1 build: (ocl) OpenCL compilation process returned >>>> tests executed: 9 passed: 9 failed: 0 skipped: Testovací aplikace Testovací aplikace je program se dvěma režimy. Prvním a výchozím režimem je textový režim, který umožňuje nastavovat základní parametry scény z příkazové řádky pomocí předdefinovaných příkazů. Druhý režim je grafický, kde dochází k vykreslování scény a je zde možné interagovat se scénou pomocí klávesnice a myši. Aplikace se spouští z příkazové řádky takto. $./testapp Při spuštění lze argumenty ovlivnit velikost okna, ve kterém se bude provádět vykreslování. Implicitní hodnotou je zde rozlišení Příklad, jak lze nastavit velikost okna na hodnotu je následující (vede k navýšení výkonu). $./testapp --resolution Aplikace také akceptuje argumenty --help a --version pro výpis nápovědy a verze, tyto argumenty musí být prvním argumentem, aby byly vzaty v potaz. Po spuštění aplikace dojde k přepnutí do příkazového režimu a současně se objeví vykreslovací okno, které je prázdné. V textovém režimu jsou akceptovány následující příkazy. quit ukončí aplikaci. load octree načte octree soubor.oct. load raw načte raw model z raw souboru. set camera nastaví kameru. help vytiskne nápovědu k příkazům. toggle fullscreen přepíná celoobrazovkový režim. list lights vypíše dynamická světla. add light přidá dynamické světlo do scény. remove light odstraní dynamické světlo ze scény. 48

49 set ambient nastaví ambientní světlo. inspect ambient vypíše barvu ambientního světla. run přepne vykonávání do grafické části aplikace a začne zaznamenávat demo. benchmark vytiskne výkonnostní shrnutí od posledního spuštění pomocí run nebo run demo. save demo uloží demo do souboru, použije se poslední známý pohyb kamery. load demo načte demo ze souboru. run demo spustí poslední známé demo, které mohlo být načteno ze souboru nebo bylo vygenerováno příkazem run a následnou interakcí. Po potvrzení některých příkazů dochází k další interakci s uživatelem, aby přes standardní vstup zadal srozumitelně další dodatečné argumenty. Uvedu několik příkladů. > load_octree enter path:../data/myhead.oct Select traversal method: (1) kd-restart (2) kd-backtrack (3) kd-shortstack (half stack length) > 3 Octree info: size 512 x 512 x 512 Octree stats: nodes total B used: leaf: V tomto případě došlo k načtení obrazu umístěného na cestě../data/myhead.oct, tento obraz může být zobrazen pomocí příkazu run nebo run_demo, je-li přítomen nějaký demo záznam. > set_camera Options: (1) Reset to default (2) Set position (3) Set matrix 2 Enter new camera position enter vector/point components in X Y Z order Tato interakce s programem způsobí nastavení kamery na pozici 128, 128, 128. Pomocí příkazu set_camera lze dále resetovat nastavení kamery na výchozí hodnoty, kdy poloha je 0, 0, 0 a transformační matice je jednotková matice. Poslední 49

50 volba umožňuje nastavit libovolnou matici po sloupcích, sloupce ale budou normalizovány. Poslední příklad vytvoří dynamické světlo, které se bude pohybovat po kruhové trajektorii. > add_light Light creation Enter ARGB color by its components: Enter light position: enter vector/point components in X Y Z order Should be this light truly dynamic? [1,0] 1 Enter radius midpoint: enter vector/point components in X Y Z order Enter rotation axis: enter vector/point components in X Y Z order Enter rotation speed in radians/second 2 Zde je nejprve potřeba naplnit barvu světla, zde je zvoleno bílé světlo. Následuje zadání pozice světla, poté je třeba zadat pravdivostní hodnotu 0 nebo 1. V případě, že uživatel zadá 0, proces přidávání světla zde končí. V opačném případě se světlo nastaví tak, aby obíhalo po kruhové trajektorii. Zde je třeba vložit střed otáčení, dále osu otáčení a rychlost otáčení v radiánech za sekundu. Poznamenejme, že ve výchozím stavu je ambientní světlo nastaveno na bílou barvu, tudíž je potřeba zredukovat tuto barvu, aby byly patrné stíny vržené dynamickým světlem. Přenastavení ambientního světla se provede příkazem set_ambient. Do grafického režimu se lze dostat pouze příkazem run nebo run_demo a musí být splněna podmínka, že byl načten nějaký model pomocí příkazu load_octree nebo pomocí load_raw. V případě raw modelu není implementováno nasvětlování a v případě opuštění bounding-boxu modelu dojde ke zmizení modelu (není implementován ořez paprsků). Ve scéně v režimu run lze kameru natáčet pomocí myši tak, jak bývá u 3D editačních programů zvyklé. Pohyb ve směru kamery se docílí pomocí klávesy w, pohyb proti směru kamery potom pomocí s. Úkroky do stran se provádějí pomocí kláves a a d. Pro přepnutí z grafického režimu zpět do textového režimu slouží klávesa Esc, při nízkém počtu snímků za sekundu je třeba ji podržet déle nebo ji zmáčknout i několikrát, to je způsobeno omezením knihovny SDL a přímého přístupu do bufferu klávesnice. V režimu run se ukládá demo záznam pozice a natočení kamery a pozice světel pro každý vykreslený snímek, předchozí demo záznam bude smazán a nahrazen tímto. Demo záznam je mechanizmus určený pro měření výkonu nad stejnou sadou snímků 50

51 tak, aby výsledek nebyl zkreslen. Aktuální demo záznam lze nahradit příkazem run nebo načtením demo záznamu ze souboru pomocí příkazu load_demo, demo záznam lze ukládat pomocí save_demo. Spuštění aktuálního demo záznamu lze provést příkazem run_demo, zde je třeba ještě přidat informaci o maximálním počtu povolených světel ve scéně, to je vhodné pro měření výkonu vzhledem k počtu světel. Spuštěný demo záznam lze předčasně ukončit klávesou Esc. K programu jsou přiloženy čtyři demo záznamy s názvy odpovídajícími testovacím modelům s příponou.dem, například tedy existuje demo voxelstein.dem. Při každém grafickém běhu se shromažďují údaje o výkonu, které lze vytisknout na standardní výstup příkazem benchmark Konverzní utilita Jedná se o malý program napsaný také pod knihovnou VoXen, slouží k převodům voxelových dat do různých formátů. Jako zdrojový obraz je podporován raw model, octree model,.vxl soubor nebo výčet 2D obrázků ve formátu podporovaném knihovnou SDL_image. Jako výstupní formát je možné zvolit octree nebo raw model. Typ vstupních dat se určuje podle následujících argumentů. -oct bude předpokládat octree soubor bezprostředně za tímto argumentem. -vxl bude předpokládat.vxl soubor bezprostředně za argumentem. -set předpokládá konečný výčet 2D obrázků reprezentující řezy, pořadí bude zachováno. -raw bezprostředně musí následovat informace o šířce, výšce a hloubce a parametr pro barvový formát (-t pro true-color, -g pro černobílý obraz s pixelem velikosti 1B, -argb pro ARGB32 barvy). Za vstupním argumentem a jeho volbami následuje volba výstupního formátu, zde je přípustné předat pouze -oct nebo -raw a bezprostředně poté následuje cesta k výstupnímu souboru. Případné další argumenty jsou ignorovány. Při nesprávném předání argumentů dojde k řízenému ukončení utility. Nakonec uvedu ještě krátké příklady praktického použití. $./voxconv -vxl untitled.vxl -oct untitled.oct octree size: 1024 info: stack-top: Octree info: size 1024 x 1024 x 1024 Octree stats: nodes total B used: leaf: Vstupem tohoto příkladu je.vxl soubor untitled.vxl a ten je zkonvertován do formátu octree, cesta k výstupnímu souboru je untitled.oct. 51

52 $./voxconv -set../data/teacup/*.png -oct teacup.oct../data/teacup/00cup.png../data/teacup/01cup.png../data/teacup/02cup.png../data/teacup/03cup.png../data/teacup/04cup.png../data/teacup/05cup.png../data/teacup/06cup.png../data/teacup/07cup.png../data/teacup/08cup.png../data/teacup/09cup.png../data/teacup/10cup.png../data/teacup/11cup.png../data/teacup/12cup.png../data/teacup/13cup.png../data/teacup/14cup.png../data/teacup/15cup.png../data/teacup/16cup.png../data/teacup/17cup.png../data/teacup/18cup.png../data/teacup/19cup.png in_count: 20 octree size: 32 info: stack-top: Octree info: size 32 x 32 x 32 Octree stats: nodes 6262 total B used: leaf: 5066 Tento příklad dostane na vstupu skrze regulární výraz obrázky, které převede do octree teacup.oct Poznámky ke kompilaci a ke kompatibilitě Kompilace knihovny i všech programů je prováděna pomocí nástroje GNU/Make. Soubor Makefile je umístěn v adresáři se zdrojovými kódy. Míru optimalizace lze určit pomocí několika předdefinovaných voleb: all základní kompatibilní kompilace pomocí gcc a se zapnutou volbou -O3. clang stejné jako volba all, pouze je použit kompilátor clang. fastgcc nekompatibilní kompilace určená pouze pro stroj, na kterém se kompiluje a pro stroje s ním kompatibilní. fastclang stejné jako fastgcc, pouze se použije clang. 52

53 debug kompilace pomocí nástroje gcc se zapnutými debugovacími symboly a optimalizační úrovní -O0. sse sestavení proběhne pomocí nástroje clang se zapnutými sse instrukcemi. Tento soubor Makefile však pouze volá další kompilační soubory, tudíž lze kompilovat libovolnou část s libovolnými parametry. Jako příklad uživatelské kompilace uvádím kompilaci všech částí pomocí nástroje clang pro debugovací účely. $ cd./voxen/ && make CC="clang" CFLAGS="-O0 -g" && cd../tests/ && make CC="clang" CFLAGS="-O0 -g" && cd../testapp/ && make CC="clang" CFLAGS="-O0 -g" && cd../conversion_tool/ && make CC="clang" CFLAGS="-O0 -g" && cd.. Pro reálné nasazení je velmi vhodné provést kompilaci s maximálními optimalizačními volbami a jako výhodnější se ukazuje použít kompilátor clang. Pro úspěšnou kompilaci je dále třeba mít nainstalován alespoň jeden kompilátor jazyka C99 a příslušné vývojové hlavičkové soubory a knihovny. Dále je třeba mít nainstalovanou knihovnu SDL a SDL_image, včetně hlavičkových souborů. Knihovna VoXen je linkována se všemi aplikacemi staticky, dynamická knihovna.so je však také dostupná Testování, spuštění a známé chyby V současné době je knihovna bezpečně provozovatelná pouze na systémech založených na jádře GNU/Linux a procesorech rodiny Intel i386. Velmi pravděpodobně však bude po překompilování funkční i na jiných unixových platformách a velmi pravděpodobně bude funkční i 64-bitová verze knihovny. Zcela určitě však knihovna nebude správně fungovat na platformách používajících big endian řazení bytů, to je zapříčiněno některými specifickými optimalizacemi knihovny, které jsou korektní pouze na little endian systémech. Systémy rodiny Windows nejsou podporovány z důvodu nekompatibility s knihovnou pthread. Pro aplikace postavené nad knihovnou VoXen tudíž platí stejná omezení. Knihovna i všechny přiložené programy byly řádně otestovány a nevyskytuje se v nich žádná známá chyba. K testování a odhalování chyb byl použit nástroj gdb a valgrind ke sledování korektní manipulace s pamětí. Pro profilování kódu jsem použil nástroj callgrind a grafickou nadstavbu KCacheGrind. Testování probíhalo pod operačním systémem Ubuntu s 32-bitovým jádrem a zapnutým pae režimem. Pro spuštění všech aplikací je třeba mít nainstalovány 32-bitové varianty knihovny SDL verze 1.2 a knihovnu SDL image verze 1.2. V operačních systémech rodiny Ubuntu lze tyto knihovny opatřit následujícím příkazem (u 64-bitových verzí Ubuntu je třeba přidat :i386). # apt-get install libsdl1.2debian libsdl-image1.2 53

54 Případné další nesplněné závislosti lze opatřit nástrojem ldd, to se týká jiných operačních systémů založených na jádře GNU/Linux. Programy musí být opatřeny příznakem spustitelnosti tak, jak bývá v unixových systémech zvykem, proto nelze žádný program spustit přímo z datového média, ale musí být překopírovány na oddíl, který podporuje oprávnění. Správné nastavení oprávnění zajistíme následujícím příkazem použitým na spustitelný soubor EXECUTABLE. $ chmod +x EXECUTABLE 7.6. Dokumentace knihovny VoXen Knihovna je dokumentovaná pomocí nástroje Doxygen, který umožňuje export do formátu html nebo pdf pomocí L A TEX. Rozsah dokumentace pokrývá všechny veřejné funkce, struktury a jiná primitiva, vnitřní struktury a funkce jsou ponechány bez dokumentace. Soubory s dokumentací jsou součástí datového média Licence a kopírování V současné chvíli držím zdrojové kódy pod nesvobodnou licencí, zdrojové kódy však v budoucnu velmi pravděpodobně uvolním pod licencí GNU/GPLv3, pokud o ně projeví zájem komunita. Všechny binární soubory mohou být kopírovány bez vědomí autora pro nekomerční účely. Některé obrazové materiály (voxelstein a voxlap) podléhají licenci třetích stran, zbylé obrazové materiály jsou šířeny pod licencí Creative Commons CC BY. Podrobnosti o licencích jsou uvedeny v souborech LICENSE Obrazové podklady Voxelové obrazové podklady nejsou zcela běžně dostupné, zejména pokud jde o medicínská data. Na ta se totiž vztahují právní omezení. Nakonec jsem tedy za přispění svého vedoucího práce dospěl k tomu, že nejlepší bude opatřit si data na základě skenu vlastního těla. Což mi bylo laskavě umožněno v nemocnici U svaté Anny v Brně, kde jsem se zapojil do výzkumného projektu zaměřeného na sledování aktivity mozku, coby dobrovolník. Samotný sken byl proveden pomocí magnetické rezonance a s nasazenou EEG čepicí, která měří aktivitu mozku. Příprava na skenování zahrnovala připojení senzorů sledujících činnost srdce (EKG), následné nasazení čepice s elektrodami, které byly vodivě spojeny nemalým množstvím odolného gelu s pokožkou hlavy. Následné vyšetření bylo provedeno v tunelu. Zde byl nejprve proveden NMR snímek, následoval klidový stav, kdy byla sledována aktivita mozku při zavřených očích. Poté byl proveden příčný sken a následovala série jednoduchých otázek s otevřenýma očima. Otázky s jistou pravděpodobností obsahovaly gramatické nebo sémantické chyby, případně se jednalo 54

55 pouze o sekvence znaků X. Toto celé trvalo bezmála hodinu za celkové nehybnosti pro korektní výstupy. Následná data jsem na základě svého přání získal jako sekvence černobílých bmp obrázků. Kvalitu snímků v oblasti kolem uší bohužel poněkud zredukovala nasazená sluchátka. Výsledná data jsem vyfiltroval pomocí high-pass filtru, který propustí jenom barvy dostatečně blízké bílé barvě, tím se obraz relativně efektivně zbaví šumu. Tento test se v měřeních označuje jako myhead. Na obrázku 4. je jeden podélný řez hlavou a na obrázku 5. je již patrný výsledek raytracingu. Obrázek 4. Obrázek získaný z magnetické rezonance. Dalším zdrojem dat mi byla testovací aplikace ke knihovně Voxlap, která obsahuje poměrně rozsáhlý model představující terén s domem a několika dalšími objekty. Pro dodržení licence poznamenejme, že se jedná o dílo převzaté z knihovny VOXLAP vytvořené Kenem Silvermanem ( a její šíření je vázáno na nekomerční použití. Tato převzatá data jsou exportována z vxl souboru a v testech se objevují pod názvem voxlap. Nejkomplexnějším modelem je model mapy z otevřené hry Voxelstein 3D která je založena na knihovně VO- XLAP a je šířená pod MIT licencí. Tento model opět vznikl exportem z vxl modelu. V testech se jeho označení objevuje jako voxelstein. Posledním a současně nejjednodušším modelem je model krychle, který slouží zejména pro testovací účely a pro zjištění nejvyšší rychlosti raytracingu na daném 55

56 Obrázek 5. Vykreslený model hlavy. stroji. Test označuji jako simple Srovnání V této kapitole jsou provedena měření na několika modelech, sledovat budu zejména paměťovou náročnost konkrétních modelů a průměrný počet snímků za sekundu v softwarovém režimu vzhledem k několika algoritmům. Obrazovou kvalitu zkonfrontuji s již existujícími implementacemi a vyjádřím se k možnému zlepšení kvality za pomocí pokročilých nasvětlovacích technik. Testování probíhalo na stroji se čtyřjádrovým procesorem AMD Phenom(tm) II X4 B55 Processor 3.3GHz, osazeným 4GB pamětí RAM (1333 Mhz). Softwarové vybavení bylo Ubuntu (32-bit) s linuxovým jádrem 3.8.x-generic i686. Knihovna byla kompilována s optimalizačními parametry -O3 -mtune=native -march=native pomocí nástrojů gcc verze a clang verze Srovnání paměťové náročnosti Data zde uvedená jsou získána na základě zjištění velikosti souborů a pomocí metody inspect. Kompresní poměr C p počítám následujícím výrazem: C p = M c M o, kde M c je velikost komprimovaného souboru v bajtech a M o je velikost původního souboru v bajtech. Pokud dostáváme výsledek C p < 1 je zkomprimovaný 56

57 Obrázek 6. Model z testovací aplikace knihovny VOXLAP (od Kena Silvermana). soubor menší než původní, v opačném případě se jedná o zápornou komprimaci, komprimací se zabývá tabulka 2. Velikost souborů a jejich následných otisků v paměti počítače ukazuje tabulka 1. Detailnější pohled na poměr mezi listovými a všemi uzly octree ukazuje tabulka 3. Název testu Rozměry obrazu Raw formát Octree formát simple GB 4KB voxlap GB 44MB voxelstein GB 205MB myhead MB 71MB Tabulka 1. Tabulka srování velikosti souborů podle modelů. Ze srovnání jasně vyplývá, že řídké modely velmi dobře využívají potenciálu octree a na těchto obrazových podkladech se kompresní poměr pohybuje pod 20% Srovnání časové náročnosti Tato kapitola shrnuje výsledky časových nároků na vykreslení snímků. Všechny testy jsou provedeny při rozlišení z důvodu rozumné rychlosti softwarového vykreslování. Tabulka 4. sleduje výkon různých algoritmů na různých datech a bez dynamických světel. Na základě této tabulky se lze domnívat, že algoritmy pracující se zásobníkem (kd-backtrack a kd-shortstack) nepřinášejí 57

58 Obrázek 7. Pohled na mapu ze hry Voxelstein. Název testu Kompresní poměr simple 0, voxlap 0, voxelstein 0, myhead 0, Tabulka 2. Tabulka kompresního poměru. žádnou velkou výhodu co do rychlosti vykreslování. Jejich výhoda však nespočívá v navýšení průměrných hodnot FPS, ale ve snížení maximální doby pro vykreslení snímku, jak o tom vypovídá tabulka 6. za cenu zvýšení minimální doby pro vykreslení snímku. Algoritmy kd-shortstack a kd-backtrack se jeví jako vhodnější hlavně v komplexních scénách, kde dokonce způsobí mírné navýšení průměrného počtu snímků za sekundu (voxelstein). Tabulka 5. je stejná jako předchozí, avšak v těchto testech je zapnuto dynamické osvětlení pomocí jednoho světla. Výsledky jsou poměrně očekávatelné, výkon poměrně razantně poklesl v závislosti na umístění zdroje světla. Výkon také nejstrměji klesal u velmi komplexních dat, zde byl téměř poloviční. Výsledky měření se blíží výsledkům ze článku [9], přestože tato implementace byla hardwarová. Autor této práce však zaznamenal o něco patrnější výhodu algoritmu kd-shortstack. To lze vysvětlovat nižší cenou matematických výpočtů na GPU a vyšší cenou přístupu do paměti, protože algoritmy kd-shortstack a kd-backtrack právě redukují počet přístupů do paměti za cenu vyšší výpočetní 58

59 Obrázek 8. Jednoduchý testovací model. Název testu Celkový počet uzlů octree Počet listových uzlů simple 3 1 voxlap voxelstein myhead Tabulka 3. Tabulka srování počtu všech uzlů octree s počtem listových uzlů. složitosti Srovnání obrazové kvality Srovnání obrazové kvality je poměrně subjektivní záležitost. Navíc jediný případ, kdy se může lišit obrazový výstup knihovny VoXen, je při použití raw modelu (vzhledem k použití zobecněného Bresenhamova algoritmu). Pro ilustraci tedy přikládám srovnání na stejných datech reprezentovanými octree modelem a raw modelem, rozdíl je znározněn na obrázku 9. Následuje ukázka výstupu z velmi pokročilé implementace ze článku [3], jedná se o obrázek 10. Další obrázek pochází z práce Kristofa Römische [9], jeho implementace je co do kvality obrazových výstupů velmi podobná mé implementaci, obrázek 11. pochází z jeho práce. 59

60 Obrázek 9. Rozdíl v kvalitě raycastingu mezi syrovým modelem (velvo) a octree modelem (vpravo). Obrázek 10. Obrazový výstup ze článku GigaVoxels. 60

61 Test kd-restart kd-backtrack kd-shortstack simple 38,18 20,80 20,80 voxlap 8,87 8,81 8,34 voxelstein 5,47 5,83 5,52 myhead 10,41 9,47 8,96 Tabulka 4. Tabulka srování průměrných FPS v softwarové implementaci vzhledem k různým algoritmům a pouze s ambientním osvětlením. Test kd-restart kd-backtrack kd-shortstack simple 26,54 16,77 16,64 voxlap 5,30 5,80 5,56 voxelstein 3,00 3,48 3,31 myhead 7,82 7,53 7,18 Tabulka 5. Tabulka průměrných hodnot FPS s jedním dynamickým světlem. 8. Diskuze Kapitola zkonfrontuje mou implementaci s jinými již existujícími implementacemi a nastíní nedostatky a přednosti mé implementace Srovnání s jinými projekty Má práce poskytuje podobné výstupy jako práce [9], nicméně autor nijak nedokumentuje svůj kód, ani nenabízí žádnou knihovnu jako výstup své práce. Tudíž není možné využít v jiném projektu jeho kód, navíc je jeho kód psán výhradně pro platformu Windows díky vazbám na DirectX a HLSL. Tato implementace dokonce ani neumí ukládat octree na disk a podle jeho práce je nutné vždy nejprve octree zkompilovat. Díky hardwarové implementaci v HLSL je však rychlejší. Dalším projektem je program napsaný spolu s článkem [3]. Tento program je napsaný firmou NVIDIA pod platformou CUDA a MS Windows, což je samo o sobě limitující. Navíc neposkytují žádné API pro svoji práci, tudíž se vlastně jedná o další ad-hoc řešení, které by se jen težko zabudovalo do jiné aplikace. Na druhou stranu je tato implementace velmi pokročilá, zejména v oblasti kvality obrazu Možnosti využití dosažených výsledků V současné době lze knihovnu nepochybně použít pro implementaci prohlížeče 61

62 Test kd-restart kd-backtrack kd-shortstack simple 64/17 73/34 81/33 voxlap 332/20 285/39 288/40 voxelstein 292/28 281/39 280/41 myhead 187/20 187/22 200/23 Tabulka 6. Tabulka nejhorších a nejlepších časových výsledků (v milisekundách), údaje jsou bez dynamických světel. Obrázek 11. Obrazový výstup z práce Kristofa Römische. CT nebo NMR snímků, na rozumně výkonných strojích lze bez problémů dosahovat poměrně vysokých FPS. V současné době se rozvíjí tzv. 3D tisk, i v této oblasti si umím představit aplikaci napsanou pod knihovnou VoXen, která by sloužila k editaci modelů a byla by analogií k 2D rastrovým editorům. V případě reimplementace některých kritických výpočtů knihovny VoXen pod platformou OpenCL by mohla knihovna sloužit i v počítačových hrách Možnosti dalšího rozšíření knihovny VoXen Základní API knihovny bylo stanoveno a byla implementována základní funkcionalita, která je do značné míry ověřena sadou testů. Hlavní cíl dalšího vývoje spatřuji v zahrnutí podpory OpenCL, které by nahradilo softwarový raytracing, přínos takového opatření bude spočívat ve značném nárůstu výkonu. V současné 62

Optimalizace vykreslování voxelové grafiky

Optimalizace vykreslování voxelové grafiky KMI 24. listopadu 2014 Voxelová grafika Zobecnění rasterové grafiky do 3D (zobecnění pojmu pixel na pojem voxel). Konkurence k povrchové (polygonové reprezentaci). Výhody: skutečná hloubka (schopnost zachytit

Více

Osvětlování a stínování

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

Více

5 Rekurze a zásobník. Rekurzivní volání metody

5 Rekurze a zásobník. Rekurzivní volání metody 5 Rekurze a zásobník Při volání metody z metody main() se do zásobníku uloží aktivační záznam obsahující - parametry - návratovou adresu, tedy adresu, kde bude program pokračovat v metodě main () po skončení

Více

Pokročilé metody fotorealistického zobrazování

Pokročilé metody fotorealistického zobrazování Pokročilé metody fotorealistického zobrazování 14.5.2013 Úvod Motivace Základní informace Shrnutí metod Představení programu RayTracer Reference Motivace Základní informace Motivace snaha o vytvoření realistických

Více

Katedra informatiky, Univerzita Palackého v Olomouci. 27. listopadu 2013

Katedra informatiky, Univerzita Palackého v Olomouci. 27. listopadu 2013 Katedra informatiky, Univerzita Palackého v Olomouci 27. listopadu 2013 Rekonstrukce 3D těles Reprezentace trojrozměrných dat. Hledání povrchu tělesa v těchto datech. Představení několika algoritmů. Reprezentace

Více

PB001: Úvod do informačních technologíı

PB001: Úvod do informačních technologíı PB001: Úvod do informačních technologíı Luděk Matyska Fakulta informatiky Masarykovy univerzity podzim 2013 Luděk Matyska (FI MU) PB001: Úvod do informačních technologíı podzim 2013 1 / 29 Obsah přednášky

Více

Surfels: Surface Elements as Rendering Primitives

Surfels: Surface Elements as Rendering Primitives Surfels: Surface Elements as Rendering Primitives Výzkum v počítačové grafice Martin Herodes Nevýhody plošných primitiv Reprezentace složitých objektů pomocí plošných primitiv (trojúhelníků, čtyřúhelníků

Více

Animace a geoprostor. První etapa: Animace 3. přednáško-cvičení. Jaromír Landa. jaromir.landa@mendelu.cz Ústav informatiky PEF MENDELU v Brně

Animace a geoprostor. První etapa: Animace 3. přednáško-cvičení. Jaromír Landa. jaromir.landa@mendelu.cz Ústav informatiky PEF MENDELU v Brně Animace a geoprostor První etapa: Animace 3. přednáško-cvičení Jaromír Landa jaromir.landa@mendelu.cz Ústav informatiky PEF MENDELU v Brně Náplň přednáško-cvičení Nasvícení scény Světelné zdroje umělé

Více

Textury v real-time grafice. 2004-2005 Josef Pelikán, MFF UK Praha http://cgg.ms.mff.cuni.cz/~pepca/ Josef.Pelikan@mff.cuni.cz

Textury v real-time grafice. 2004-2005 Josef Pelikán, MFF UK Praha http://cgg.ms.mff.cuni.cz/~pepca/ Josef.Pelikan@mff.cuni.cz Textury v real-time grafice 2004-2005 Josef Pelikán, MFF UK Praha http://cgg.ms.mff.cuni.cz/~pepca/ Josef.Pelikan@mff.cuni.cz Textury vylepšují vzhled povrchu těles modifikace barvy ( bitmapa ) dojem hrbolatého

Více

Intervalové stromy. Představme si, že máme posloupnost celých čísel p 0, p 1,... p N 1, se kterou budeme. 1. Změna jednoho čísla v posloupnosti.

Intervalové stromy. Představme si, že máme posloupnost celých čísel p 0, p 1,... p N 1, se kterou budeme. 1. Změna jednoho čísla v posloupnosti. Intervalové stromy Představme si, že máme posloupnost celých čísel p 0, p 1,... p N 1, se kterou budeme průběžně provádět tyto dvě operace: 1. Změna jednoho čísla v posloupnosti. 2. Zjištění součtu čísel

Více

Vyplňování souvislé oblasti

Vyplňování souvislé oblasti Počítačová grafika Vyplňování souvislé oblasti Jana Dannhoferová (jana.dannhoferova@mendelu.cz) Ústav informatiky, PEF MZLU. Které z následujících tvrzení není pravdivé: a) Princip interpolace je určení

Více

Multimediální systémy. 11 3d grafika

Multimediální systémy. 11 3d grafika Multimediální systémy 11 3d grafika Michal Kačmařík Institut geoinformatiky, VŠB-TUO Osnova přednášky Princip 3d objekty a jejich reprezentace Scéna a její osvětlení Promítání Renderování Oblasti využití

Více

IB108 Sada 1, Příklad 1 Vypracovali: Tomáš Krajča (255676), Martin Milata (256615)

IB108 Sada 1, Příklad 1 Vypracovali: Tomáš Krajča (255676), Martin Milata (256615) IB108 Sada 1, Příklad 1 ( ) Složitost třídícího algoritmu 1/-Sort je v O n log O (n.71 ). Necht n = j i (velikost pole, které je vstupním parametrem funkce 1/-Sort). Lehce spočítáme, že velikost pole předávaná

Více

CGI. Computer generated imagery Počítačové triky Animované filmy Počítačové hry. Technologické trendy v AV tvorbě, CGI 2

CGI. Computer generated imagery Počítačové triky Animované filmy Počítačové hry. Technologické trendy v AV tvorbě, CGI 2 CGI Computer generated imagery Počítačové triky Animované filmy Počítačové hry Technologické trendy v AV tvorbě, CGI 2 CGI Šíření světla v prostoru Možnosti simulace šíření v PC Pohyby CGI objektů Technologické

Více

Stromy, haldy, prioritní fronty

Stromy, haldy, prioritní fronty Stromy, haldy, prioritní fronty prof. Ing. Pavel Tvrdík CSc. Katedra počítačů FEL České vysoké učení technické DSA, ZS 2008/9, Přednáška 6 http://service.felk.cvut.cz/courses/x36dsa/ prof. Pavel Tvrdík

Více

Grafická data jsou u 2D vektorové grafiky uložena ve voxelech NEPRAVDA Grafická data jsou u rastrové grafiky uložena v pixelech PRAVDA Grafická data

Grafická data jsou u 2D vektorové grafiky uložena ve voxelech NEPRAVDA Grafická data jsou u rastrové grafiky uložena v pixelech PRAVDA Grafická data Grafická data jsou u 2D vektorové grafiky uložena ve voxelech Grafická data jsou u rastrové grafiky uložena v pixelech Grafická data jsou u vektorové grafiky uložena v pixelech Na rozdíl od rastrové grafiky

Více

Filtrace snímků ve frekvenční oblasti. Rychlá fourierova transformace

Filtrace snímků ve frekvenční oblasti. Rychlá fourierova transformace Filtrace snímků ve frekvenční oblasti Rychlá fourierova transformace semestrální práce z předmětu KIV/ZVI zpracoval: Jan Bařtipán A03043 bartipan@students.zcu.cz Obsah Úvod....3 Diskrétní Fourierova transformace

Více

PŘEDSTAVENÍ GRAFICKÉHO PROCESORU NVIDIA G200

PŘEDSTAVENÍ GRAFICKÉHO PROCESORU NVIDIA G200 PŘEDSTAVENÍ GRAFICKÉHO PROCESORU NVIDIA G200 Bc.Adam Berger Ber 208 Historie a předchůdci G200 V červnu roku 2008 spatřila světlo světa nová grafická karta od společnosti Nvidia. Tato grafická karta opět

Více

GEOGRAFICKÉ INFORMAČNÍ SYSTÉMY 6

GEOGRAFICKÉ INFORMAČNÍ SYSTÉMY 6 UNIVERZITA TOMÁŠE BATI VE ZLÍNĚ FAKULTA APLIKOVANÉ INFORMATIKY GEOGRAFICKÉ INFORMAČNÍ SYSTÉMY 6 Lubomír Vašek Zlín 2013 Obsah... 3 1. Základní pojmy... 3 2. Princip rastrové reprezentace... 3 2.1 Užívané

Více

GRAFICKÉ ADAPTÉRY. Pracovní režimy grafické karty

GRAFICKÉ ADAPTÉRY. Pracovní režimy grafické karty GRAFICKÉ ADAPTÉRY Grafický adaptér (též videokarta, grafická karta, grafický akcelerátor) je rozhraní, které zabezpečuje výstup obrazových dat z počítače na zobrazovací jednotku (monitor, displej, dataprojektor,

Více

2 Základní funkce a operátory V této kapitole se seznámíme s použitím funkce printf, probereme základní operátory a uvedeme nejdůležitější funkce.

2 Základní funkce a operátory V této kapitole se seznámíme s použitím funkce printf, probereme základní operátory a uvedeme nejdůležitější funkce. Vážení zákazníci, dovolujeme si Vás upozornit, že na tuto ukázku knihy se vztahují autorská práva, tzv copyright To znamená, že ukázka má sloužit výhradnì pro osobní potøebu potenciálního kupujícího (aby

Více

NPRG030 Programování I 3/2 Z --- NPRG031 Programování II --- 2/2 Z, Zk

NPRG030 Programování I 3/2 Z --- NPRG031 Programování II --- 2/2 Z, Zk NPRG030 Programování I 3/2 Z --- NPRG031 Programování II --- 2/2 Z, Zk Pavel Töpfer Katedra softwaru a výuky informatiky MFF UK MFF Malostranské nám., 4. patro, pracovna 404 pavel.topfer@mff.cuni.cz http://ksvi.mff.cuni.cz/~topfer

Více

Pokročilé osvětlovací techniky. 2005 Josef Pelikán, MFF UK Praha http://cgg.ms.mff.cuni.cz/~pepca/ Josef.Pelikan@mff.cuni.cz

Pokročilé osvětlovací techniky. 2005 Josef Pelikán, MFF UK Praha http://cgg.ms.mff.cuni.cz/~pepca/ Josef.Pelikan@mff.cuni.cz Pokročilé osvětlovací techniky 2005 Josef Pelikán, MFF UK Praha http://cgg.ms.mff.cuni.cz/~pepca/ Josef.Pelikan@mff.cuni.cz Obsah nefotorealistické techniky hrubé tónování kreslení obrysů ( siluety ) složitější

Více

DUM 01 téma: Obecné vlastnosti tabulkového editoru, rozsah, zápis do buňky, klávesové zkratky

DUM 01 téma: Obecné vlastnosti tabulkového editoru, rozsah, zápis do buňky, klávesové zkratky DUM 01 téma: Obecné vlastnosti tabulkového editoru, rozsah, zápis do buňky, klávesové zkratky ze sady: 02 tematický okruh sady: Tabulkový editor ze šablony: 07 KANCELÁŘSKÝ SOFTWARE určeno pro: 1-4. ročník

Více

Studentská tvůrčí a odborná činnost STOČ 2015

Studentská tvůrčí a odborná činnost STOČ 2015 Studentská tvůrčí a odborná činnost STOČ 2015 NÁVRH A REALIZACE ALGORITMU PRO SYSTÉM LIMITNÍHO OZAŘOVÁNÍ David OCZKA Vysoká škola báňská - Technická univerzita Ostrava Fakulta elektrotechniky a informatiky

Více

zejména Dijkstrův algoritmus pro hledání minimální cesty a hladový algoritmus pro hledání minimální kostry.

zejména Dijkstrův algoritmus pro hledání minimální cesty a hladový algoritmus pro hledání minimální kostry. Kapitola Ohodnocené grafy V praktických aplikacích teorie grafů zpravidla graf slouží jako nástroj k popisu nějaké struktury. Jednotlivé prvky této struktury mají často přiřazeny nějaké hodnoty (může jít

Více

Základní škola Moravský Beroun, okres Olomouc

Základní škola Moravský Beroun, okres Olomouc Charakteristika vyučovacího předmětu matematika Vyučovací předmět má časovou dotaci čtyři hodiny týdně v prvním ročníku, pět hodin týdně ve druhém až pátém ročníku, pět hodin týdně v šestém ročníku a čtyři

Více

Perspektiva jako matematický model objektivu

Perspektiva jako matematický model objektivu Západočeská univerzita v Plzni Fakulta aplikovaných věd Katedra informatiky a výpočetní techniky Semestrální práce z předmětu KMA/MM Perspektiva jako matematický model objektivu Martin Tichota mtichota@students.zcu.cz

Více

Aritmetika s velkými čísly na čipové kartě

Aritmetika s velkými čísly na čipové kartě Aritmetika s velkými čísly na čipové kartě Ivo Rosol ředitel divize vývoje OKsystem s.r.o. Praha, 23.5.2013 Spojujeme software, technologie a služby Čísla v kryptografii V kryptografii se zásadně pracuje

Více

KMA/PDB. Karel Janečka. Tvorba materiálů byla podpořena z prostředků projektu FRVŠ č. F0584/2011/F1d

KMA/PDB. Karel Janečka. Tvorba materiálů byla podpořena z prostředků projektu FRVŠ č. F0584/2011/F1d KMA/PDB Prostorové spojení Karel Janečka Tvorba materiálů byla podpořena z prostředků projektu FRVŠ č. F0584/2011/F1d Obsah Prostorové spojení pomocí hnízděných cyklů. Prostorové spojení pomocí R-stromů.

Více

Staré mapy TEMAP - elearning

Staré mapy TEMAP - elearning Staré mapy TEMAP - elearning Modul 1 Digitalizace Ing. Markéta Potůčková, Ph.D. 2013 Přírodovědecká fakulta UK v Praze Katedra aplikované geoinformatiky a kartografie Obsah Digitalizace starých map a její

Více

Barvy na počítači a grafické formáty

Barvy na počítači a grafické formáty Barvy na počítači a grafické formáty Hlavním atributem, který se používá při práci s obrazem či s grafickými formáty, je barva. Při práci s barvami je důležité určit základní množinu barev, se kterou budeme

Více

TECHNICKÁ UNIVERZITA V LIBERCI FAKULTA UMĚNÍ A ARCHITEKTURY. Studijní program: B8206 Výtvarná umění. Obor: Vizuální komunikace BAKALÁŘSKÁ PRÁCE

TECHNICKÁ UNIVERZITA V LIBERCI FAKULTA UMĚNÍ A ARCHITEKTURY. Studijní program: B8206 Výtvarná umění. Obor: Vizuální komunikace BAKALÁŘSKÁ PRÁCE TECHNICKÁ UNIVERZITA V LIBERCI FAKULTA UMĚNÍ A ARCHITEKTURY Studijní program: B8206 Výtvarná umění Obor: Vizuální komunikace BAKALÁŘSKÁ PRÁCE JAN VALENTA Vedoucí bakalářské práce: Doc. Stanislav Zippe

Více

Rámcový manuál pro práci s programem TopoL pro Windows

Rámcový manuál pro práci s programem TopoL pro Windows Rámcový manuál pro práci s programem TopoL pro Windows Příkazy v nabídce Předmět Volba rastru rychlá klávesa F4 Příkaz otevře vybraný rastr; tj. zobrazí ho v předmětu zájmu. Po vyvolání příkazu se objeví

Více

Kapitola 11. Vzdálenost v grafech. 11.1 Matice sousednosti a počty sledů

Kapitola 11. Vzdálenost v grafech. 11.1 Matice sousednosti a počty sledů Kapitola 11 Vzdálenost v grafech V každém grafu lze přirozeným způsobem definovat vzdálenost libovolné dvojice vrcholů. Hlavním výsledkem této kapitoly je překvapivé tvrzení, podle kterého lze vzdálenosti

Více

Geekovo Minimum. Počítačové Grafiky. Nadpis 1 Nadpis 2 Nadpis 3. Božetěchova 2, Brno

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í

Více

Výukové materiály pro výuku 3D grafiky na SOŠ

Výukové materiály pro výuku 3D grafiky na SOŠ Výukové materiály pro výuku 3D grafiky na SOŠ Část 1. Výukové materiály pro učitele a studenty Popis Výukové materiály pro výuku počítačové grafiky na střední odborné škole se zaměřením na informační technologie

Více

Hloubka ostrosti trochu jinak

Hloubka ostrosti trochu jinak Hloubka ostrosti trochu jinak Jan Dostál rev. 1.1 U ideálního objektivu platí: 1. paprsek procházející středem objektivu se neláme, 2. paprsek rovnoběžný s optickou osou se láme do ohniska, 3. všechny

Více

Umělá inteligence I. Roman Barták, KTIML. roman.bartak@mff.cuni.cz http://ktiml.mff.cuni.cz/~bartak

Umělá inteligence I. Roman Barták, KTIML. roman.bartak@mff.cuni.cz http://ktiml.mff.cuni.cz/~bartak Umělá inteligence I Roman Barták, KTIML roman.bartak@mff.cuni.cz http://ktiml.mff.cuni.cz/~bartak Na úvod Agent s reflexy pouze převádí současný vjem na jednu akci. Agent s cílem umí plánovat několik akcí

Více

Jak pracovat s absolutními hodnotami

Jak pracovat s absolutními hodnotami Jak pracovat s absolutními hodnotami Petr Matyáš 1 Co to je absolutní hodnota Absolutní hodnota čísla a, dále ji budeme označovat výrazem a, je jeho vzdálenost od nuly na ose x, tedy je to vždy číslo kladné.

Více

Počítačové zpracování obrazu Projekt Učíme se navzájem

Počítačové zpracování obrazu Projekt Učíme se navzájem Počítačové zpracování obrazu Projekt Učíme se navzájem Tomáš Pokorný, Vojtěch Přikryl Jaroška 15. ledna 2010 Tomáš Pokorný email: xtompok@gmail.com Jaroška 1 Obsah Abstrakt! 4 Začátky! 5 M&M 5 Původní

Více

01_Grafické rozhraní

01_Grafické rozhraní 01_Grafické rozhraní Jaké jsou základní rozdíly mezi konzolovou aplikací a aplikací s grafickým uživatelským rozhraním? Hlavní rozdíly mezi běžnou konzolovou aplikací a aplikací s GUI lze shrnout do dvou

Více

Zobrazování a osvětlování

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

Více

Vývoj počítačové grafiky

Vývoj počítačové grafiky Vývoj počítačové grafiky Počítačová grafika Základní pojmy Historie ASCII Art 2D grafika Rastrová Vektorová 3D grafika Programy Obsah Počítačová grafika obor informatiky, který používá počítače k tvorbě

Více

2 Spojité modely rozhodování

2 Spojité modely rozhodování 2 Spojité modely rozhodování Jak již víme z přednášky, diskrétní model rozhodování lze zapsat ve tvaru úlohy hodnocení variant: f(a i ) max, a i A = {a 1, a 2,... a p }, kde f je kriteriální funkce a A

Více

Základní datové struktury III: Stromy, haldy

Základní datové struktury III: Stromy, haldy Základní datové struktury III: Stromy, haldy prof. Ing. Pavel Tvrdík CSc. Katedra počítačových systémů Fakulta informačních technologií České vysoké učení technické v Praze c Pavel Tvrdík, 2010 Efektivní

Více

Matice se v některých publikacích uvádějí v hranatých závorkách, v jiných v kulatých závorkách. My se budeme držet zápisu s kulatými závorkami.

Matice se v některých publikacích uvádějí v hranatých závorkách, v jiných v kulatých závorkách. My se budeme držet zápisu s kulatými závorkami. Maticové operace Definice Skalár Představme si nějakou množinu, jejíž prvky lze sčítat a násobit. Pěkným vzorem jsou čísla, která už známe od mala. Prvky takové množiny nazýváme skaláry. Matice Matice

Více

Přibližný výpočet efektů globálního osvětlení na GPU

Přibližný výpočet efektů globálního osvětlení na GPU České vysoké učení technické v Praze Fakulta elektrotechnická Katedra počítačové grafiky a interakce Diplomová práce Přibližný výpočet efektů globálního osvětlení na GPU Bc. Miroslav Novotný Vedoucí práce:

Více

Obsah. Položkování 1: Prefix dřívějších osamocených dílů se zachovává...23 Položkování 2: Editace předběžných čísel...23

Obsah. Položkování 1: Prefix dřívějších osamocených dílů se zachovává...23 Položkování 2: Editace předběžných čísel...23 Obsah VÍTEJTE V ADVANCE STEEL 2013, ČÁSTÍ ŘEŠENÍ GRAITEC BIM... 5 ADVANCE CAD DOSTUPNÁ 64BITOVÁ PLATFORMA... 6 VYLEPŠENÍ PLATFORMY ADVANCE CAD 2013... 7 NOVÁ PALETA NÁSTROJŮ... 8 MODELOVÁNÍ... 9 Modelování

Více

Vývoj počítačové grafiky. Tomáš Pastuch Pavel Skrbek 15.3. 2010

Vývoj počítačové grafiky. Tomáš Pastuch Pavel Skrbek 15.3. 2010 Vývoj počítačové grafiky Tomáš Pastuch Pavel Skrbek 15.3. 2010 Počítačová grafika obor informatiky, který používá počítače k tvorbě umělých grafických objektů nebo pro úpravu již nasnímaných grafických

Více

BAKALÁŘSKÁ PRÁCE. Optimalizace trojúhelníkových sítí v E 3 a jejich zobrazování. 1999 / 2000 Jan Doubek

BAKALÁŘSKÁ PRÁCE. Optimalizace trojúhelníkových sítí v E 3 a jejich zobrazování. 1999 / 2000 Jan Doubek Západočeská univerzita v Plzni Fakulta aplikovaných věd Informatika a výpočetní technika BAKALÁŘSKÁ PRÁCE Optimalizace trojúhelníkových sítí v E 3 a jejich zobrazování 1999 / 2000 Jan Doubek 2 Obsah 1

Více

5.3.2 Vzdělávací obsah vyučovacího předmětu

5.3.2 Vzdělávací obsah vyučovacího předmětu 5.3.2 Vzdělávací obsah vyučovacího předmětu Předmět: Matematika Ročník: 1. Očekávané výstupy z RVP ZV Školní výstupy Učivo Přesahy a vazby (mezipředmětové vztahy, průřezová témata) používá přirozená čísla

Více

Úvod do počítačové grafiky

Úvod do počítačové grafiky Úvod do počítačové grafiky Zpracoval: ing. Jaroslav Chlubný Počítačová grafika Počítačová grafika a digitální fotografie zaujímá v současnosti stále významnější místo v našem životě. Uveďme si jen několik

Více

Základy programování (IZP)

Základy programování (IZP) Základy programování (IZP) Sedmé laboratorní cvičení Vysoké učení technické v Brně, Fakulta informačních technologií v Brně Božetěchova 2, 612 66 Brno Cvičící: Petr Veigend (iveigend@fit.vutbr.cz) Gabriela

Více

Fakulta informačních technologíı. IZG cvičení 6. - Zobrazování 3D scény a základy OpenGL 1 / 38

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

Více

Obsah. KAPITOLA 1 Dříve než začneme 19 Kdysi dávno aneb střípky z historie algoritmických strojů 20 1801 21 1833 21 1890 22 třicátá léta 22

Obsah. KAPITOLA 1 Dříve než začneme 19 Kdysi dávno aneb střípky z historie algoritmických strojů 20 1801 21 1833 21 1890 22 třicátá léta 22 Předmluva 11 Čím se tato kniha liší od jiných příruček? 11 Proč C++? 12 Jak číst tuto knihu? 12 Čím se budeme zabývat? 13 Kapitola 1: Dříve než začneme 13 Kapitola 2: Rekurze 13 Kapitola 3: Analýza složitosti

Více

Algoritmy a datové struktury

Algoritmy a datové struktury Algoritmy a datové struktury Stromy 1 / 32 Obsah přednášky Pole a seznamy Stromy Procházení stromů Binární stromy Procházení BS Binární vyhledávací stromy 2 / 32 Pole Hledání v poli metodou půlení intervalu

Více

8) Jaké jsou důvody pro použití víceprůchodového překladače Dříve hlavně kvůli úspoře paměti, dnes spíše z důvodu optimalizace

8) Jaké jsou důvody pro použití víceprůchodového překladače Dříve hlavně kvůli úspoře paměti, dnes spíše z důvodu optimalizace 1) Charakterizujte křížový překladač Překlad programu probíhá na jiném procesoru, než exekuce. Hlavním důvodem je náročnost překladače na cílovém stroji by ho nemuselo být možné rozběhnout. 2. Objasněte

Více

GRAFY A GRAFOVÉ ALGORITMY

GRAFY A GRAFOVÉ ALGORITMY KATEDRA INFORMATIKY PŘÍRODOVĚDECKÁ FAKULTA UNIVERZITA PALACKÉHO GRAFY A GRAFOVÉ ALGORITMY ARNOŠT VEČERKA VÝVOJ TOHOTO UČEBNÍHO TEXTU JE SPOLUFINANCOVÁN EVROPSKÝM SOCIÁLNÍM FONDEM A STÁTNÍM ROZPOČTEM ČESKÉ

Více

Operační systémy Linux, Mac OS X a jejich srovnání

Operační systémy Linux, Mac OS X a jejich srovnání 5 5.1 Operační systémy Linux, Mac OS X a jejich srovnání Popište výhody programů OpenSource, čím se vyznačují OpenSource programy se vyznačují tím, že se dodávají i se zdrojovým kódem. S tímto kódem může

Více

Implementace A* algoritmu na konkrétní problém orientace v prostoru budov

Implementace A* algoritmu na konkrétní problém orientace v prostoru budov Implementace A* algoritmu na konkrétní problém orientace v prostoru budov Popis problému Orientaci ve známém prostředí lze převést na problém nalezení cesty z místa A do místa B. Obecně platí, že robot

Více

Text úlohy. Vyberte jednu z nabízených možností:

Text úlohy. Vyberte jednu z nabízených možností: 2. pokus 76% Úloha 1 V rovině je dán NEKONVEXNÍ n-úhelník a bod A. Pokud paprsek (polopřímka) vedený z tohoto bodu A má (po vynechání vodorovných hran a rozpojení zbývajících hran) celkově 4 průsečíky

Více

Rasterizace je proces při kterém se vektorově definovaná grafika konvertuje na. x 2 x 1

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í

Více

Stromy. Strom: souvislý graf bez kružnic využití: počítačová grafika seznam objektů efektivní vyhledávání výpočetní stromy rozhodovací stromy

Stromy. Strom: souvislý graf bez kružnic využití: počítačová grafika seznam objektů efektivní vyhledávání výpočetní stromy rozhodovací stromy Stromy úvod Stromy Strom: souvislý graf bez kružnic využití: počítačová grafika seznam objektů efektivní vyhledávání výpočetní stromy rozhodovací stromy Neorientovaný strom Orientovaný strom Kořenový orientovaný

Více

Seminář z IVT Algoritmizace. Slovanské gymnázium Olomouc Tomáš Kühr

Seminář z IVT Algoritmizace. Slovanské gymnázium Olomouc Tomáš Kühr Seminář z IVT Algoritmizace Slovanské gymnázium Olomouc Tomáš Kühr Algoritmizace - o čem to je? Zatím jsme se zabývali především tím, jak určitý postup zapsat v konkrétním programovacím jazyce (např. C#)

Více

DYNAMICKÉ PROGRAMOVÁNÍ A PROBLÉM BATOHU

DYNAMICKÉ PROGRAMOVÁNÍ A PROBLÉM BATOHU ČVUT V PRAZE FAKULTA INFORMAČNÍCH TECHNOLOGIÍ JAN SCHMIDT A PETR FIŠER MI-PAA DYNAMICKÉ PROGRAMOVÁNÍ A PROBLÉM BATOHU EVROPSKÝ SOCIÁLNÍ FOND PRAHA A EU: INVESTUJEME DO VAŠÍ BUDOUCNOSTI Dynamické programování

Více

D E T E K C E P O H Y B U V E V I D E U A J E J I C H I D E N T I F I K A C E

D E T E K C E P O H Y B U V E V I D E U A J E J I C H I D E N T I F I K A C E D E T E K C E P O H Y B U V E V I D E U A J E J I C H I D E N T I F I K A C E CÍLE LABORATORNÍ ÚLOHY 1. Seznámení se s metodami detekce pohybu z videa. 2. Vyzkoušení si detekce pohybu v obraze kamery ÚKOL

Více

usimt03r JEDNOTKA PRO SIMULACI VZDÁLENÉ VARIANTY TERMINÁLU TERM03 NA POČÍTAČI PC Příručka uživatele a programátora

usimt03r JEDNOTKA PRO SIMULACI VZDÁLENÉ VARIANTY TERMINÁLU TERM03 NA POČÍTAČI PC Příručka uživatele a programátora usimt03r JEDNOTKA PRO SIMULACI VZDÁLENÉ VARIANTY TERMINÁLU TERM03 NA POČÍTAČI PC Příručka uživatele a programátora SofCon spol. s r.o. Střešovická 49 162 00 Praha 6 tel/fax: +420 220 180 454 E-mail: sofcon@sofcon.cz

Více

Základy 3D modelování a animace v CGI systémech Cinema 4D C4D

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

Více

přetížení operátorů (o)

přetížení operátorů (o) přetížení operátorů (o) - pro vlastní typy je možné přetížit i operátory (tj. definovat vlastní) - pro definici slouží klíčové slovo operator následované typem/znakem operátoru - operátor je speciální

Více

9 Prostorová grafika a modelování těles

9 Prostorová grafika a modelování těles 9 Prostorová grafika a modelování těles Studijní cíl Tento blok je věnován základům 3D grafiky. Jedná se především o vysvětlení principů vytváření modelů 3D objektů, jejich reprezentace v paměti počítače.

Více

8. Geometrie vrací úder (sepsal Pavel Klavík)

8. Geometrie vrací úder (sepsal Pavel Klavík) 8. Geometrie vrací úder (sepsal Pavel Klavík) Když s geometrickými problémy pořádně nezametete, ony vám to vrátí! Ale když užzametat,takurčitěnepodkoberecamístosmetákupoužijtepřímku.vtéto přednášce nás

Více

Vizuální programovací jazyk

Vizuální programovací jazyk Vizuální programovací jazyk Adam Zmrzlý Seminář LaSArIS, 24. 04. 2013 Obsah Motivace Vizuální programování Jazyk Shades Jazyk Tints Interpret a běhové prostředí Shader Vývojové prostředí CodePainter Ukázky

Více

NEXIS 32 rel. 3.50. Generátor fází výstavby TDA mikro

NEXIS 32 rel. 3.50. Generátor fází výstavby TDA mikro SCIA CZ, s. r. o. Slavíčkova 1a 638 00 Brno tel. 545 193 526 545 193 535 fax 545 193 533 E-mail info.brno@scia.cz www.scia.cz Systém programů pro projektování prutových a stěnodeskových konstrukcí NEXIS

Více

Práce na počítači. Bc. Veronika Tomsová

Práce na počítači. Bc. Veronika Tomsová Práce na počítači Bc. Veronika Tomsová Barvy Barvy v počítačové grafice I. nejčastější reprezentace barev: 1-bitová informace rozlišující černou a bílou barvu 0... bílá, 1... černá 8-bitové číslo určující

Více

Rekurzivní algoritmy

Rekurzivní algoritmy Rekurzivní algoritmy prof. Ing. Pavel Tvrdík CSc. Katedra počítačových systémů Fakulta informačních technologií České vysoké učení technické v Praze c Pavel Tvrdík, 2010 Efektivní algoritmy (BI-EFA) ZS

Více

Počítačová grafika 2 (POGR2)

Počítačová grafika 2 (POGR2) Počítačová grafika 2 (POGR2) Pavel Strachota FJFI ČVUT v Praze 19. února 2015 Kontakt Ing. Pavel Strachota, Ph.D. Katedra matematiky Trojanova 13, místnost 033a E-mail: pavel.strachota@fjfi.cvut.cz WWW:

Více

Počítačová grafika 1. Úvod do grafiky, základní pojmy. Rastrová grafika.

Počítačová grafika 1. Úvod do grafiky, základní pojmy. Rastrová grafika. Počítačová grafika 1 Úvod do grafiky, základní pojmy. Rastrová grafika. Proč vůbec grafika? Zmrzlinový pohár s převažující červenou barvou. Základem je jahodová zmrzlina, která se nachází ve spodní části

Více

Počítačové šachy. Otakar Trunda

Počítačové šachy. Otakar Trunda Počítačové šachy Otakar Trunda Hraní her obecně Hra je definovaná pomocí: Počáteční situace Funkce vracející množinu přípustných tahů v každé situaci Ohodnocení koncových stavů Našim cílem je najít strategii

Více

Seznámení Corel Draw. PDF vytvořeno zkušební verzí pdffactory Pro www.fineprint.cz. Panel Vlastnosti. panel základních kreslicích nástrojů

Seznámení Corel Draw. PDF vytvořeno zkušební verzí pdffactory Pro www.fineprint.cz. Panel Vlastnosti. panel základních kreslicích nástrojů Seznámení Corel Draw Okno programu Objeví se po spuštění, většinou je připraven nový, prázdný dokument, obvyklá velikost A4. Pamatujme, že na běžném monitoru se stránka zobrazí menší, takže při tisku budou

Více

STROMOVE ALGORITMY Prohledavani do sirky (level-order) Po vodorovnejch carach fronta

STROMOVE ALGORITMY Prohledavani do sirky (level-order) Po vodorovnejch carach fronta STROMOVE ALGORITMY Prohledavani do sirky (level-order) Po vodorovnejch carach vlož do fronty kořen opakuj, dokud není fronta prázdná 1. vyber uzel z fronty a zpracuj jej 2. vlož do fronty levého následníka

Více

Břetislav Fajmon, UMAT FEKT, VUT Brno. Poznámka 1.1. A) první část hodiny (cca 50 minut): představení všech tří metod při řešení jednoho příkladu.

Břetislav Fajmon, UMAT FEKT, VUT Brno. Poznámka 1.1. A) první část hodiny (cca 50 minut): představení všech tří metod při řešení jednoho příkladu. Břetislav Fajmon, UMAT FEKT, VUT Brno Poznámka 1.1. A) první část hodiny (cca 50 minut): představení všech tří metod při řešení jednoho příkladu. Na jiných příkladech je téma podrobně zpracováno ve skriptech

Více

České vysoké učení technické v Praze Fakulta elektrotechnická Katedra počítačů

České vysoké učení technické v Praze Fakulta elektrotechnická Katedra počítačů České vysoké učení technické v Praze Fakulta elektrotechnická Katedra počítačů Bakalářská práce Simulátor pásového bojového vozidla Jan Horký Vedoucí práce: Ing. Michal Hapala Studijní program: Elektronika

Více

OPTIKA - NAUKA O SVĚTLE

OPTIKA - NAUKA O SVĚTLE OPTIKA OPTIKA - NAUKA O SVĚTLE - jeden z nejstarších oborů yziky - studium světla, zákonitostí jeho šíření a analýza dějů při vzájemném působení světla a látky SVĚTLO elektromagnetické vlnění λ = 380 790

Více

SOFTWARE NA ZPRACOVÁNÍ MRAČEN BODŮ Z LASEROVÉHO SKENOVÁNÍ. Martin Štroner, Bronislav Koska 1

SOFTWARE NA ZPRACOVÁNÍ MRAČEN BODŮ Z LASEROVÉHO SKENOVÁNÍ. Martin Štroner, Bronislav Koska 1 SOFTWARE NA ZPRACOVÁNÍ MRAČEN BODŮ Z LASEROVÉHO SKENOVÁNÍ SOFTWARE FOR PROCESSING OF POINT CLOUDS FROM LASER SCANNING Martin Štroner, Bronislav Koska 1 Abstract At the department of special geodesy is

Více

9. Úvod do teorie PDR

9. Úvod do teorie PDR 9. Úvod do teorie PDR A. Základní poznatky o soustavách ODR1 Diferenciální rovnici nazveme parciální, jestliže neznámá funkce závisí na dvou či více proměnných (příslušná rovnice tedy obsahuje parciální

Více

Výukový materiál vytvořen v rámci projektu EU peníze školám "Inovace výuky" registrační číslo CZ.1.07/1.5.00/34.0585

Výukový materiál vytvořen v rámci projektu EU peníze školám Inovace výuky registrační číslo CZ.1.07/1.5.00/34.0585 Výukový materiál vytvořen v rámci projektu EU peníze školám "Inovace výuky" registrační číslo CZ.1.07/1.5.00/34.0585 Škola: Adresa: Autor: Gymnázium, Jablonec nad Nisou, U Balvanu 16, příspěvková organizace

Více

Západočeská univerzita v Plzni. Fakulta aplikovaných věd Katedra matematiky. Geometrie pro FST 1. Pomocný učební text

Západočeská univerzita v Plzni. Fakulta aplikovaných věd Katedra matematiky. Geometrie pro FST 1. Pomocný učební text Západočeská univerzita v Plzni Fakulta aplikovaných věd Katedra matematiky Geometrie pro FST 1 Pomocný učební text František Ježek, Marta Míková, Světlana Tomiczková Plzeň 29. srpna 2005 verze 1.0 Předmluva

Více

Editor pro vizualizaci interiérů bytů

Editor pro vizualizaci interiérů bytů České vysoké učení technické v Praze Fakulta elektrotechnická Katedra počítačové grafiky a interakce Bakalářská práce Editor pro vizualizaci interiérů bytů Dominik Vondráček Vedoucí práce: Ing. David Sedláček

Více

λ, (20.1) 3.10-6 infračervené záření ultrafialové γ a kosmické mikrovlny

λ, (20.1) 3.10-6 infračervené záření ultrafialové γ a kosmické mikrovlny Elektromagnetické vlny Optika, část fyziky zabývající se světlem, patří spolu s mechanikou k nejstarším fyzikálním oborům. Podle jedné ze starověkých teorií je světlo vyzařováno z oka a oko si jím ohmatává

Více

Gymnázium Jiřího Ortena, Kutná Hora. volné rovnoběžné promítání průmětna

Gymnázium Jiřího Ortena, Kutná Hora. volné rovnoběžné promítání průmětna Předmět: Matematika Náplň: Stereometrie, Analytická geometrie, Komplexní čísla Třída: 3. ročník Počet hodin: 4 hodiny týdně Pomůcky: PC a dataprojektor Volné rovnoběžné promítání Zobrazí ve volném rovnoběžném

Více

Algoritmy výpočetní geometrie

Algoritmy výpočetní geometrie Algoritmy výpočetní geometrie prof. Ing. Pavel Tvrdík CSc. Katedra počítačových systémů Fakulta informačních technologií České vysoké učení technické v Praze c Pavel Tvrdík, 2010 Efektivní algoritmy (BI-EFA)

Více

Digitalizace signálu (obraz, zvuk)

Digitalizace signálu (obraz, zvuk) Digitalizace signálu (obraz, zvuk) Základem pro digitalizaci obrazu je převod světla na elektrické veličiny. K převodu světla na elektrické veličiny slouží např. čip CCD. Zkratka CCD znamená Charged Coupled

Více

Anti Aliasing. Ondřej Burkert. atrey.karlin.mff.cuni.cz/~ondra/ ~ondra/stranka

Anti Aliasing. Ondřej Burkert. atrey.karlin.mff.cuni.cz/~ondra/ ~ondra/stranka Anti Aliasing Ondřej Burkert atrey.karlin.mff.cuni.cz/~ondra/ ~ondra/stranka Úvod Co je to anti - aliasing? Aliasing = vznik artefaktů v důsledku podvzorkování při vzorkování (sampling) obrazu podvzorkování

Více

Reprezentace 3D modelu

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é

Více

REPREZENTACE 3D SCÉNY

REPREZENTACE 3D SCÉNY REPREZENTACE 3D SCÉNY JANA ŠTANCLOVÁ jana.stanclova@ruk.cuni.cz Obrázky (popř. slajdy) převzaty od RNDr. Josef Pelikán, CSc., KSVI MFF UK Obsah reprezentace 3D scény objemové reprezentace výčtové reprezentace

Více

Co je grafický akcelerátor

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

Více

Obsah. Obsah. Úvod... 15. 1. Spuštění programu... 17. 2. Pracovní prostředí... 19. 3. Vytvoření a otevření dokumentu... 21. 4. Kreslení objektů...

Obsah. Obsah. Úvod... 15. 1. Spuštění programu... 17. 2. Pracovní prostředí... 19. 3. Vytvoření a otevření dokumentu... 21. 4. Kreslení objektů... CORELDRAW 12 5 Úvod... 15 1. Spuštění programu... 17 1.1 Obnovení výchozích hodnot...17 2. Pracovní prostředí... 19 3. Vytvoření a otevření dokumentu... 21 3.1 Vytvoření nového dokumentu...21 3.2 Otevření

Více

VYSOKÁ ŠKOLA EKONOMICKÁ V PRAZE. Optimalizace trasy při revizích elektrospotřebičů

VYSOKÁ ŠKOLA EKONOMICKÁ V PRAZE. Optimalizace trasy při revizích elektrospotřebičů VYSOKÁ ŠKOLA EKONOMICKÁ V PRAZE FAKULTA INFORMATIKY A STATISTIKY Hlavní specializace: Ekonometrie a operační výzkum Název diplomové práce Optimalizace trasy při revizích elektrospotřebičů Diplomant: Vedoucí

Více

Algoritmus Minimax. Tomáš Kühr. Projektový seminář 1

Algoritmus Minimax. Tomáš Kühr. Projektový seminář 1 Projektový seminář 1 Základní pojmy Tah = přemístění figury hráče na tahu odpovídající pravidlům dané hry. Při tahu může být manipulováno i s figurami soupeře, pokud to odpovídá pravidlům hry (např. odstranění

Více