ČESKÉ VYSOKÉ UČENÍ TECHNICKÉ V PRAZE Fakulta elektrotechnická Katedra počítačové grafiky a interakce
Porovnání VRML prohlížečů Bakalářská práce
Vedoucí práce Ing. David Sedláček Student Marek Štych
leden 2012
ii
Poděkování Děkuji panu Ing. Davidu Sedláčkovi za obětavé vedení mé bakalářské práce, za podnětné připomínky a rady ke zpracovávané problematice.
iii
iv
Prohlášení Prohlašuji, že jsem svou bakalářskou práci s názvem Porovnání pokročilých zobrazovacích technik VRML prohlížečů vypracoval samostatně a použil k tomu úplný výčet citací použitých pramenů, které uvádím v seznamu přiloženém k práci. Nemám závažný důvod proti užití tohoto školního díla ve smyslu §60 Zákona č.121/2000 Sb., o právu autorském, o právech souvisejících s právem autorským a o změně některých zákonù (autorský zákon). V ……………. dne ………………
v
……………………. podpis
vi
Anotace Cílem této práce je porovnání prohlížečů formátu VRML z pohledu pokročilých zobrazovacích technik, jako jsou vícevrstvé textury, bump textury, shadery a stíny. Pro toto porovnání bylo nutné vytvořit scénu obsahující vhodné objekty pro testování, například zrcadla, koberce, vodu ve sklenici, zvlněné plochy. Výsledkem je úvaha, který z VRML prohlížečů poskytuje kvalitnější prostředky pro foto-realistické zobrazování v reálném čase.
Summary Goal of this work is comparison of VRML browsers, specifically theirs advanced graphic techniques such as layered textures, bump textures, shaders and shadows. It was necessary to create scene which include objects suitable for testing. For example carpets, mirrors, glass of water, bump surfaces. Outcome of this work is consideration, which of the VRML browsers provides us, with better tools for photo-realistic real time imaging.
vii
viii
Obsah 1. Úvod. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 2. Analýza . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 2.1. Použité nástroje . . . . . . . . . . . . . . . . . . . . . . . . .2 2.1.1. Blender . . . . . . . . . . . . . . . . . . . . . . . . 2 2.1.2. Chisel . . . . . . . . . . . . . . . . . . . . . . . . . 2 2.1.3. GIMP . . . . . . . . . . . . . . . . . . . . . . . . . 2 3. Vytvoření scény . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3 3.1 Vytváření scény v 3D modeláři . . . . . . . . . . . . . . . . . 3 3.2 Scéna ve VRML . . . . . . . . . . . . . . . . . . . . . . . . . 4 4. Porovnání pokročilých zobrazovacích technik na příkladech . . . . . . 6 4.1 Bump mapping . . . . . . . . . . . . . . . . . . . . . . . . . 6 4.1.1. Bump mapping v BS Contactu . . . . . . . . . . . .7 4.1.2. Bump mapping v Cortoně 3D . . . . . . . . . . . .11 4.1.3. Porovnání . . . . . . . . . . . . . . . . . . . . . . 13 4.2 Zrcadlení . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 4.2.1. Zrcadlení v BS Contactu . . . . . . . . . . . . . . 15 4.2.2. Zrcadlení v Cortoně 3D . . . . . . . . . . . . . . . 19 4.2.3. Porovnání . . . . . . . . . . . . . . . . . . . . . . 22 4.3 Vodní hladina . . . . . . . . . . . . . . . . . . . . . . . . . . 23 4.3.1. Vodní hladina v BS Contactu . . . . . . . . . . . . 24 4.3.2. Vodní hladina v Cortoně 3D . . . . . . . . . . . . .26 4.3.3. Porovnání . . . . . . . . . . . . . . . . . . . . . . 27 4.4 Chlupy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .28 4.4.1. Chlupy v BS Contactu . . . . . . . . . . . . . . . 28 4.4.2. Chlupy V Cortoně 3D . . . . . . . . . . . . . . . . 30 4.4.3. Porovnání . . . . . . . . . . . . . . . . . . . . . . 32 4.5 Stíny . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 4.5.1. Stíny v BS Contactu . . . . . . . . . . . . . . . . . 33 4.6 Oheň . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37 4.6.1. Oheň v BS Contactu . . . . . . . . . . . . . . . . . 37 4.6.2. Oheň v Cortoně 3D . . . . . . . . . . . . . . . . . 39 4.6.3. Porovnání . . . . . . . . . . . . . . . . . . . . . . 41 4.7. Výsledná scéna ve VRML prohlížečích . . . . . . . . . . . . .41 5. Závěr . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 6. Literatura . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 7. Přílohy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45 7.1 Obsah přiloženého CD . . . . . . . . . . . . . . . . . . . . 45 7.2 Přiložené kódy . . . . . . . . . . . . . . . . . . . . . . . . .45
ix
x
1. Úvod VRML (Virtual Reality Modeling Language) je grafický formát založený na deklarativním programovacím jazyce. Byl navržen pro popis trojrozměrných scén, které obsahují aktivní i pasivní objekty. Slouží tedy pro vytváření a zobrazování 3D grafiky. Tento jazyk má také prostředky pro tvorbu virtuální reality. Objekty se mohou pohybovat, měnit barvu, nebo mohou reagovat na kliknutí či táhnutí myší. Objekty také mohou reagovat na časovače, přítomnost Avatara nebo mohou samy generovat událost. Hlavní výhodou jazyka VRML je, že byl navržen pro použití na internetu. Virtuální světy tedy lze procházet na webu v reálném čase. Nejběžnější způsob, jak zobrazovatVRML soubory, je pomocí VRML pluginů. Tyto pluginy jsou známé jako VRML prohlížeč. Aby zobrazování VRML souborů fungovalo, je zapotřebí tento plugin stáhnout a nainstalovat do Internet Exploreru, Firefoxu, Google Chromu nebo do jiného webového prohlížeče. Těchto VRML prohlížečů je k dispozici několik. Například Cosmo Player, Flux Player, BS Contact, Cortona 3D. Všechny tyto prohlížeče jsou na internetu k dispozici zdarma. Cílem mé práce bylo porovnat VRML prohlížeče z pohledu pokročilých zobrazovacích technik. Pro nedostatek podpory pro pokročilé zobrazovací techniky jsem se rozhodl z porovnání VRML prohlížečů vyloučit všechny kromě BS Contactu a Cortony 3D. Oba tyto pluginy mají na internetu výborně zpracované domovské stránky, které poskytují podrobnosti o pluginech, příklady použití, download pluginu, ale hlavně podporu pro pokročilé zobrazovací metody. Výsledkem této práce je úvaha, která shrnuje použití pokročilých zobrazovacích technik v BS Contactu a Cortoně 3D a porovnává je.
2. Analýza Porovnání VRML prohlížečů BS Contact a Cortona 3D bude v této práci provedeno následovně. Nejprve bude vytvořena scéna v 3D modeláři. Po vytvoření scény v 3D modeláři je nutné ji exportovat do formátu wrl, který mohou zobrazovat VRML prohlížeče. Scéna bude exportována dvakrát, jedna bude určena pro BS Contact a jedna pro Cortonu 3D. Po odstranění všech komplikací spojených s exportem do VRML budou obyčejné předměty na scéně dotvořeny tak, aby vizuálně vylepšovaly scénu. Tyto úpravy budou provedeny stejně na scénách pro oba VRML prohlížeče. Dále se na scéně bude nacházet několik objektů, na které budou aplikovány pokročilé zobrazovací techniky. Oba VRML prohlížeče mají vlastní shadery a jiné pokročilé zobrazovací techniky, které lze zobrazit pouze v prohlížeči, pro který jsou určeny. Proto tyto objekty musí být vytvářeny dvakrát, jednou pro BS Contact a jednou pro Cortonu 3D, přičemž vizuální výsledky těchto objektů budou různé. Postupně budou vytvořeny všechny tyto objekty, které vypadají odlišně v BS Contactu a Cortoně 3D. Já budu u každého tohoto použití pokročilé zobrazovací techniky porovnávat výsledky z obou prohlížečů. Hodnocena bude jak vizuální stránka, tak zda objekty věrohodně kopírují fyzikální vlastnosti objektů z reálného světa. Na závěr bude vytvořeno několik fotografií kompletní scény v Cortoně 3D a BS Contactu. Poté bude také možno porovnat celkový dojem ze scény.
1
2.1. Použité nástroje Programy uvedené v této sekci byly nezbytné pro dosažení cílů práce. Budu se o nich často zmiňovat v textu dále, proto jsem se rozhodl uvést k těmto programům popis jejich funkce.
2.1.1. Blender 2.49 Pro tuto práci jsem potřeboval vytvořit scénu. Tato scéna obsahuje 3D objekty se složitou geometrií. Modelovat je přímo ve VRML by bylo zdlouhavé, u některých objektů dokonce téměř nemožné. Proto bylo zapotřebí použít 3D modeláře, nástroj, který pomáhá vytvářet 3D objekty, které je z něj možné exportovat do formátu kompatibilního s VRML prohlížeči. K dispozici je široký výběr 3D modelářů, například Maya, 3D studio Max, Lightweave atd. Všechny tyto modeláře jsou ale komerční produkty a jejich pořízení stojí nemalou částku. Jedinou alternativou bylo tedy použít 3D modelář Blender, který je zdarma. Nutno říct, že program Blender je i přes volnou licenci na srovnatelné úrovni s ostatními modeláři. Nejdůležitější pro mou práci byla funkce Blenderu nazvaná VRML 97, která exportuje objekty vytvořené v tomto modeláři do formátu wrl, který je zobrazitelný ve VRML prohlížečích. Více informací o programu Blenderu lze nalézt na jeho internetové stránce, kde jej lze i bezplatně získat.
2.1.2. Chisel Chisel je program zlepšující kvalitu, výkonnost a spolehlivost VRML kódu. Chisel nabízí široké spektrum nástrojů pro práci s VRML soubory: diagnostické nástroje pro lokalizování chyb, nástroj na přeměnu nebezpečného a špatně uspořádaného kódu na správně uspořádaný kód. Umožňuje ztrátovou i bezztrátovou redukci kódu. Na všechny soubory wrl, které vznikly exportem z programu Blender, jsem použil nástroj na správné uspořádání kódu (cleaner). Tento nástroj dělá kód menší a přehlednější tím, že odstraňuje kód, který je nepotřebný, redundantní nebo nevyužitý. Tímto nástrojem byla často velikost souboru snížena až na polovinu. Druhý nástroj, který jsem používal, byla ztrátová redukce kódu. Tuto redukci jsem používal na zaokrouhlování čísel, protože export z Blenderu pracoval s přesností na dvanáct desetinných míst. Tato přesnost byla pro moje účely naprosto redundantní. Program Chisel je na internetu volně dostupný.
2.1.3. GIMP 2 ( GNU Image Manipulation Program ) Gimp je program pro úpravu grafiky. Je používán pro úpravu fotografií, tvorbu webové grafiky a podobné účely. Dokáže upravovat jak rastrovou grafiku tak vektorové funkce. Díky tomu jsem s ním byl schopen upravovat všechny typy obrázků. Používal jsem jej jak pro úpravu obyčejných fotografií tak pro vytváření a úpravu textur. Program GIMP má volnou licenci, tzn. že jej lze získat na internetu bezplatně. To byl důvod, proč jsem se rozhodl použít GIMP namísto obdobného nástroje Adobe Photoshop.
2
3. Vytvoření scény Pro testování pokročilých metod zobrazování VRML prohlížečů bylo zapotřebí vytvořit objekty, na které tyto metody půjdou vhodně aplikovat. Rozhodl jsem se vytvořit scénu, ve které by všechny tyto předměty mohly být přítomny současně aniž by scéna působila nepřirozeně. Proto jsem vymodeloval kychyň. Kuchyň dává příležitost k aplikování všech pokročilých zobrazovacích technik, které jsem chtěl testovat. Obsahuje zrcadlo, které simuluje funkci reálného zrcadla, tzn. odráží obraz podle pozice pozorovatele. Na sporáku zde hoří oheň. Váza, stojící na stole, má na sobě vyryt vzor a působí plasticky. Pod kuchyňským stolkem je koberec, který je skutečně chlupatý. V dřezu je voda a v ní ponořená sklenička. Tato vodní hladina odráží jak věci nad hladinou, tak pod hladinou. Na podlahu v kuchyni dopadají stíny od ostatních objektů na scéně.Kuchyň také obsahuje obyčejné, statické předměty. Tyto předměty slouží pouze k vytvoření lepšího prostředí.
3.1. Vytvoření scény v 3D modeláři Všechny objekty vyjmenované v Popisu scény mají složitou geometrii. Vytvářet je přímo ve VRML by bylo zdlouhavé, pro některé objekty dokonce téměř nemožné. Proto scéna byla nejprve vymodelována pomocí 3D modeláře. Jako 3D modelář jsem zvolil Blender. Nejprve jsem vyfotil moji kuchyni, která mi posloužila jako volná předloha. Poté jsem v Blenderu postupně vymodeloval všechny objekty na scéně. Objektům byly nastaveny materiály, ze kterých jsou vytvořeny. Na některé objekty bylo zapotřebí umístit textury. Nakonec bylo nutné přidat na scénu několik bodových světel, osvětlujících linku a jedno světlo mimo místnost, reprezentující slunce. Výsledný render scény v Blenderu je vidět na obrázku 3.1.
Obrázek 3.1 Render scény z Blenderu 3
3.2. Scéna ve VRML Blender umožňuje export vymodelovaných objektů do jazyka VRML. Po provedení této procedury byla scéna zobrazitelná ve VRML prohlížeči. To ale odhalilo dva nedostatky, které bylo zapotřebí odstranit. První problém se týká materiálů a textur, tvořících povrch objektů. I přesto, že Blender dokáže některé materiály při renderování zobrazit, ve VRML materiál zobrazit nejde. Názorným příkladem tohoto materiálu je lesklý metalický povrch sporáku. Taktéž objekty, které byly v Blenderu natexturované ve VRML, natexturované nejsou. (viz. Obrázek 3.2) Bylo tedy nutné u všech objektů upravit položku appearance, obsahující nastavení materiálů a textur.
Obrázek 3.2 Problém s materiály a texturami
4
Druhý problém nastal jen u některých objektů. Po exportu jsem si totiž všiml, že u některých objektů je vždy vidět jen strana čelem k pozorovateli a zadní strana objektu je neviditelná. Problém nastal například u skleniček, které je možno vidět na obrázku 3.3. Tento problém jsem odstranil v Blenderu. Objekty, které jevily tuto chybu, jsem duplikoval a u jejich duplikátů jsem použil funkci Blenderu mesh → normals → recalculate outside. Poté jsem objekty znovu exportoval do VRML, kde bylo už vše v pořádku.
Obrázek 3.3 Problém s normálami objektů Po odstranění těchto esenciálních problémů byl VRML kód, vyexportovaný z Blenderu, často stále velice nepřehledný. Některé jeho části byly dokonce redundantní a VRML prohlížeče vyhazovaly varování (warnings). Protože jsem věděl, že se všemi objekty budu muset pracovat a manipulovat, rozhodl jsem se jejich VRML kódy co nejvíce zjednodušit a zpřehlednit, odstranit varování. Proto jsem zde postupně na všechny objekty použil program Chisel a jeho funkci Clean. Po použití programu Chisel byl kód přehledný a bez chyb a bylo možné ho použít v pokračování mé práce.
5
4. Porovnání pokročilých zobrazovacích technik na příkladech Tato kapitola má šest podkapitol. Každá podkapitola reprezentuje použití jedné pokročilé zobrazovací techniky. Tyto techniky se budu snažit použít v obou VRML prohlížečích. Pokud prohlížeč nebude danou pokročilou techniku zobrazování podporovat, pokusím se najít jiné řešení pro dosažení vizuálně podobného výsledku. Všechny tyto podkapitoly budou obsahovat použití techniky v BS Contactu, použití techniky v Cortoně 3D a jejich porovnání. V sekci použití techniky bude popsáno, jakým způsobem konkrétní technika funguje, jaký je její princip. Také se pokusím vysvětlit jak techniku správně použít. V sekci porovnání budu porovnávat výsledek práce v Cortoně 3D a BS Contactu. Každá pokročilá zobrazovací technika bude tedy hodnocena samostatně.
4.1 Bump mapping Bump mapping je technika texturování, která vytváří iluzi nerovnosti povrchu beze změn jeho geometrie. Iluze nerovnosti povrchu se dosahuje úpravou normály v každém pixelu plochy. Modifikovaná normála pak ovlivní výpočet osvětlené plochy. Výsledkem je zvlněný povrch objektu i přesto, že se geometrie povrchu objektu nezměnila. Pro lepší představu je uveden obrázek 4.1.1. pod textem. Na konvici na obrázku nahoře je aplikována bump mapa, díky které vypadá konvice na obrázku dole plasticky. Rozhodl jsem se Bump mapu použít na obyčejné váze. Cílem bylo, aby její povrch vypadal nerovně, vytvářel vzor, který je na váze vyrytý a tím zlepšil vizuální dojem z vázy. Pro obě varianty (pro BS Contact i Cortonu 3D) jsem použil stejné textury, stejnou scénu, tzn. polohu objektu vůči světlům a stejnou intenzitu světel.
Obrázek 4.1.1 Ukázka Bump mappingu
6
4.1.1. Bump mapping v BS Contactu V tomto VRML prohlížeči je Bump mapa zpracována pomocí vertex shaderu, který je volně dostupný na stránkách BS Contactu. Je pojmenován BumpPlastic.fx. Pro použití shaderu na objekt je zapotřebí zadefinovat jeho použití v appearance. Pro lepší představu uvádím příklad vložení Vertexshaderu BumpPlastic.fx ve zdrojovém kódu 4.1.1. appearance shaderAppearance{ vertexshader DEF Vertexshader1 Vertexshader { field SFFloat Bumpy 5 url "HLSL/BumpPlastic.fx" exposedField SFNode diffuseMap ImageTexture { url "textury/Vase.jpg" } exposedField SFNode normalMap ImageTexture { url "textury/trpos.jpg" } } }
zdrojový kód 4.1.1. V příkladu je vidět, že je zapotřebí definovat dvě textury. První textura reprezentuje materiál, ze kterého je objekt vyroben. To znamená, že pokud bychom měli obyčejný objekt, na který by nebyl aplikován Vertexshader, byla by toto jediná textura, která by byla použita. Ve výše uvedeném příkladu je to textura nazvaná Vase.jpg. Druhá textura reprezentuje takzvanou Bump mapu. Bump mapa definuje nerovnosti na povrchu objektu, tzn. místa, kde má objekt působit plasticky. V příkladu je to textura nazvaná trpos.jpg.
Obrázek 4.1.2. Použité textury Po definování použití shaderu a obou textur následuje geometrie objektu. Důležité je zmínit, že tento shader funguje pouze na objekty, jejichž geometrie je definována pomocí IndexFaceSet. Nelze ho tedy aplikovat na základní objekty jako je například koule, krychle, které byly vymodelovány pomocí specifických vrml funkcí jako například: Cube {width 1 height 1 depth 1 }
zdrojový kód 4.1.2. 7
Toto omezení mi však žádné nepříjemnosti nezpůsobilo. Všechny objekty v mé scéně byly vytvářeny pomocí 3D modeláře Blender. Po domodelování v Blenderu je nutné objekt exportovat do formátu VRML, aby bylo možné jej dále používat. Při tomto exportu jsou všechny objekty automaticky charakterizovány pomocí IndexFaceSet. Ale i za předpokladu, že někdo vytváří jednoduchou scénu, pro kterou nepotřebuje použít externí 3D modelář, lze jakékoliv těleso vymodelovat přímo pomocí IndexFaceSet. Pro uvedený přiklad modelování krychle pomocí funkce Cube existuje obdoba pomocí indexfaceset uvedená ve zdrojovém kódu 4.1.3. geometry IndexedFaceSet { solid TRUE coord DEF coord_Cube_012 Coordinate { point [ 1 -1 -1 1 -1 1 -1 -1 1 -1 -1 -1 1 1 -1 1 1 1 -1 1 1 -1 1 -1 ] } coordIndex 0 1 2 4 7 6 0 4 5 1 5 6 2 6 7 4 0 3 ]
[ 3 5 1 2 3 7
-1, -1, -1, -1, -1, -1,
}
zdrojový kód 4.1.3. IndexFaceSet určuje geometrii objektu. Položka point obsahuje seznam všech bodů, neboli vrcholů, keré těleso budou tvořit. Pod coordIndex se nachází pořadí, ve kterém se body mají spojit tak, aby vytvořily jednotlivé stěny objektu. Spojení bodů z kódu 4.1.3. podle prvního řádku v coordIndex je vidět na obrázku 4.1.3. Bod=( souřadnice x, souřadnice z, souřadnice y ) 0=( 1 -1 -1) 1=(1 -1 1) 2=(-1 -1 1) 3=(-1 -1 -1)
8
Obrázek 4.1.3. Ukázka IndexedFaceSet Takto je geometrie běžně určována u všech objektů. Oproti běžným objektům je pro správnou funkci Bumpmappingu ještě třeba zadefinovat texture coordinates. (viz zdrojový kód 4.1.4.) Tento seznam bodů definuje, jak bude textura aplikována na povrch tělesa. To přináší spoustu možností. Pomocí jedné textury a jedné bump textury lze díky texture coordinates vytvořit libovolný počet povrchů tělesa. texCoord MultiTextureCoordinate {coord [ TextureCoordinate { point [ 1 0, 1 .1, 1 .1, 1 .2, 1 .3, 1 .3, 1 .4, 1 .4, 1 .5, 1 .6, 1 .6, 1 .7, 1 .8, 1 .8, 1 .9, 1 .9, 1 1, 1 0, 1 .1, 1 .1, 1 .2, 1 .3, 1 .3, 1 .4, 1 .4, 1 .5, 1 .6, 1 .6, 1 .7, 1 .8, 1 .8, 1 .9, 1 .9, 1 1, 1 0, 1 .1, 1 .1, 1 .2, 1 .3, 1 .3, 1 .4, 1 .4, 1 .5, 1 .6, 1 .6, 1 .7, 1 .8,
]
] } TextureCoordGen { mode "TANGENT" parameter [ 0 2 ] }
}
zdrojový kód 4.1.4. 9
Výsledek BumpMappingu v BS Contactu:
Obrázek 4.1.4. Výsledek Bump mapy v BS Contactu
10
4.1.2. Bump mapping v Cortoně 3D V Cortoně 3D je celý kód VRML na první pohled velice jednoduchý. Na začátku je třeba definovat ExternProto pro Bump mapu, tzn. použít kód, který už někdo naprogramoval, což je obdoba BumpPlastic.fx u BSContactu. Použití může vypadat: zdrojový kód 4.1.5. EXTERNPROTO BumpMap [ exposedField SFNode texture exposedField SFVec3f direction ] [ "urn:ParaGraph:BumpMap" ]
zdrojový kód 4.1.5. Urn je internetový zdroj se jménem, které má narozdíl od Url trvalou hodnotu (význam). To znamená, že program bude vždy schopný najít zdroj. Poté je třeba v položce appearance (vzhled) nutné uvést cestu ke dvěma texturám, obdobně jako u BS Contactu jedna textura reprezentuje materiál, ze kterého je objekt vyroben a druhá textura představuje mapu nerovností povrchu (bump mapu). Toto zadání cest k texturám je uvedeno ve zdrojovém kódu 4.1.6. appearance AdvancedAppearance { material Material {diffuseColor 1 1 1} textures [ ImageTexture {url "textury/Vase.jpg"} DEF bm BumpMap { direction 1 0 0 texture ImageTexture {url "textury/trpos.jpg"} } ] backgroundFactor ["ZERO","ZERO"] foregroundFactor ["ONE","BACK_COLOR"] }
zdrojový kód 4.1.6. Součástí je také geometrie objektu, na který má být bump textura aplikována. Tato geometrie může být zadána jakýmkoliv způsobem použitelným ve VRML. Zdrojové kódy 4.1.5 a 4.1.6. vznikly úpravou zdrojových kódů volně dostupných na stránkách Cortony 3D. [1]
11
Výsledek BumpMappingu v Cortoně 3D:
Obrázek 4.1.5. Výsledek Bump mapy v Cortoně 3D
12
4.1.3. Porovnání Při porovnání výsledků je vidět, že BS Contact daleko lépe zvládá světlo dopadající na objekt, jsou jasně vidět místa, kde se těleso má lesknout, což dodává realistický dojem objektu. Oproti tomu Cortona nebere materiál, ze kterého je těleso vytvořeno, vůbec v úvahu. Proto vypadá váza stejně, když na ni dopadá světlo z několika lamp, nebo když na ni nedopadá světlo žádné. Chová se jako obyčejný objekt, kterému je pouze nastavena textura, ale žádný materiál. Další výhoda BS Contactu oproti Cortoně spočívá v namapování umístění textury. To umožňuje s jednou obyčejnou bump texturou dosáhnout na váze poměrně zajímavého vzorku. Cortona tuto možnost nemá, texturu si umístí na objekt automaticky a pokud se nám nelíbí, jak výsledný vzorek vypadá, je nejjednodušším způsobem, jak ho zlepšit, upravit samotnou Bump mapu. Velký rozdíl je ale také ve fázi programování. Zatímco v BS Contactu je zapotřebí získat soubor BumpPlastic.fx a potom ho vložit k souboru s vázou a zadat k němu cestu, Cortona si soubor jednoduše najde na internetu a v programu touto akcí zabere pouze jeden řádek. Dále ačkoliv mapování umístění textury může vypadat prakticky, přináší s sebou spoustu komplikací. Pokud je textura mapována na jednoduchý objekt jako je například krychle nebo koule, může být napsání texture coordinates jednoduché. Pokud však máme nějaký složitější objekt (v tomto případě vázu) a snažíme se na něj namapovat Bump mapu pomocí texture coordinates, jedná se o velice složitou a zdlouhavou práci. Závěrem lze shrnout, že se mi daleko lépe pracovalo s Cortonou 3D, objekty s Bump texturou vznikaly rychle a jednoduše, zatímco v BS Contactu byla práce zdlouhavější. Porovnání výsledků práce však nahrává spíše BS Contactu, takže pokud jde o vytváření scény, ve které má být několik objektů, na které má být aplikována Bump mapa, volil bych BS Contact, pokud je programátor s jazykem VRML obeznámen a nevadí mu strávit více času vytvářením scény. Naopak začátečníkovi s jazykem VRML bych doporučil Cortonu 3D, protože za poměrně malého úsilí lze dosáhnout solidních výsledků.
13
4.2. Zrcadlení Zrcadlení je část projektu, jejímž výsledkem má být zrcadlo, které je upevněno v rámu a visí na boční stěně kuchyně. Zrcadlo musí být věrohodné. To znamená, že podléhá zákonům fyziky. Proto jsem musel aplikovat tyto dva hlavní zákony platící pro odraz v zrcadle. Pokud je bod objektu o souřadnicích (x, y, z), potom odraz tohoto bodu bude mít souřadnice (-x, y, z), tedy zrcadlový odraz je obrácení souřadnic osy, která je kolmo k zrcadlu. (V mém případě je k zrcadlu kolmá osa x). Toto je vidět na fotografii z reálného světa na obrázku 4.2.1.
Obrázek 4.2.1. Ukázka zrcadlení v reálném světě V interaktivní scéně se obraz v zrcadle musí dynamicky měnit v závislosti na poloze pozorovatele a na směru pohledu pozorovatele. Tento problém opět řeší fyzika, tentokráte teorie odrazu světla od zrcadla. Důležité je, že úhel dopadu světla se rovná úhlu odrazu světla (viz obrázek 4.2.2).
Obrázek 4.2.2. Odraz světla od zrcadla 14
4.2.1. Zrcadlení v BS Contactu V BS Contactu jsem zrcadlení řešil pomocí Shaderu waterRTT.fx. Tento shader je určen k simulaci vodní hladiny. Původní použití Shaderu waterRTT.fx mohlo vypadat tedy například jako na obrázku 4.2.3.
Obrázek 4.2.3. Ukázka Shaderu waterRTT Pro použití shaderu na klasické zrcadlo bylo tedy zapotřebí udělat několik zásadních změn přímo v shaderu. První změnou byla úprava vzorečku, který slouží k výpočtu, jak mají být ve vodní hladině odráženy objekty (první řádek je původní, druhý je upravený). Změnou tohoto vzorečku jsem změnil výpočet souřadnice odráženého bodu tak, aby výsledný odražený objekt byl souměrný podle osy z k původnímu objektu. Pro lepší představu uvedu příklad: kdyby na výše uvedeném obrázku stál člověk na vodní hladině, jeho hlava by se odrážela nejníže, zatímco jeho nohy by byly nejvýše, blízko vodní hladiny. Pro potřeby zrcadla je ale zapotřebí, aby člověk dívající se do zrcadla viděl hlavu nahoře a nohy na zemi, ne aby stál vzhůru nohama. Pro lepší představu jsem uvedl obrázek 4.2.4. Out.oScreenTexCoord.z = ScreenTexCoord.z/screenTexCoordScale /2 ; Out.oScreenTexCoord.z = -ScreenTexCoord.z/screenTexCoordScale /2 ;
Obrázek 4.2.4. Znázornění odrazu v BS Contactu 15
Druhou nutnou úpravou v shaderu byla změna poměru odrazu a lomu (reflection, refraction). Hladina vody je průhledná. Zobrazuje tedy, co je pod ní, ale také odráží, co je nad ní.. Poměr odrazu a lomu je závislý na pozici a pohledu pozorovatele. Čím blíže jsme k hladině a díváme se k horizontu, tím více odráží hladina, co je nad ní, naopak čím kolměji se díváme na hladinu vody, tím spíše vidíme pouze to, co je pod hladinou a žádný odraz. To je v shaderu reprezentováno vzorečkem return lerp(refr,refl, f);
Funkce lerp je funkcí lineární interpolace. Určuje tedy poměr odrazu a lomu (refr = refraction, refl = reflection). F může nabývat hodnot 0 až 1, 0 reprezentuje pouze lom, 1 reprezentuje pouze odraz. Pro použití shaderu na obyčejné zrcadlo je třeba potlačit jakýkoliv lom, nesmí být vidět, co je za zrcadlem, je třeba jen odrazit obraz scény. Toho lze tedy dosáhnout úpravou vzorečku na return lerp(refr,refl, 1);
Poslední úpravou shaderu byla úprava zrcadlové plochy. Protože byl shader původně určen pro vodní hladinu, generuje na povrchu šum, který má reprezentovat vlnění vody. Tento šum bylo tedy nutné odstranit, čehož lze docílit úpravou vzorečku pro výpočet textury, která má být umístěna na zrcadlovou plochu. refl = tex2D(reflmap, ScreenTexCoord.xy /ScreenTexCoord.z + 0.5 -normalAnimMapColor.rg * disturbingScale) ; refl = tex2D(reflmap, (ScreenTexCoord.xy /ScreenTexCoord.z + 0.5) );
Pro aplikaci upraveného shaderu na plochu zrcadla bylo nejprve nutné tuto plochu vytvořit. Tato plocha musí mít pouze 2D rozměr, nesmí být například součástí povrchu kvádru. Plochu bylo třeba definovat pomocí IndexFaceSetu a muselo být zadefinováno, jak texturu zrcadla mapovat na tuto plochu, což je určeno pomocí MultiTextureCoordinates. (viz. Zdrojový kód 4.2.1) geometry IndexedFaceSet { coord Coordinate{ point[ -2.03 0.115 2.325 -2.03 0.115 2.9 -2.03 1.125 2.9 -2.03 1.125 2.325 ] } coordIndex[ 0 3 2 1 -1, ] texCoord MultiTextureCoordinate { coord [ TextureCoordinate { point [ 0 0, 1 0, 1 1, 0 1,] } TextureCoordGen { mode "COORD-EYE" } ] } }
zdrojový kód 4.2.1 16
Také je nutné definovat, jaké objekty se mají v zrcadle odrážet. To je provedeno uvedením těchto objektů v položce reflectChildren v appearance. V mém případě nechávám zrcadlo odrážet všechny objekty. Proto pod položkou reflectChildren v kódu 4.2.2. uvádím children USE scena, s tím, že scéna je definována jinde v kódu a obsahuje všechny objekty. Takto určené objekty pro zrcadlení jsem uzavřel do Transformu, aby bylo možné upravit souřadnice x tak, aby bylo splněno pravidlo o zrcadlení (viz výše). Scéna zobrazená v zrcadle je také posunuta o jeden metr níž. Důvodem pro tuto operaci byl pouze lepší vizuální vjem ze zrcadla. appearance M17_WaterShaderApp { reflectChildren [ Transform { scale -1 1 1 translation 0 -1 0 children USE scena } ] normalTex USE waterNormalTex fresnelTex USE waterFresnelTex }
zdrojový kód 4.2.2
17
Výsledek zrcadlení v BS Contactu
Obrázek 4.2.5. Výsledek v BS Contactu
18
4.2.2. Zrcadlení v Cortoně 3D V Cortoně 3D je efekt zrcadlení vyřešen poměrně jednoduchým trikem, namísto skutečného zrcadlení scény je odraz v zrcadle fotografie. Aby toto řešení skutečně fungovalo, nestačí jedna fotografie, ale je vytvořena krychle uvedená na obrázku 4.2.6, která má na každé své straně jednu fotografii. Jednotlivé fotografie potom musí být upravené tak, aby na sebe správně navazovaly.
Obrázek 4.2.6. Krychle s fotografiemi
19
Pro zjednodušení této úlohy a správné navázání fotografií na jednotlivých stranách krychle jsem nejprve vytvořil jakési panorama pokoje, které jsem potom rozdělil na tři menší fotografie a ty jsem umístil na tři strany krychle, tak jak je to uvedeno na obrázku 4.2.7. Pro potřeby modelovaného zrcadla stačí umístit fotografii jen na tři strany krychle
Obrázek 4.2.7. Znázornění umístění fotografií na krychli Pokud by tato krychle nebrala ohled na pozici pozorovatele, v mé scéně by zrcadlo pořád ukazovalo fotografii na straně označené jako 2 na obrázku 4.2.8. Protože je ale povrch této krychle závislý na pozici pozorovatele, dynamicky se fotografie přesouvají po povrchu krychle tak, aby na straně 2 byla vždy fotografie, nebo části dvou fotografií odpovídající tomu, co by pozorovatel měl skutečně vidět.
Obrázek 4.2.8. Znázornění posunu fotografií 20
Výsledek zrcadlení v Cortoně3D
Obrázek 4.2.9. Výsledek v Cortoně 3D
21
4.2.3. Porovnání Nejprve porovnám vytváření zrcadla. V BS Contactu bylo nutné upravovat shader samotný. To bylo poměrně složité, protože shader obsahuje hodně vzorečků pro výpočet správné textury, která se má na zrcadlo umístit a je nutné v těchto často dlouhých a složitých vzorcích hledat části, které musí být změněny, aby shader nefungoval jako vodní hladina, ale jako zrcadlo. Oproti tomu se v Cortoně 3D shader nemusel upravovat vůbec. Pro Cortonu 3D bylo oproti BS Contactu nutno vytvořit několik fotografií scény, které bylo nutno upravit. Úprava fotografií je poměrně jednoduchá, takže by neměla dělat problém nikomu se základními znalostmi programů Gimp nebo Photoshop. Některé 3D modeláře jako napřiklad Blender nabízejí přímo možnost vytvoření 6 fotografií, které na sebe navazují a tvoří krychli, čímž úprava fotografií odpadá úplně. Nejzásadnější rozdíl mezi BS Contactem a Cortonou 3D v zrcadle je při vkládání nových objektů do scény. Pokud přidáme nový objekt do BS Contactu, stačí ho pouze uvést pod položkou reflectChildren. Velice jednoduché, rychlé a funkční. Pokud přidáme objekt do Cortony 3D a chceme, aby byl také odrážen v zrcadle, je třeba udělat nové fotografie scény s objektem, upravit je a vyměnit. Ačkoliv se nejedná o složité operace, jsou poměrně zdlouhavé a činí celou práci se zrcadlem velice neefektivní. Z principu této problematiky také vyplývá, že zrcadlo v Cortoně není schopné zachytit pohyb objektů. Fotografie jsou jednoduše statické a neměnné, zatímco v BS Contactu jsou pohyblivé objekty bezchybně odráženy. V zrcadle je potom vidět plápolající oheň, otevírající se dveře nebo třeba hýbající se postavy. Zrcadlo v Cortoně 3D má oproti BS Contactu jednu výhodu, tou je jednoduchost. Jelikož se nejedná o skutečné zrcadlení objektů, je zrcadlo výpočetně jednoduché a scénu nezpomaluje. Pokud navíc fotografie uděláme v dobré kvalitě, je možné dosáhnout pěkného výsledku za cenu velice malých nároků na PC. Po zprovoznění zrcadla v BS Contactu jsem na průměrném a lepším PC nepozoroval žádný rozdíl ve vykreslování scény. Když jsem však zkoušel pustit scénu z BS Contactu na starém notebooku, zrcadlo významně ovlivnilo zpomalení vykreslování scény. Ve shrnutí bych rád doporučil každému, kdo uvažuje o zrcadle ve své scéně, použít BS Contact. I přesto, že do vytváření zrcadla musí vložit více úsilí, výsledek a možnosti práce s tímto výsledkem jsou daleko lepší než v Cortoně 3D a určitě stojí za tu trochu času navíc.
22
4.3. Vodní hladina Výsledkem vodní hladiny by měla být plocha. Tato plocha musí mít dvě vlastnosti: odrážet objekty, které se nacházejí nad hladinou vody (reflect).a zároveň zobrazovat objekty pod vodou . Vodní hladina by také měla aplikovat lom světla (refract), protože světlo se ve vodě šíří ¾ rychlostí oproti vzduchu. Všechny tyto aspekty vodní hladiny jsou vidět na fotografii z reálného světa na obrázku 4.3.1.
Obrázek 4.3.1. Vodní hladina v reálném světě
23
4.3.1 Vodní hladina v BS Contactu V BS Contactu je pro vytváření vodní hladiny shader. Tento shader se jmenuje WaterRTT.fx. Nejprve je nutné do kódu vložit spojení s tímto shaderem, což je uvedeno ve zdrojovém kódu 4.3.1., který jsem získal na stránkách BS Contactu. [2] EXTERNPROTO M17_WaterShaderApp [ exposedField SFNode skyCubeTex exposedField SFNode normalTex exposedField SFNode fresnelTex exposedField MFNode reflectChildren exposedField MFNode refractChildren field MFInt32 reflectSize field MFInt32 refractSize exposedField SFTime rippleInterval exposedField SFFloat perturbScale ]
Zdrojový kód 4.3.1. Dalším krokem je vytvoření scény, která bude obsahovat i vodní hladinu. Objekty je možné buď rovnou vytvářet ve stejném souboru, nebo je vkládat již vytvořené pomocí funkce inline. Použití této funkce je uvedenov přiloženém zdrojovém kódu 1. Když je scéna připravena, je nutno vytvořit samotnou vodní hladinu. Nejprve se definuje její geometrie pomocí indexedFaceSet. Vodní hladina v BS Contactu musí být vždy pouze plocha. To znamená, že má pouze 2D rozměr. Vytvoření takové 2D plochy je uvedeno v přiloženém zdrojovém kódu 2. Nyní je připravena plocha, na kterou má být umístěna textura, která bude zobrazovat odraz (reflect) objektů nad hladinou a lom (refract) objektů pod hladinou. To je díky shaderu WaterRTT.fx v BS Contactu velice jednoduché. V položce appearance zadefinujeme použití shaderu pomocí fráze appearance M17_WaterShaderApp, poté pod položku reflectChildren uvedeme objekty, které mají být odráženy ve vodní hladině a pod položku refractChildren uvedeme objekty, které jsou pod hladinou a mají být vidět. V mé scéně je dřez a v něm zpoloviny potopená sklenička. Proto nechávám dřez i skleničku jak odrážet ve vodní hladině tak zobrazovat jejich potopené části pod hladinou, což je provedeno pomocí zdrojového kódu 4.3.2. appearance M17_WaterShaderApp { reflectChildren [ USE umyvadlo USE OB_sklenicka ] refractChildren [ USE umyvadlo USE OB_Sklenicka_002 ] } }
Zdrojový kód 4.3.2
24
Takto připravená vodní hladina je plně funkční a splňuje základní požadavky. BS Contant, konrétně shader WaterRTT.fx ale umožňuje navíc dvě úpravy vodní hladiny. Tyto úpravy je nutné dělat přímo v shaderu. První úpravou lze získat zvlněnou hladinu. Shader WaterRTT.fx obsahuje proměnnou disturbing scale, kterou je možné měnit. Tím dosahujeme různého zvlnění vodní hladiny. Vlny se po povrchu vodní hladiny pohybují a podle jejich polohy se počítá jak odraz věcí nad hladinou tak podoba věcí pod hladinou, což vodní hladině dodává realističnosti. Druhá úprava se týká poměru lomu k odrazu. Shader WaterRTT.fx rozhoduje, kolik z výsledné textury bude ovlivněno objekty nad hladinou a kolik objekty pod hladinou. Čím se úhel pohledu pozorovatele k hladině blíží k 0°, tím více vidíme odraz objektů nad hladinou. Naopak čím více se úhel pohledu pozorovatele blíží k 90°, tím více vidíme objekty pod hladinou a méně odraz objektů nad hladinou. Tento poměr jde ale v shaderu libovolně upravovat. Můžeme využívat pouze odraz nebo lom, měnit vzorec tak, aby například voda více odrážela. Výsledek vodní hladiny v BS Contactu
Obrázek 4.3.2. Výsledek v BS Contactu 25
4.3.2. Vodní hladina v Cortoně 3D Cortona 3D nemá shader pro vytvoření vodní hladiny. Má dva shadery, které by bylo možné použít jako substituci. Jeden se stará o odraz, funguje jako zrcadlo. Druhý zobrazuje objekty za ním, ale upravuje jim geometrii. Tento shader by mohl být použit pro lom světla. Bohužel se tyto dva shadery nedají navzájem kombinovat. To znamená, že pomocí nich jde vytvořit vodní hladina, která pouze odráží objekty nad sebou, nebo vodní hladina, která pouze zobrazuje objekty pod vodou. Ani jedna z těchto vodních ploch by tedy nesplňovala kritéria pro správnou funkci vodní hladiny. Rozhodl jsem se tedy udělat vodní hladinu v Cortoně 3D pomocí obyčejné plochy. Této ploše jsem v nastavení materiálu, viz zdrojový kód 4.3.3, přiřadil průhlednost. Toto řešení lze aplikovat i v BS Contactu. appearance Appearance { material DEF MA_test Material { material DEF MA_test Material { diffuseColor 0 0.4 0.5 ambientIntensity 0.249999 specularColor 0 0.4 0.5 emissiveColor 0.0 0.0 0.0 shininess 0.153696 transparency 0.5 } } }
Zdrojový kód 4.3.3 Výsledek vodní hladiny v Cortoně 3D
Obrázek 4.3.3. Výsledek v Cortoně 3D 26
4.3.3. Porovnání Práce v BS Contactu nebyla složitá. Shader nebylo nutné upravovat. Výsledek je po vizuální stránce velice dobrý. Cortona 3D nemá žádný shader, který by byl vhodný pro vytváření vodní hladiny. Pokud má být ve scéně voda, ať už jde o pouhou trochu vody v dřezu, nebo o velkou vodní plochu jako je třeba řeka, doporučuji použít BS Contact, konrétně shader WaterRTT.fx, kterým se dá poměrně jednoduše vytvořit vodní hladina jakkoliv velká, klidná či rozbouřená. Tento shader má pouze jeden nedostatek. Vodní hladina je viditelná pouze z pohledu shora. Pokud by se pozorovatel díval z úhlu 0° vůči vodní hladině, nebyla by vidět. Pokud by se pozorovatel díval ze záporného úhlu, tzn. byl by pod hladinou vody, neviděl by také vůbec nic. Tento shader je tedy absolutně nevhodný pro scény, které se mají odehrávat pod hladinou vody. Ve všech ostatních případech je to jasná volba.
27
4.4. Chlupy Chlupy (z anglického fur) je kapitola, která se zabývá vytvořením materiálů, které jsou tvořeny z hodně vlasů (vláken). Mým cílem bylo vytvoření koberce, který má jednotlivá vlákna delší než je u obyčejných koberců běžné, přibližně 2-3 cm. Delší vlákna jsem zvolil hlavně pro jednoznačnější porovnání této pokročilé zobrazovací techniky v Cortoně 3D a BS Contactu.
4.4.1. Chlupy v BS Contactu Chlupy jsou v BS Contactu vytvářeny pomocí shaderu Fur.fx. Tento shader dělá iluzi chlupatých objektů tím, že vytvoří hodně ploch se stejným vzorem blízko nad sebou jak je znázorněno v obrázku 5.1. Z kódu, ve kterém se rozhodneme tento shader používat, mu musíme předat dvě proměnné. Jedna se nazývá GlowThickness. Úpravou této proměnné můžeme dosáhnout různé vzdálenosti ploch od sebe, čímž vytváříme hustší či řidší chlupy. Druhá se nazývá GlowColor. Ta reprezentuje barvu materiálu, který má být chlupatý.
Obrázek 5.1. Vrstvy vytvořené pomocí Fur.fx Je zde pouze jedna textura zobrazená na obrázku 5.2, která je aplikována na námi zadanou barvu materiálu. Tato textura se jmenuje Fur.dds. Funguje jako „šum,“ který způsobuje, že materiál nepůsobí jako jeden celek, ale hodně nezávislých chlupů.
Obrázek 5.2. Fur.dds 28
Slabší stránkou této techniky je zobrazování chlupatých objektů z dálky. Pokud od chlupatého objektu stojíme v určité vzdálenosti, začne vypadat jako by měl obyčejný, hladký povrch. Podobné pozorování můžeme vidět i v reálném světě, ale způsob, kterým je toto provedeno u shaderu Fur.fx, není vizuálně uspokojivý.
Výsledek chlupů v BS Contactu
Obrázek 5.3. Výsledek v BS Contactu
29
4.4.2. Chlupy v Cortoně 3D Efekt chlupů je v Cortoně 3D vytvořen pomocí directX 9.0 shaderu. Namísto obvyklého appearance, který definuje povrch většiny objektů, je zde ShaderAppearance. I zde lze definovat vizuální charakteristiku jako v obyčejném Appearance (například material a texture). Tyto údaje jsou ale brány v platnost pouze pokud DirectX9 není aktivován nebo pokud hardware nepodporuje shadery. Jsou tedy pouze jakousi pojistkou pro případ, že by na daném PC shader nefungoval. Pole vertexShader reprezentuje odkaz na vertex shader, který je klíčový pro správné zobrazení chlupatých objektů. Toto je vidět v Zdrojovém kódu 4.4.1. , který je volně k dispozici na stránkách Cortony 3D. [1] EXTERNPROTO ShaderAppearance [ exposedField SFNode fillProperties exposedField SFNode fragmentShader exposedField SFNode lineProperties exposedField SFNode material exposedField SFNode texture exposedField SFNode textureTransform exposedField SFNode vertexShader ]
Zdrojový kód 4.4.1 Uzel vertexShader definuje vertex shader, který modifikuje geometrii vrcholů. V příkladu, který je na stránce Cortony volně k dispozici, je již takový shader předpřipraven a lze jej využít. Dělat vlastní vertex shader by zabralo nepochybně spoustu času. Daleko lepší řešení je použít vertex shader, který už existuje a upravit ho co nejlépe pro svoje potřeby. Pro představu uvádím jako příklad vertex shader, který jsem použil já v přiloženém zdrojovém kódu 3.
30
Výsledek v Cortoně 3D
Obrázek 5.4. Výsledek v Cortoně 3D
31
4.4.3. Porovnání Porovnání těchto dvou technik není jednoduché. Vytvoření chlupatého koberce mi trvalo přibližně stejně dlouho v BS Contactu i v Cortoně 3D. Ani v jednom z VRML prohlížečů jsem nenarazil na žádný závažný problém, který by mi výrazně komplikoval aplikování shaderů na objekt. Z vizuálního hlediska pro mě bylo opět těžké vybrat vítěze. I přes moji snahu a úpravu shaderů samotných jsem ani u jednoho z prohlížečů nedosáhl výsledku, který by se dal hodnotit jako velmi dobrý. Nakonec dva faktory rozhodly, že bych pro tuto problematiku zvolil Cortonu 3D. Prvním je skutečnost, že chlupatý objekt vypadá stále stejně i při změně vzdálenosti od něj, což u BS Contactu neplatí. Druhým faktorem bylo porovnání použití těchto shaderů jinými lidmi. Jelikož jsem byl nerozhodný, který z koberců vypadá lépe, rozhodl jsem se najít další použití těchto shaderů. Zatímco u BS Contactu jsem nenašel ukázku, která by vypadala výrazně lépe než můj koberec, u Cortony 3D byl k dispozici na domovských stránkách příklad použití, který uvádím na obrázku 5.5 a jehož výsledek hodnotím jako uspokojivý.
Obrázek 5.5. Ukázka chlupů v Cortoně 3D
32
4.5. Stíny V reálném světě každý objekt, na který dopadá světlo, vrhá stín. To zobrazuje obrázek 4.5.1. Technika stínování ve VRML by měla simulovat stíny tak, jak by vypadaly v reálném světě. Cortona 3D nemá pro stíny žádný shader. Proto jsem se soustředil pouze na BS Contact, který pro techniku stínování shader má. Mým cílem bylo zjistit, jak kvalitní vrhané stíny jsou a zda-li fungují i v dynamické scéně, ve které se objekty pohybují.
Obrázek 4.5.1. Stíny v reálném světě
4.5.1. Stíny v BS Contactu V BS Contactu jsou stíny vytvářeny pomocí shaderu ShadowShader.fx. Pro jeho správné použití v příkladu je zapotřebí vytvořit přibližně 400 řádek kódu pro správnou komunikaci se shaderem. Proto je lepší zkopírovat tento kód z příkladu uvedeného na stránkách BS Contactu a upravit ho tak, aby vyhovoval pro naši scénu. Scéna z příkladu na stránkách BS Contactu je zobrazena na obrázku 4.5.2.
Obrázek 4.5.2. Stíny v BS Contactu 33
Na scéně je vidět pohybující se žonglér a několik statických objektů, válců. Nejdůležitější je však plocha, na které objekty stojí, protože na tu se promítají stíny.Světlo vrhá lampa, která rotuje okolo celé scény. V následujícím popisu budu bod po bodu vysvětlovat, co je zapotřebí změnit, aby stíny byly v jiné scéně. Nejprve je nutné vyjmout objekty z příkladu a nahradit je vlastními objekty. Důležité je objekty rozdělit na dvě skupiny. Na ty, které mají vrhat stíny a na ty, které nemají. Předměty, které vrhají stín, by měly být uvedeny ve skupině sceneShadow. Předměty, které stín nevrhají, mohou být umístěny libovolně v kódu. Příklad takového rozdělení je kód 4.5.1. který vznikl úpravou kódu příkladu na obrázku 4.5.2. DEF stena_bok_pravy Transform { //pravá stěna nevrhá stín children [ Inline { url ["./help/stenabok.wrl"] } ] } DEF sceneShadow Group { // vše v této skupině stín vrhá children [ DEF OB_mramorova_deska Transform { children [ Inline { url ["./help/mramorova_deska.wrl"] }
]
] } DEF OB_stena_zadni Transform { children [ Inline { url ["./help/stenabok2.wrl"] } ] } DEF Stul Transform { children [ Inline { url ["./help/stolek.wrl"] } ] }
}
Zdrojový kód 4.5.1
34
Nyní jsou na scéně místo původních objektů objekty z naší scény. Teď je nutné upravit zem této scény. Pravděpodobně zem z příkladu v BS Contactu nebude vyhovovat rozměrům a pozici v naší scéně. Zem je definována pomocí IndexedFaceSet, které lze libovolně měnit. Pokud by pro naše účely objektu, na který dopadají stíny, nebyla vhodná plocha, je možné pomocí IndexedFaceSet vymodelovat jakýkoliv objekt. To znamená, že stíny mohou dopadat ve scéně na všechny objekty, ne jenom na zem. Jak bylo řečeno v úvodu, světlo v původní scéně mění svoji pozici. Pohybuje se po kružnici a vždy svítí na její střed. Pro většinu obyčejných scén je ale zapotřebí statické světlo. Toho lze docílit změnou proměnné f a r, f reprezentuje úhel, ve kterém se světlo nachází na kružnici. R představuje poloměr kružnice, po které se světlo pohybuje. Pro lepší představu uvádím obrázek 4.5.3.
Obrázek 4.5.3. Znázornění proměnných k a r Pomocí těchto dvou proměnných můžeme světlo dostat do libovolné polohy. Pokud scéně nevyhovuje světlo směřující do středu, je možné upravit tento vzoreček: var direction = new SFVec3f(x,y,2+Math.sin(f));
35
Výsledky stínů v BS Contactu
Obrázek 4.5.4. Výsledek v BS Contactu
36
4.6. Oheň Na scéně se nachází sporák, na kterém hoří oheň. Pro oheň je důležité, že nesmí být statický. Pokud bychom měli statický objekt a na něm obyčejnou texturu, oheň by nevypadal reálně. Proto cílem této části práce je udělat oheň, který se co nejvíce podobá reálnému ohni, který plane.
4.6.1. Oheň v BS Contactu V BS Contactu je efekt hořícího ohně vytvořen pomocí speciálního shaderu, který se jmenuje Flame.fx. Tento shader vytváří 2D plochy, viz obrázek 4.6.1. Tyto plochy umísťuje velice blízko za sebe. Na každou z nich je použita textura ohně. Tím je vytvořena iluze 3D ohně.
Obrázek 4.6.1. Znázornění 2D ploch Aby oheň hořel, tedy nebyl pouze statický, je třeba na jednotlivé 2D plochy, ze kterých je tvořen, aplikovat šum. Flame.fx na to používá čtyři oktávy procedurálního šumu. (viz. originál zdrojového kódu, získaného ze stránek BS Contactu, Zdrojový kód 4.6.1) float4 GenerateNoise4f(float3 Pos : POSITION) : COLOR{ float4 c; float3 P = Pos*VOLUME_SIZE; c.r = noise(P); c.g = noise(P + float3(11, 17, 23)); c.b = noise(P + float3(57, 93, 65)); c.a = noise(P + float3(77, 15, 111)); return abs(c); }
Zdrojový kód 4.6.1 Pro použití shaderu je doporučeno použít příklad ze stránek BS Contactu. Tento příklad obsahuje přibližně 150 řádek javascriptu, který je zapotřebí pro správnou funkci shaderu. Nejjednodušší je tedy zkopírovat tento javascript a pouze upravit proměnné a vzorečky tak, aby oheň měl správnou velikost a vzdálenost jednotlivých 2D ploch od sebe. Také lze upravit frekvenci šumu. Nastavení těchto parametrů závisí na scéně, ve které chceme oheň použít a je individuální. 37
Tato technika má jeden zásadní nedostatek. Textura je na 2D plochu mapována pouze z jedné strany. Když si oheň prohlížíme zepředu, vidíme ho správně. Pokud se pomalu mění pozice pozorovatele tak, že se na oheň začne dívat z boku, oheň se pomalu vytrácí. Když dosáhneme bodu, kdy bychom měli vidět texturu ohně na druhé straně 2D plochy, oheň zmizí. Tento nedostatek je vidět na výsledných fotografiích. Pokoušel jsem se upravit shader tak, aby se obraz ohně na 2D plochách vykresloval z obou stran, což se mi nepodařilo. Předpokládám však, že by tvůrce shaderu dokázal tento nedostatek odstranit. Skutečnost, že oheň není vidět z boku, je Achillova pata této techniky. Z principu tento problém nejde odstranit. Výsledek hořícího ohně v BS Contactu:
Obrázek 4.6.2. Výsledek v BS Contactu
38
4.6.2. Oheň v Cortoně 3D V Cortoně 3D není pro hořící oheň žádná specifická technika. Rozhodl jsem se tedy udělat oheň pomocí animace typu gif. V programu Gimp jsem vytvořil animaci ohen.gif. Tato animace je ve VRML použita jako textura, kontrétně MovieTexture pro libovolný objekt. Pro oheň sporáku jsem použil jako objekt, na který byla textura umístěna, kouli. Dále jsem v appearance vložil řádek loop TRUE, který zajistí nekonečné opakování animace. Tuto jednoduchou techniku na vytvoření ohně vystihuje zdrojový kód 4.6.2. Transform { rotation 0 0 1 0 children [ Shape {appearance Appearance { texture MovieTexture { loop TRUE url "ohen.gif" } } geometry Sphere {radius 0.035}} ] }
Zdrojový kód 4.6.2
39
Výsledek hořícího ohně v Cortoně 3D
Obrázek 4.6.3. Výsledek v Cortoně 3D
40
4.6.3. Porovnání Výše byly uvedeny dvě techniky, kterými lze vytvořit efekt hořícího ohně. Jedna technika je použitelná pouze v BS Contactu, druhá technika je použitelná v obou VRML prohlížečích. Srovnání prohlížečů tedy pro tuto úlohu nemá smysl. BS Contact má možnost navíc, kterou Cortona nemá a je tedy rozhodně lepší volbou, pokud chceme mít ve scéně oheň. Za porovnání ale tyto dvě techniky stojí. Shader z BS Contactu nám umožňuje vytvořit daleko realističtější oheň. Ten ale nevypadá dobře, pokud se na něj díváme z velkého úhlu nebo zezadu, což nevadí, pokud na scéně nehrozí, že pozorovatel dosáhne těchto hluchých úhlů (například oheň v krbu). Pokud má být ale oheň ve středu scény, nebo pokud se oheň má pohybovat okolo pozorovatele, je použití tohoto shaderu nerozumné. V tomto případě bych volil řešení pomocí animace gif. Ačkoliv animací nelze dosáhnout tak dobrého vizuálního výsledku jako u shaderu Flame.fx, lze dobrou prací na animaci dosáhnout slušných výsledků. Tato technika je tedy spíše náročná na práci v programech photoshop, Gimp, atd. než ve VRML.
4.7. Výsledná scéna ve VRML prohlížečích Všechny pokročilé zobrazovací techniky už byly použity. Každá technika byla hodnocena a porovnána individuálně. V grafice ale nemusí záležet jenom na jednotlivých detailech, ale na celkovém dojmu ze scény. Proto v této kapitole uvedu obrázky kompletní scény. Nejprve fotografii renderu scény z blenderu na obrázku 4.7.1. Tuto fotografii jsem bral jako předlohu a ideál, kterému jsem se při práci s VRML snažil přiblížit. Jak jednotlivé VRML prohlížeče dokázaly zachytit ducha scény je vidět na fotografiích 4.7.2. a 4.7.3.
Obrázek 4.7.1. scéna ve 3D modeláři 41
Obrázek 4.7.2. scéna ve VRML prohlížeči BS Contact
Obrázek 4.7.3. scéna ve VRML prohlížeči Cortona 3D 42
5. Závěr V této práci jsem postupně testoval několik pokročilých zobrazovacích technik. Zobrazovací technika byla vždy použita ve dvou VRML prohlížečích, v BS Contactu a Cortoně 3D. Ostatní VRML prohlížeče, které fungují jako pluginy do webových prohlížečů, nemají takovou podporu a možnosti jako tyto dva, proto by porovnávání s nimi nemělo žádný význam. Poté, co jsem objekt vytvořil v obou prohlížečích, jsem zhodnotil a porovnal konkrétní nedostatky a přínosy. Porovnával jsem fázi programování, tedy jak bylo složité zobrazovací techniku zprovoznit, jak složitá je manipulace s ní, tedy například její úprava. Rozhodujícím faktorem ale bylo, jak objekt, na který byla pokročilá zobrazovací technika použita, vypadal. Vzhledem k tomu, že se jedná o grafickou prezentaci, je vizuální výsledek tím nejdůležitějším. Když jsem začínal realizovat první porovnání Bump mappingu, Cortona 3D mi připadala jednodušší a práce s ní byla rychlá, zatímco s BS Contactem jsem se dlouho trápil. Některé kódy uvedené na stránkách BS Contactu navíc nešly otevřít v běžném textovém editoru ani v Netbeans, ale musel jsem kvůli nim stáhnout VRMLPad. Přestože mi práce s BS Contactem v tomto případě připadala zbytečně složitá a zdlouhavá, výsledek byl vizuálně lepší než výsledek v Cortoně 3D. S každou další zobrazovací technikou jsem se s BS Contactem seznamoval víc a víc. Nakonec jsem se dostal do fáze, kdy jsem dokázal zobrazovací techniky vytvářet a upravovat stejně rychle jako v Cortoně 3D. Vizuální výsledky všech zobrazovacích technik byly lepší u BS Contactu. Cortona 3D dokonce některé složitější funkce, například stíny, neuměla zobrazovat vůbec. Proto bych na závěr své práce rád doporučil každému, kdo uvažuje o použití jakékoliv z pokročilých zobrazovacích technik, použít BS Contact. Ze začátku může být práce s ním složitější, ale jsem přesvědčen, že každá minuta investovaná navíc se vrátí ve vizuálním výsledku modelované scény.
43
6. Literatura [1]
VRML Extensions : Advanced visual effects. [online]. [vid. 2011-12-21]. Dostupné z: http://www.parallelgraphics.com/developer/products/cortona/extensions
[2]
BS Contact VRML/X3D Release 7.0: DirectX9 Shader Support. [online]. [vid.2011-12-21]. Dostupné z: http://www.bitmanagement.com/developer/contact/examples/shader/shader.html
[3]
TIŠŇOVSKÝ, Pavel. VRML: jazyk pro popis virtuální reality. [online]. [vid. 2011-12-21]. Dostupné z: http://www.root.cz/clanky/vrml-jazyk-pro-popis-virtualni-reality/
[4]
Prof. NELSON, Stephen. Properties of Light: Reflection, Refraction, Dispersion, and Refractive Indices: Reflection and Refraction of Light. [online]. [vid. 2011-12-21]. Dostupné z: http://www.tulane.edu/~sanelson/geol211/proplight.htm
[5]
Rendering Pipeline Overview: Geometry shader. [online]. [vid. 2011-12-21]. Dostupné z: http://www.opengl.org/wiki/Rendering_Pipeline_Overview#Geometry_Shader
44
7. Přílohy Přílohy obsahují dodatečné informace k přiloženému CD, pro lepší orientaci ve složkách. Také jsou zde uvedeny zdrojové kódy, které byly příliš dlouhé na to aby bylo vhodné uvádět je přímo v textu.
7.1. Obsah přiloženého CD Na přiloženém CD jsou kromě tohoto dokumentu přiložené dvě VRML scény, na kterých byly pokročilé zobrazovací techniky porovnávány. Cortona 3D scene Tato složka obsahuje scénu vytvořenou v Cortoně 3D. Scéna se spouští pomocí application.wrl. BS Contact scene Tato složka obsahuje scénu vytvořenou v BS Contactu. Scéna se spouští pomocí application.wrl.
7.2. Přiložené zdrojové kódy Přiložený zdrojový kód 1 DEF umyvadlo Transform { children [ Inline { url ["./drez.wrl"] } ] } DEF OB_Sklenicka Transform { children [ Inline { url ["./sklenicka.wrl"] } ] }
Přiložený zdrojový kód 2 DEF waterPlane Shape { geometry IndexedFaceSet { coord Coordinate{ point[ 1.1 -0.2 1.65 -0.2 1.65 -0.2 1.1 -0.2 ] } coordIndex[ 0 1 2 3 0 -1, ]
45
1.3, 1.3, 0.6, 0.6,
Přiložený zdrojový kód 3 Tento zdrojový kód vznikl úpravou kódu ze stránek Cortony 3D. [1] vertexShader DEF VertexShader1 VertexShader { exposedField SFNode Tex0 USE Tex0 url "hlsl: texture Tex0; float4x4 ModelView : WORLDVIEW; float4x4 Projection : PROJECTION; float3 LightDir = normalize(float3(1.0f,1.0f,1.0f)); float4 GlowColor = float4(0.2f,0.1f,0.0f,0.35f); float4 GlowAmbient = float4(0.1f,0.1f,0.1f,0.1f); float GlowThickness = 0.0f; float currentpass : CURRENTPASS; struct VSTEXTURE_OUTPUT{ float4 Position : POSITION; float4 Diffuse : COLOR; float2 TexCoord : TEXCOORD0; }; VSTEXTURE_OUTPUT VSTexture ( float4 Position : POSITION, float3 Normal : NORMAL, float2 TexCoord : TEXCOORD0) { VSTEXTURE_OUTPUT Out = (VSTEXTURE_OUTPUT)0; float3 L = -LightDir; float3 P = mul(Position,(float4x3)ModelView); float3 N = normalize(mul(Normal,(float3x3)ModelView)); Out.Position = mul(float4(P,1),Projection); Out.Diffuse = 0.1f*max(1,1); Out.TexCoord = TexCoord; return Out; } struct VSGLOW_OUTPUT{ float4 Position : POSITION; float4 Diffuse : COLOR; float2 TexCoord : TEXCOORD0; }; VSGLOW_OUTPUT VSGlow ( float4 Position : POSITION, float3 Normal : NORMAL, float2 TexCoord : TEXCOORD0) { VSGLOW_OUTPUT Out = (VSGLOW_OUTPUT)0; float displacement = GlowThickness * .1; float3 P = mul(Position,(float4x3)ModelView); float3 N = normalize(mul(Normal,(float3x3)ModelView)); P += N*displacement; P[1]+=.01* currentpass; Out.Position = mul(float4(P,1),Projection); float3 L = -LightDir; Out.Diffuse = GlowColor*1.25; Out.TexCoord = TexCoord; Out.TexCoord.y -= 0.01 * currentpass / 14.0; Out.Diffuse.b *= 1.0 - currentpass / 14.0; Out.Diffuse.w *= 1.0 - currentpass*0.01; return Out; } technique TGlowAndTexture{ pass PTexture {
46
VertexShader = compile vs_1_1 VSTexture(); } pass PGlow0{ VertexShader = compile vs_1_1 VSGlow(); PixelShader = NULL; Texture[0]= (Tex0); AlphaBlendEnable = TRUE; SrcBlend = SRCALPHA; DestBlend = ONE; ColorOp[0]= MODULATE; ColorArg1[0]= TEXTURE; ColorArg2[0]= CURRENT; AlphaOp[0]= MODULATE; AlphaArg1[0]= TEXTURE; AlphaArg2[0]= CURRENT; ZWriteEnable = FALSE; AlphaTestEnable = TRUE; } pass PGlow1{VertexShader = compile vs_1_1 VSGlow();} pass PGlow2{VertexShader = compile vs_1_1 VSGlow();} pass PGlow3{VertexShader = compile vs_1_1 VSGlow();} pass PGlow4{VertexShader = compile vs_1_1 VSGlow();} pass PGlow5{VertexShader = compile vs_1_1 VSGlow();} pass PGlow6{VertexShader = compile vs_1_1 VSGlow();} pass PGlow7{VertexShader = compile vs_1_1 VSGlow();} pass PGlow8{VertexShader = compile vs_1_1 VSGlow();} pass PGlow9{VertexShader = compile vs_1_1 VSGlow();} pass PGlow10{VertexShader = compile vs_1_1 VSGlow();} pass PGlow11{VertexShader = compile vs_1_1 VSGlow();} pass PGlow12{VertexShader = compile vs_1_1 VSGlow();} pass PGlow13{VertexShader = compile vs_1_1 VSGlow();} pass PGlow14{VertexShader = compile vs_1_1 VSGlow();} } "
}
47