English
Kamil Dudka

RRV - Radiosity Renderer and Visualizer (C++, OpenGL)

Detail souboru

Jméno:Stáhnoutproj_doc_content.tex [Stáhnout]
Detekovaná znaková sada:ISO-8859-2 - [Stáhnout jako UTF-8]
Umístění: rrv > doc
Velikost:21.5 KB
Poslední změna:2022-09-09 13:06

Zdrojový kód

% \date{15. května 2007}
% \setyear{2007}
% \author{Kamil Dudka}
% \title{Knihovna pro~práci s~objekty ve~sdílené~paměti}
% \FITproject{BP}
 
\chapter{Úvod}
Radiozita je pokročilá zobrazovací metoda používaná ve fotorealistické grafice. Její výpočet je časově náročný. Tato práce se zabývá jednoduchou implementací výpočtu radiozity, která využívá akceleraci založenou na \texttt{OpenGL}.
 
Pomocí vzniklého programu byly vypočítány vzorové scény, které se do této dokumentace nevešly -- lze stáhnout z \href{http://dudka.cz/rrv}{{\tt http://dudka.cz/rrv}}. Kromě toho lze z webu stáhnout krátké \href{http://dudka.cz/rrv/files/video/room4.x264.avi?action=download}{video} (asi 20 vteřin), které ukazuje, jak se šíří radiozita v průběhu výpočtu.
 
Nedílnou součástí této dokumentace je dokumentace API a diagramy tříd, které jsou dostupné rovněž na webu projektu.
 
\section{Podíl jednotlivých členů týmu na projektu}
\begin{description}
 \item[David Bařina, xbarin02]~\\
    - Výpočet konfiguračních faktorů pomocí \texttt{OpenGL}\\
    - Převod primitiv (koule, válec, čajník) na polygonální reprezentaci
 \item[Kamil Dudka, xdudka00]~\\
    - Objektový model\\
    - Dělení na plošky\\
    - Mezipaměť pro konfigurační faktory\\
    - Interpolace barev
 \item[Jakub Filák, xfilak01]~\\
    - Vstup/výstup XML, DTD\\
    - Zpracování parametrů příkazové řádky
 \item[Lukáš Hefka, xhefka00]~\\
    - Program pro vizualizaci\\
    - Vzorová vstupní scéna
 \end{description}
 
\vfill\hfill {\footnotesize Tento dokument byl vysázen systémem \LaTeX.}
 
\chapter{Teoretická část}\label{theory}
\section{Radiozita}
 Radiozita\cite{wikiRadiosity} je metoda globální iluminace scény (šíření světelné energie) používaná k renderování 3D scény v počítačové grafice. Radiozita jako renderovací metoda byla představena v roce 1984 výzkumníky na Cornell University. Vychází ze zákona zachování energie. Proto vyžaduje energeticky uzavřené scény. Nedokáže pracovat s průhlednými objekty, zrcadly a~texturami. Scéna musí být reprezentována polygonálním modelem.
 
 Zobrazovací rovnice vychází z dvousměrové distribuční funkce BRDF\cite{RGI}. Plochy nejen odrážejí světlo, ale mohou mít i vlastní zářivost. Šíří se pouze difúzní odraz světla.
 
 Vlastní výpočet může probíhat buď iteračně (progresivně) nebo řešením soustavy rovnic (maticové řešení). Před vlastním výpočtem je třeba polygony ve scéně rozdělit na malé plošky a spočítat \textit{konfigurační faktory} (vliv každé plošky na každou jinou plošku ve scéně). Plošky, které na sebe nevidí mají konfigurační faktor 0. Iterační výpočet, který je použit v~našem projektu, má výhodu postupného zobrazení výsledku po každé iteraci.
 
 Radiozita (zářivost) každé plošky je definována jako:
 \begin{equation}
  B_i = E_i + R_i \sum_{j=1}^n B_j F_{ij}
 \end{equation}
 
 kde:
 \begin{itemize}
  \item $B_i$ je radiozita plošky $i$.
  \item $E_i$ je vyzařovaná energie této plošky.
  \item $R_i$ je odrazivost plošky.
  \item suma reprezentuje součet energií přicházejících na plošku $i$ ze všech ostatních plošek.
  \item $F_{ji}$ je konfigurační faktor mezi ploškami $i$ a $j$ (vliv plošky $j$ na plošku $i$).
 \end{itemize}
 
\section{Výpočet konfiguračního faktoru pomocí \texttt{OpenGL}}\label{ffOpenGL}
Konfigurační faktor\cite{Ashdown} (\textit{form factor}) říká, kolik energie energie plošky (\textit{patche}) $i$ je přímo přijato ploškou $j$. Plošky vzdálenější mají od plošky cílové mají na tuto vliv menší než~plošky bližší. Plošky viditelné z cílové plošky ze strany mají menší vliv než plošky ležící přímo před cílovou ploškou (\textit{Lambertův kosinový zákon}). K výpočtu konfiguračního faktoru je třeba vykreslit scénu z pohledu cílové plošky ($i$) s rozsvícenou ploškou zdrojovou ($j$). Toto vykreslení (vyrenderování) scény je třeba provést pro všechny dvojice plošek ve scéně. Vykreslením všech zdrojových plošek rozdílnou barvou ke každé cílové plošce najednou lze výpočet značně urychlit. Složitost klesá z kvadratické (počet plošek na druhou) na lineární. Z výsledné vyrenderované bitmapy se pak spočítá form factor pro všechny zdrojové plošky viditelné v této bitmapě k plošce cílové (z jejíhož pohledu byla scéna renderována).
 
Při vlastním renderovaní\cite{HugoElias} je potřeba vidět z pohledu cílové plošky celých $180^\circ$ světa ležícího před touto ploškou. Dále je třeba aplikovat Lambertův kosinový zákon a tím snížit vliv plošek, které se nacházejí z boku cílové plošky, oproti ploškám ležících přímo naproti cílové plošky. Čím více z boku zdrojová ploška leží, tím méně světla z ní cílová ploška přijme.
 
K vyrenderováni $180^\circ$ scény se používá vyrenderováni do tzv. \textit{polokrychle} (hemicube). To znamená vyrenderováni scény při pohledu ze středu patche do přední stěny a do~4~bočních polostěn. Renderuje se s úhlem pohledu $90^\circ$ (perspektiva). Vyrenderováni přední stěny se kamera umístí do středu cílového patche a bude se dívat ve směru normálového vektoru tohoto patche. K renderování je použito \texttt{OpenGL}, konkrétně funkce \texttt{gluLookAt()} z knihovny \texttt{GLU}. \quotedblbase{UP\textquotedblleft} vektor je zvolen rovnoběžně s jednou ze stran trojúhelníkového patche.
 
Při renderování bočních stran se kamera opět dívá ze středu patche a renderuje se opět s úhlem pohledu $90^\circ$. Směr pohledu je ovšem kolmý na normálový vektor (\quotedblbase{UP\textquotedblleft} vektor z renderování přední stěny). Pro renderování všech 4 stran se kamera postupně otáčí po~$90^\circ$. Z výsledné bitmapy je podstatná pouze část nad horizontem cílového trojúhelníku (tzn. polovina boční stěny). Všechna renderování probíhají postupně do jediného framebufferu. Oblast framebufferu, do které se bude kreslit, se nastavuje funkcí \texttt{glViewport()}. Pro další zpracování je důležité, aby na sebe pohledy do stran polokrychle správně navazovaly (správné \quotedblbase{UP\textquotedblleft} vektory). Po dokončení renderování je ve framebufferu zobrazena rozbalená krychle (tvoří kříž). Podstatná je pouze vnitřní část tohoto kříže (bez spodních částí bočních pohledů). V této oblasti je nyní nutné zohlednit Lambertův kosinový zákon.
 
Velmi jednoduše řečeno, Lambertův kosinový zákon říká, že paprsek dopadající na střed plošky kolmo má na její osvětlení vliv největší. Paprsek dopadající pod nějakým úhlem má vliv menší úměrně tomuto úhlu (kosinus tohoto úhlu). Paprsek dopadající téměř rovnoběžně s povrchem plošky má vliv téměř zcela zanedbatelný.
 
Před vlastním počítáním konfiguračních faktorů z vyrenderované bitmapy je nutné přenést obsah framebufferu do paměti pomocí funkce \texttt{glReadPixels()}. Dále ji bitmapa postupně procházena po pixelech. Barva každého pixelu udává, kterou zdrojovou plošku v~tomto místě cílová ploška vidí (barva pixelu je indexem zdrojové plošky). Pouhým sčítáním počtu pixelů ve scéně dané barvy by se spočítal konfigurační faktor nezohledňující Lambertův kosinový zákon (čím více pixelů ze zdrojové plošky je viděno ploškou cílovou, tím větší mají na sebe vliv). Podle pozice $(x,y)$ v bitmapě je spočten vliv (koeficient) daného pixelu na celkový form factor k dané zdrojové plošce. Největší vliv mají pixely ležící ve~středu bitmapy (středu přední stěny polokrychle), kde je tento koeficient roven $1$. Nejmenší vliv (koeficient roven $0$) mají pixely na vnějších hranách bočních polostěn. Tento koeficient je počítán jako součin kosinů pozice $x$ a $y$, kde střed bitmapy má $x$ i $y$ rovno nule. Směrem ke~stranám se $x$ i $y$ zmenšuje (doleva a nahoru) a zvětšuje (doprava a dolů) až k hodnotě~$\frac{\pi}{2}$.
 
\chapter{Návrh řešení}\label{design}
Výpočet radiozity je časově náročný a klade vysoké nároky na výkon stroje. Hlavními cíli návrhu tedy bylo:
\begin{itemize}
 \item Co nejvíce urychlit výpočet -- využití HW akcelerace, maximální využití dostupné paměti, ...
 \item Možnost pracovat s mezivýsledky -- pro co nejrychlejší odhalení nedostatků ve vstupní scéně nebo zvolených parametrech výpočtu.
 \item Možnost navázat na dříve přerušený výpočet -- v případě výpadku elektřiny, pádu systému, ...
\end{itemize}
 
\section{Reprezentace scény}
Výpočet radiozity pracuje s polygonálním modelem -- na nejnižší úrovni jsou tedy tělesa ve~scéně reprezentována množinou polygonů (trojúhelníků). Jednomu trojúhelníku odpovídá struktura \texttt{Triangle}. Na rozdíl od běžných polygonálním modelů však nezadáváme přímo barvu polygonu, kterou vidí uživatel. Tato barva je vypočítána pomocí radiozity. Zadávají se místo toho dvě složky:
\begin{itemize}
 \item \texttt{emission} -- barva, kterou polygon vyzařuje. Používá se pouze pro zdroje světla, tělesa, která sama o sobě nezáří, mají tuto složku nulovou.
 \item \texttt{reflectivity} -- barva, kterou polygon odráží. Jedná se tedy o barvu tělesa tak, jak ji vnímáme intuitivně.
\end{itemize}
 
Při zadávání scény uživatelem však nemusí být vždy práce s jednotlivými polygony zcela intuitivní. Proto definuje objektový model některá základní primitiva -- krychle, koule, válec a čajník\footnote{Polygonální reprezentaci čajníku lze stáhnout z \href{http://home.student.uu.se/yuca7825/Ass2_YuCao_YaoWang.zip}{http://home.student.uu.se/yuca7825/Ass2\_YuCao\_YaoWang.zip}}. Každé primitivum je reprezentováno samostatnou třídou, která zapouzdřuje převod na polygonální model.
 
Uživatel má tedy dvě možnosti, jak reprezentovat tělesa ve scéně -- polygonálně nebo pomocí primitiv. Tyto přístupy jsou z pohledu výpočtu zaměnitelné -- proto je nad nimi definována abstraktní třída \texttt{Entity}. Třída \texttt{TriangleSet} reprezentuje kontejner polygonů na nízké úrovni.
 
Nad jednotlivými tělesy je možné provádět běžné transformace ve 3D -- k tomu slouží třída \texttt{TransformMatrix} a metoda \texttt{setTransformMatrix} třídy \texttt{Entity}. Část objektového modelu reprezentující těleso je zjednodušeně znázorněna na obr. \ref{class_Entity}.
\begin{figure}[h]
  \begin{center}\includegraphics[scale=0.65]{img/class_Entity.png}\end{center}
  \caption{Abstraktní třída \texttt{Entity}}\label{class_Entity}
\end{figure}
 
Scéna je tedy z pohledu uživatele tvořena oddělenými tělesy. Všechny tělesa ve scéně jsou spravovány třídou \texttt{Scene}. Tato třída, mimo jiné, umožňuje scénu jako celek načíst ze~vstupního XML souboru\footnote{DTD pro reprezentaci scény je na adrese \href{http://dudka.cz/dtd/scene.dtd}{http://dudka.cz/dtd/scene.dtd}} a zapsat do výstupního XML souboru. Třída  \texttt{EntitySet} reprezentuje kontejner entit na nízké úrovni. Kompozice třídy \texttt{Scene} je znázorněna na obr. \ref{class_Scene}.
\begin{figure}[h]
  \begin{center}\includegraphics[scale=0.65]{img/class_Scene.png}\end{center}
  \caption{Třída \texttt{Scene} -- reprezentace scény}\label{class_Scene}
\end{figure}
 
Reprezentace scény pomocí oddělených těles je vhodná pro uživatele a také pro některé pomocné výpočty (např. interpolace barev). Pro výpočet radiozity však tato reprezentace vhodná není. Radiozita uvažuje vliv každé plošky na ostatní plošky -- bez ohledu na to, kterému tělesu plošky patří. Pro tento účel byly vytvořeny enumerátory pro přístup k~jednotlivým ploškám. Situaci znázorňuje obr. \ref{class_diagram_enumerators}.
\begin{figure}[h]
  \begin{center}\includegraphics[scale=0.45]{img/class_diagram_enumerators.png}\end{center}
  \caption{Enumerátory -- třídy pro přístup k jednotlivým ploškám}\label{class_diagram_enumerators}
\end{figure}
 
Základem je třída \texttt{PatchSequenceEnumerator}, která implementuje sekvenční průchod přes všechny plošky ve scéně. K indexovanému přístupu k ploškám slouží třída \texttt{PatchRandom\-AccessEnumerator}, která se konstruuje z již existující instance sekvenčního enumerátoru. Tato třída alokuje větší množství paměti, proto je vhodné její instanci sdílet mezi všemi objekty, které vyžadují indexovaný přístup k ploškám.
 
\section{Výpočet radiozity}
Před vlastním výpočtem radiozity je nutné rozdělit trojúhelníky z vstupní scény na plošky požadované velikosti. K tomu účelu slouží metoda \texttt{divide} třídy \texttt{Scene}, která odstartuje rekurzivní dělení trojúhelníků. Rekurzivní dělení je vždy zastaveno při dosažení požadované velikosti (obsahu) trojúhelníku. Pro výpočet obsahu trojúhelníku je použitý Heronův vzo\-rec\cite{heron}:
\begin{equation}
 S = \sqrt{s(s-a)(s-b)(s-c)}
\end{equation}
kde
\begin{equation}
 s=\frac{a+b+c}{2}
\end{equation}
 
Vlastní výpočet radiozity je zajišťován třídou \texttt{RadiosityRenderer}. Instance této třídy se tvoří metodou \texttt{createRadiosityRenderer} třídy \texttt{Scene}, které se předají parametry výpoč\-tu. Vztahy objektů pro výpočet radiozity jsou zachyceny na obr. \ref{class_RadiosityRenderer}
\begin{figure}[h]
  \begin{center}\includegraphics[scale=0.5]{img/class_RadiosityRenderer.png}\end{center}
  \caption{Třída \texttt{RadiosityRenderer} -- reprezentace scény}\label{class_RadiosityRenderer}
\end{figure}
 
Z pohledu uživatele trvá výpočet radiozity věčnost -- je tedy na místě průběh výpočtu sledovat a nějak na něj reagovat. K tomuto účelu byl použit návrhový vzor \textit{observer}, přičemž třída \texttt{RadiosityRenderer} je zde v roli sledovaného objektu. V současné verzi projektu jsou implementovány dva observery (pozorovatelé) -- \texttt{ConsoleProgressIndicator} a \texttt{ContinousSaver}. Jednotlivé pozorovatele je možné za běhu připojovat a odpojovat. Třída \texttt{ConsoleProgressIndicator} během výpočtu vypisuje do konzole základní informace o průběhu. Třída \texttt{ContinousSaver} ukládá mezivýsledky do souboru s předem nastavenou frekvencí. Frekvence ukládání se v průběhu výpočtu snižuje, což odpovídá snižujícím se změnám radiozity ve~scéně. Tyto mezivýsledky je možné použít například pro generování videa -- viz. kapitola \ref{results}.
 
Jádrem výpočtu radiozity je výpočet konfiguračních faktorů -- tento výpočet zajišťuje třída \texttt{FormFactorEngine}. Její implementace používá \texttt{OpenGL} pro urychlení výpočtu -- viz. kapitola \ref{ffOpenGL}. Tento výpočet je však (zejména pro scény s velkým počtem plošek) náročný a je tedy nejslabším místem aplikace z hlediska výkonu.
 
Nabízí se tedy řešení: ukládat si vypočtené konfigurační faktory do paměti mezi jednotlivými průchody. Množství potřebné paměti však roste s kvadrátem k počtu plošek ve~scéně a pro netriviální scénu se všechny konfigurační faktory do paměti nevlezou. Rozum\-ným kompromisem je uchovávat v mezipaměti tolik konfiguračních faktorů, kolik se jich tam vleze a to co možná nejefektivnějším způsobem.
 
Mezipaměť pro vypočtené konfigurační faktory zajišťuje třída \texttt{PatchCache}\footnote{Spolu s hodnotou konfiguračního faktoru je potřeba uchovávat odkaz na plošku, ke které se konfigurační faktor vztahuje.}. Tato mezipaměť je hierarchická -- konfigurační faktory všech plošek ovlivňujících jednu konkrétní plošku se shlukují v objektech třídy \texttt{PatchCacheLine}. Počet potřebných objektů \texttt{Patch\-Cache\-Line} tvořících mezipaměť je zřejmě stejný jako počet plošek ve scéně.
 
Jednotlivé objekty \texttt{PatchCacheLine} spolu potom soutěží o uložení v mezipaměti. Krité\-riem je přitom počet uložených konfiguračních faktorů uvnitř objektu (a tím pádem velikost objektu v paměti). Vyšší prioritu pro uchování paměti mají objekty s nižší velikostí. Objekty s vyšší velikostí je efektivnější znovu vypočítat. Diagram tříd tvořících mezipaměť je na~obr.~\ref{class_PatchCache}. Prioritní fronta je implementována pomocí stejnojmenného STL kontejneru\cite{Stroustrup}.
\begin{figure}[h]
  \begin{center}\includegraphics[scale=0.5]{img/class_PatchCache.png}\end{center}
  \caption{Třída \texttt{PatchCache} -- mezipaměť pro konfigurační faktory}\label{class_PatchCache}
\end{figure}
 
\section{Vizualizace}
Vizualizaci scény má na starosti třída \texttt{Visualizer}. Vizualizaci je možné provádět dvěma způsoby:
\begin{enumerate}
 \item \textbf{Interaktivně} -- uživatel může měnit pozici kamery, přepínat mezi různými způsoby zobrazení a ukládat aktuální pohled jako obrázek.
 \item \textbf{Dávkově} -- zobrazená scéna se uloží jako obrázek do souboru a program skončí.
\end{enumerate}
 
Interaktivní vizualizaci zajišťuje statická metoda \texttt{visualize}, dávkovou vizualizaci za\-jišťu\-je statická metoda \texttt{takeScreenshot}. Tyto metody mají jednu zvláštnost -- po jejich zavolání se už nikdy nevrátí řízení zpět\footnote{Tohle chování je dáno rozhraním knihovny GLUT, kterou třída používá.} a program je ukončen funkcí \texttt{std::exit()}. Při~návrhu je potřeba na tuto vlastnost brát ohled a zajistit správné uvolnění paměti a ostatních zdrojů.
 
Výsledkem radiozity jsou hodnoty barev pro jednotlivé plošky. Aby uživatel neviděl rušivé přechody barev mezi ploškami, je potřeba provést interpolaci barev. Nejprve jsou průměrováním vypočteny barvy pro jednotlivé vrcholy plošek (metoda \texttt{Entity::compute\-VertexColors()}), samotnou interpolaci potom provádí \texttt{OpenGL} během vykreslování scény.
 
\chapter{Implementace}\label{implementation}
Celý projekt byl implementován v jazyce C++, využívá knihovny standardu \texttt{OpenGL} a~knihovnu \texttt{GLUT}. Volně šiřitelný parser XML\cite{xmlParser} je součástí archivu. Automatické sestavení na~různých platformách zajišťuje multiplatformní make systém \href{http://www.cmake.org/HTML/Index.html}{CMake}. Jak bylo naznačeno v návrhu, sestavují se dva spustitelné soubory:
 
\begin{description}
 \item[\textbf{rrv-compute}] je program pro výpočet radiozity. Výpis parametrů je možné vypsat přepína\-čem \texttt{--help}, povinným parametrem je \texttt{--filein} následovaný jménem vstupního souboru. Vstupní soubor může být vytvořený uživatelem, nebo to může být mezivýs\-ledek výpočtu, na který chceme navázat.
 
 Dalším důležitým parametrem je \texttt{--divide}, který určuje nejvyšší přípustný obsah plošky ve scéně během rekurzivního dělení na plošky. Čím nižší číslo nastavíme, tím je výstup kvalitnější. Zároveň však roste doba výpočtu, proto je dobré najít vhodnou hodnotu experimentálně.
 
 Výpočet je možné urychlit nastavením vhodné hodnoty parametru \texttt{--cache}. Tento parametr určuje maximální prostor vyhrazený pro mezipaměť. Konfigurační faktory, které se do mezipaměti nevlezou je nutné počítat v každém průchodu znovu, což zpomaluje výpočet. V praxi však není vhodné nastavovat velikost mezipaměti vyšší než je velikost fyzické paměti.
 
 \item[\textbf{rrv-visualize}] je program pro vizualizaci scény. Pomocí tohoto programu je možné vizua\-lizovat vstupní scénu, jakýkoliv mezivýsledek i finální scénu s vypočtenou radiozitou. Jak bylo zmíněno v návrhu, pracuje ve dvou režimech. Výchozí je interaktivní režim, dávkový režim se zapíná volbou \texttt{--screenshot on}. Povinným parametrem je opět \texttt{--filein} následovaný jménem vstupního souboru.
 
 Pozici kamery lze v interaktivním režimu měnit myší. Levým tlačítkem se otáčí scéna, pravým tlačítkem se kamera přibližuje/oddaluje a kurzorovými šipkami se kamera posouvá. Dále je možné měnit způsob zobrazení plošek a zobrazení barev pomocí následujících kláves:
 
 \sffamily
 \begin{tabular}{|r|l|}\hline
  Klávesa&Funkce\\\hline
  1&pouze vrcholy\\
  2&pouze hranice polygonů\\
  3&vyplněné polygony\\
  7&zmenšit šířku bodů/čar\\
  8&zvětšit šířku bodů/čar\\\hline
  Z&barva odrazu\\
  X&barva zdroje světla\\
  C&barva odrazu + barva zdroje světla\\
  V&vypočtená radiozita (bez interpolace, barva plošek)\\
  B&vypočtená radiozita (jednoúrovňová interpolace)\\
  N&vypočtená radiozita (jednoúrovňová interpolace, barva plošek)\\
  M&vypočtená radiozita (dvojúrovňová interpolace)\\\hline
 
 \end{tabular}
 \end{description}
 
\section{Sestavení a instalace}
Pro úspěšné sestavení je potřeba mít nainstalovanou knihovnu GLUT, knihovny OpenGL, CMake a podporovaný překladač. Vlastní sestavení a instalace jsou velmi jednoduché a~pří\-močaré:
\begin{verbatim}
$ cmake .
$ make
$ make install
\end{verbatim} 
 
Sestavení bylo testováno na operačních systémech Linux, FreeBSD, Windows XP a Windows Vista. Na systémech Windows jsou podporovány překladače MinGW a Microsoft Visual Studio 2005.
 
Pro výpočet konfiguračního faktoru se používá akcelerátor grafické karty, přičemž číslo plošky se kóduje jako barva. Pokud provádí grafická karta vyhlazování (aplikace vyhlazování sama nezapíná), bude výsledek nesmyslný. \textbf{Proto v nastavení grafické karty nesmí být zapnutá volba vynuceného vyhlazování.}
 
\chapter{Výsledky}\label{results}
Výpočet radiozity byl testován na několika vzorových scénách, které jsou součástí archivu. Vzhledem k omezením na velikost odevzdávaného souboru (a tím pádem i dokumentace) nebylo možné umístit do této dokumentace výsledky jako obrázky. Náhled scény s vypočí\-tanou radiozitou je na obr. \ref{room4}.
 
Na webu projektu \href{http://dudka.cz/rrv}{{\tt http://dudka.cz/rrv}} je spousta obrázků z průběhu výpočtu. Také jsou tam ke stažení XML soubory s vypočtenou radiozitou, takže je možné si prohléd\-nout již spočítanou scénu. Kromě toho lze z webu stáhnout krátké \href{http://dudka.cz/rrv/files/video/room4.x264.avi?action=download}{video} (asi 20 vteřin), které ukazuje, jak se šíří radiozita v průběhu výpočtu.
 
\begin{figure}[h]
  \begin{center}\includegraphics{img/room4.png}\end{center}
  \caption{Scéna s vypočítanou radiozitou -- originální obrázek naleznete na~\href{http://dudka.cz/rrv}{{\tt http://dudka.cz/rrv}}}\label{room4}
\end{figure}
 
\chapter{Závěr}
Přestože je implementace výpočtu radiozity poměrně jednoduchá, poskytuje pěkné výsledky. Navíc je díky HW akceleraci výpočet rychlý. Konkrétní doba výpočtu závisí na složitosti vstup\-ní scény a zvolených parametrech. Při testování se doba výpočtu pohybovala v rozmezí několika minut až několika dní.
 
Byly splněny všechny požadavky zadání i hlavní cíle návrhu. Navíc bylo pomocí této implementace výpočtu radiozity vytvořeno zajímavé video. Hlavní výhoda projektu oproti běžně dostupným implementacím však spočívá v jeho jednoduchosti.
 
% ----------------------------------------------
% Použitá literatura
\bibliographystyle{./czechiso}
\begin{flushleft}
\bibliography{proj_doc}
\end{flushleft}
 
\end{document}