Niektóre zaawansowane możliwości biblioteki Three.js

Podobne dokumenty
Rysunek 1: Okno timeline wykorzystywane do tworzenia animacji.

Aleksandra Zając. Raport. Blender. Pokemon: Eevee

Ćwiczenie 4 - Podstawy materiałów i tekstur. Renderowanie obrazu i animacji

Sieciowe Technologie Mobilne. Laboratorium 2

Animacje z zastosowaniem suwaka i przycisku

Tworzenie nowego rysunku Bezpośrednio po uruchomieniu programu zostanie otwarte okno kreatora Nowego Rysunku.

Systemy wirtualnej rzeczywistości. Komponenty i serwisy

Wprowadzenie do WebGL i Three.js

Aplikacje WWW - laboratorium

Oświetlenie. Modelowanie oświetlenia sceny 3D. Algorytmy cieniowania.

Funkcje i instrukcje języka JavaScript

Przy dużej wielkości głębokości uzyskamy wrażenie nieskończoności: Dla głębokości zerowej uzyskamy tekst płaski:

Ustawienia materiałów i tekstur w programie KD Max. MTPARTNER S.C.

IRONCAD. TriBall IRONCAD Narzędzie pozycjonujące

Grafika Komputerowa Wykład 4. Synteza grafiki 3D. mgr inż. Michał Chwesiuk 1/30

Wprowadzenie do rysowania w 3D. Praca w środowisku 3D

Grafika Komputerowa Wykład 5. Potok Renderowania Oświetlenie. mgr inż. Michał Chwesiuk 1/38

Ćwiczenie 1 Galeria zdjęć

BLENDER- Laboratorium 1 opracował Michał Zakrzewski, 2014 r. Interfejs i poruszanie się po programie oraz podstawy edycji bryły

Misja#3. Robimy film animowany.

Grafika Komputerowa Wykład 6. Teksturowanie. mgr inż. Michał Chwesiuk 1/23

GIMP. Ćwiczenie nr 6 efekty i filtry. Instrukcja. dla Gimnazjum 36 - Ryszard Rogacz Strona 18

Badanie ruchu złożenia

Podstawy programowania, Poniedziałek , 8-10 Projekt, część 1

Obiektowy PHP. Czym jest obiekt? Definicja klasy. Składowe klasy pola i metody

weblsp Wybór przeglądarki i jej ustawienia Instrukcja ADH-Soft sp. z o.o., ul. 17 Stycznia 74, Warszawa

Grafika 3D program POV-Ray - 1 -

Techniki wizualizacji. Ćwiczenie 10. System POV-ray tworzenie animacji

Pętle. Dodał Administrator niedziela, 14 marzec :27

Ćwiczenie 1 Automatyczna animacja ruchu

Przewodnik po soczewkach

Mapowanie sześcienne otoczenia (cubic environment mapping)

Gry Komputerowe Laboratorium 4. Teksturowanie Kolizje obiektów z otoczeniem. mgr inż. Michał Chwesiuk 1/29. Szczecin, r

Opis funkcji modułu Konwerter 3D

SYSTEMY OPERACYJNE I SIECI KOMPUTEROWE

Wyrażenie include(sciezka_do_pliku) pozwala na załadowanie (wnętrza) pliku do skryptu php. Plik ten może zawierać wszystko, co może się znaleźć w

Po uruchomieniu programu nasza litera zostanie wyświetlona na ekranie

Smarty PHP. Leksykon kieszonkowy

Rys Odtwarzacz filmu. Możemy także skorzystać z programów służących do odtwarzania filmów np. Windows Media Player.

Google Earth. Co to jest Google Earth? Co to jest KML? Skąd można pobrać Google Earth?

Animacja. Instrukcja wykonania animacji metodą klatek kluczowych. Autor: Bartosz Kowalczyk. Blender 2.61

Studia Podyplomowe Grafika Komputerowa i Techniki Multimedialne, 2017, semestr II Modelowanie 3D - Podstawy druku 3D. Ćwiczenie nr 4.

2 Przygotował: mgr inż. Maciej Lasota

SUM Edukacja Techniczno Informatyczna Języki i Systemy Programowania. Wykład 3. dr Artur Bartoszewski - WYKŁAD: Języki i Systemy Programowania,

przedmiot kilka razy, wystarczy kliknąć przycisk Wyczaruj ostatni,

Bartosz Bazyluk SYNTEZA GRAFIKI 3D Grafika realistyczna i czasu rzeczywistego. Pojęcie sceny i kamery. Grafika Komputerowa, Informatyka, I Rok

Polecenie ŚWIATPUNKT - ŚWIATŁO PUNKTOWE

Wskaźniki a tablice Wskaźniki i tablice są ze sobą w języku C++ ściśle związane. Aby się o tym przekonać wykonajmy cwiczenie.

TECHNOLOGIE INTERNETOWE WYKŁAD 6. JavaScript Funkcje i obiekty

DesignCAD 3D Max 24.0 PL

Jak zrobić klasyczny button na stronę www? (tutorial) w programie GIMP

Raytracer. Seminaria. Hotline. początkujący zaawansowani na miejscu

Liczby losowe i pętla while w języku Python

Unity. Platforma do tworzenia gier dla różnych systemów docelowych, m.in.: Windows, macos, ios, Android, Powstała w 2005 r., obecnie wersja 5.3.

Ćwiczenie 22 Dynamiczne wczytywanie tekstu z pliku.txt

wersja 1.0 ośrodek komputerowy uj cm ul. mikołaja kopernika 7e, Kraków tel

1 TEMAT LEKCJI: 2 CELE LEKCJI: 3 METODY NAUCZANIA 4 ŚRODKI DYDAKTYCZNE. Scenariusz lekcji. Scenariusz lekcji. 2.1 Wiadomości: 2.

Grafika Komputerowa Materiały Laboratoryjne

Sieciowe Technologie Mobilne. Laboratorium 4

znajdowały się różne instrukcje) to tak naprawdę definicja funkcji main.

Materiały dla studentów pierwszego semestru studiów podyplomowych Grafika komputerowa i techniki multimedialne rok akademicki 2011/2012 semestr zimowy

Uniwersytet Zielonogórski Instytut Sterowania i Systemów Informatycznych. Ćwiczenie 3 stos Laboratorium Metod i Języków Programowania

Wizualizacja płomienia

Spora część kodu programu jest dla nas nieprzydatna. Dokonaj zmian tak, aby kod miał postać:

- dodaj obiekt tekstowy: /** Maciej */ Stage { title : "First JavaFX App" scene: Scene { width: 300 height: 300 content: [ ] } }

Unity 3D - własny ekran startowy i menu gry

Zastosowania Robotów Mobilnych

Politechnika Warszawska Wydział Mechatroniki Instytut Automatyki i Robotyki

Zawartość. Wstęp. Moduł Rozbiórki. Wstęp Instalacja Konfiguracja Uruchomienie i praca z raportem... 6

1. Opis okna podstawowego programu TPrezenter.

Widżety KIWIPortal. tworzenie umieszczanie na stronach internetowych opcje zaawansowane. Autor: Damian Rebuś Data: Wersja: 1.

Dokąd on zmierza? Przemieszczenie i prędkość jako wektory

Informatyka I. Klasy i obiekty. Podstawy programowania obiektowego. dr inż. Andrzej Czerepicki. Politechnika Warszawska Wydział Transportu 2018

HELIOS pomoc społeczna

Plan wykładu. Akcelerator 3D Potok graficzny

Tytuły Wykonawcze. Opis systemu tworzenia dokumentacji TW-1

Laboratorium 7 Blog: dodawanie i edycja wpisów

Ćwiczenie 14 Dmuchawce

Unity 3D - podpowiedzi w grze. System cząstek

Język C++ zajęcia nr 2

Chocofur szkolenie średniozaawansowane

Załącznik techniczny przedmiotu zamówienia komponentu

TEMAT :Animacja Komputerowa. Projekt współfinansowany w ramach Europejskiego Funduszu Społecznego

Spis treści. 1: Wyszukiwanie elementu : Do linii modelu : Powiel arkusze : Długość kabla : Rozmieszczenie widoków...

JAVAScript w dokumentach HTML (1) JavaScript jest to interpretowany, zorientowany obiektowo, skryptowy język programowania.

1 Tworzenie brył obrotowych

WSTĘP DO GRAFIKI KOMPUTEROWEJ

Programowanie obiektowe

0. OpenGL ma układ współrzędnych taki, że oś y jest skierowana (względem monitora) a) w dół b) w górę c) w lewo d) w prawo e) w kierunku do

Badanie zależności położenia cząstki od czasu w ruchu wzdłuż osi Ox

RYSUNEK TECHNICZNY I GEOMETRIA WYKREŚLNA INSTRUKCJA DOM Z DRABINĄ I KOMINEM W 2D

Animacje cz. 2. Rysujemy koło zębate

Multimedia i interfejsy. Ćwiczenie 5 HTML5

Języki i techniki programowania Ćwiczenia 2

Podstawy technologii WWW

Tworzenie i modyfikacja modelu geologicznego

Animacje oraz ciekawe efekty dostępne w programie GIMP

Zajęcia nr 2 Programowanie strukturalne. dr inż. Łukasz Graczykowski mgr inż. Leszek Kosarzewski Wydział Fizyki Politechniki Warszawskiej

Funkcja Raytracer. Przed korzystaniem z funkcji Raytracer należy zmienić/dostosować jego ustawienia.

KONSTRUKCJA TRÓJKĄTA 1 KONSTRUKCJA TRÓJKĄTA 2 KONSTRUKCJA CZWOROKĄTA KONSTRUKCJA OKRĘGU KONSTRUKCJA STYCZNYCH

Transkrypt:

Piotr Siekański Wydział Mechatroniki PW Niektóre zaawansowane możliwości biblioteki Three.js Fotorealizm w animacji...2 Cube mapping...2 Skybox...3 Skybox w Three.js...3 Różne materiały dla jednej bryły...4 Sterowanie kamerą za pomocą myszy...6 Ładowanie modeli z Blendera do Three.js...7 Eksport modeli z Blendera do Three.js...7 Funkcje anonimowe w JavaScript...8 Import wyeksportowanych modeli w Three.js...8 Modelowanie powierzchni zwierciadlanych...9 Systemy cząsteczkowe...10 Podstawy systemów cząsteczkowych...10 Liczby losowe w JavaScript...13 Parametry cząsteczek zależne od odległości...14 Zadania...14 1

Fotorealizm w animacji We współczesnej grafice komputerowej duży nacisk kładzie się na uzyskanie tzw. fotorealizmu, czyli stworzenia za pomocą komputera obrazów, które będą dobrze imitować rzeczywiste obiekty. Jeżeli rendering nie musi być przeprowadzany w czasie rzeczywistym, często stosuje się technikę śledzenia promieni (ang. ray tracing), która wymaga bardzo wielu obliczeń i nie nadaje się do generowania animacji w czasie rzeczywistym. Istnieje jednak wiele technik wymagających mniejszej ilości obliczeń, które w konkretnych zastosowaniach dają efekty zbliżone do śledzenia promieni. Cube mapping Cube mapping jest jedną z technik tzw. mapowania środowiskowego (ang. environment mapping). Polega na stworzeniu wirtualnego sześcianu wielokrotnie większego od sceny, którą otacza. Na każdą z jego ścian nakładana jest wcześniej przygotowana tekstura, która odpowiada widokowi z kamery ustawionej prostopadle do ściany (patrz: Rysunek 1). Najczęściej poszczególne ściany w cube mappingu nazywa się zgodnie z następującą regułą: strona osi po której leży dana ściana i nazwa osi. Np. ściana leżąca po dodatniej stronie osi x będzie nazwana px (positive x), a leżąca po ujemnej stronie osi y ny (negative y). Rysunek 1: Cube mapping 2

Skybox Cube mapping jest szeroko stosowany w tworzeniu skyboxów. Skybox jest techniką, która pozwala niskim kosztem uzyskać wrażenie realistycznej sceny o znacznie większych wymiarach niż jest w rzeczywistości. Stosowanie skyboxów stwarza wrażenie dużej odległości obiektów tła, a w rezultacie wrażenie głębi. Skybox w Three.js Dołączony plik Podstawy threejs.html zawiera podstawowy kod HTML konieczny do rozpoczęcia pracy z biblioteką Three.js. oraz zdefiniowane podstawowe zmienne i funkcje. Działanie kodu jest wyjaśnione szczegółowo w pierwszej części instrukcji. Dodano jedynie polecenie lookat, które ustawia kamerę tak, aby patrzyła na obiekt będący argumentem. Jeżeli nie zaznaczono inaczej, wszystkie poniższe polecenia należy dodawać w funkcji init(), żeby zachować czytelność kodu. Skybox jest sześcianem, a więc najpierw należy zdefiniować geometrię sześcianu oraz materiał, z którego będzie wykonany: var skyboxgeometria = new THREE.CubeGeometry( 1000, 1000, 1000); var skyboxmaterial = new THREE.MeshLambertMaterial( { color: 0x00ff00, side: THREE.BackSide ); Warto zwrócić uwagę na parametr side pojawiający się w materiale. Odpowiada on za stronę, po której będzie renderowany materiał. Może przyjmować trzy wartości: THREE.FrontSide THREE.BackSide THREE.DoubleSide Jeśli parametr nie zostanie zdefiniowany, przyjmuje domyślnie wartość THREE.FrontSide, która renderuje materiał po stronie zewnętrznej bryły. W przypadku skyboxa, konieczna jest zmiana wartości tego parametru na THREE.BackSide, ponieważ materiał ma być widoczny wewnątrz sześcianu. Możliwy jest też rendering na obu powierzchniach bryły zewnętrznej i wewnętrznej, wtedy należy ustawić wartość THREE.DoubleSide. Po zdefiniowaniu materiału należy stworzyć bryłę i dodać ją do sceny. var skybox = new THREE.Mesh( skyboxgeometria, skyboxmaterial ); scena.add( skybox ); Materiał skyboxa jest typu lambertowskiego, a więc wymaga zdefiniowania oświetlenia i dodania go do sceny w określonym miejscu: var swiatlopunktowe = new THREE.PointLight( 0xffffff, 2, 1000 ); scena.add(swiatlopunktowe); swiatlopunktowe.position.set(100,100,100); 3

Po zapisaniu i uruchomieniu pliku w przeglądarce, powinno wyświetlić się wnętrze zielonego sześcianu (Rysunek 2). Rysunek 2: Zielony skybox Różne materiały dla jednej bryły Do tej pory każda bryła korzystała z jednego materiału. Skybox musi mieć ich sześć, ponieważ wymaga zastosowania sześciu różnych tekstur. Do tego celu konieczna jest tablica przechowująca każdy z materiałów: var tablicamaterialow = []; Następnie do tablicy muszą zostać dodane materiały, najprostszy sposób to użycie polecenia push, które dodaje jeden lub więcej elementów na koniec tablicy: THREE.MeshBasicMaterial( { color: 0xff0000, side: THREE.MeshBasicMaterial( { color: 0x00ff00, side: THREE.MeshBasicMaterial( { color: 0x0000ff, side: THREE.MeshBasicMaterial( { color: 0xffff00, side: THREE.MeshBasicMaterial( { color: 0xff00ff, side: THREE.MeshBasicMaterial( { color: 0x00ffff, side: Po wykonaniu powyższego fragmentu kodu do tablicy zostanie dodanych sześć materiałów typu basic różniących się kolorem. Kolejnym krokiem jest zmiana typu materiału skyboxa z: var skyboxmaterial = new THREE.MeshLambertMaterial( { color: 0x00ff00, side: THREE.BackSide ); na: var skyboxmaterial = new THREE.MeshFaceMaterial( tablicamaterialow ); 4

Materiał typu MeshFace przyjmuje jako parametr tablicę materiałów, której poszczególne materiały są dodawane do poszczególnych ścian bryły. Materiały w tablicy są typu basic, więc światło punktowe nie będzie już potrzebne i można usunąć fragment kodu odpowiedzialny za dodanie światła: //var swiatlopunktowe = new THREE.PointLight( 0xffffff, 2, 1000 ); //scena.add(swiatlopunktowe); //swiatlopunktowe.position.set(100,100,100); Po zapisaniu pliku i uruchomieniu go w przeglądarce powinien wyświetlić się kolorowy sześcian (Rysunek 3). Rysunek 3: Rózne materiały na każdej ze ścian skyboxa Ostatnim krokiem jest dodanie tekstur do każdej ze ścian. W tym celu należy zmienić fragment kodu odpowiadający za dodawanie materiałów do tablicy z THREE.MeshBasicMaterial( { color: 0xff0000, side: THREE.MeshBasicMaterial( { color: 0x00ff00, side: THREE.MeshBasicMaterial( { color: 0x0000ff, side: THREE.MeshBasicMaterial( { color: 0xffff00, side: THREE.MeshBasicMaterial( { color: 0xff00ff, side: THREE.MeshBasicMaterial( { color: 0x00ffff, side: na 5

THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'tekstury/px.jpg' ),side: THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'tekstury/nx.jpg' ),side: THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'tekstury/py.jpg' ),side: THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'tekstury/ny.jpg' ),side: THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'tekstury/pz.jpg' ),side: THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( 'tekstury/nz.jpg' ),side: Powyższy fragment kodu ładuje odpowiednie tekstury z dołączonego katalogu nazwanego tekstury i przypisuje je do każdego z materiałów. Nazwa pliku z teksturą odpowiada jej położeniu w skyboxie. Autorem tekstur użytych w przykładzie jest Emil Persson. Rysunek 4: Skybox z teksturami Sterowanie kamerą za pomocą myszy Skybox nie wygląda realnie, gdy obserwator nie znajduje się w jego środku. Należy poprawić pozycję kamery tak, by znajdowała się w środku skyboxa np. poleceniem: kamera.position.set(0,150,0); Tak ustawiona kamera dzięki poleceniu lookat, które jak już wspomniano ustawia kamerę tak, aby patrzyła na obiekt będący argumentem, jest ustawiona zgodnie z kierunkiem wektora kamera centrum sceny - punkt (0,0,0). Dlatego jest skierowana wzdłuż osi y, czyli patrzy na dolną ścianę 6

skyboxa. Kolejnym krokiem będzie implementacja sterowania kamerą za pomocą myszy. W tym celu należy dodać na początku dokumentu dodatek do biblioteki Three.js nazwany OrbitControls znajdujący się w katalogu js. W przypadku ściągnięcia całej biblioteki Three.js znajduje się on w: folder z biblioteką threejs > examples > js > controls > OrbitControls.js <script src="js/orbitcontrols.js"></script> Następnie należy zadeklarować nową zmienną globalną odpowiadającą za sterowanie kamerą: var kontrolakamery; i wewnątrz funkcji init() przypisać ją do kontroli kamery: kontrolakamery = new THREE.OrbitControls( kamera, renderer.domelement ); Parametry odpowiadają kolejno za element, który będzie poruszany za pomocą myszy oraz odwołanie do elementu, HTML wewnątrz którego będzie poruszać się obiekt. W tym przypadku jest nim renderer. Ostatnim krokiem jest dodanie w funkcji animate() polecenia uaktualniającego stan kontroli kamery: kontrolakamery.update(); Po zapisaniu pliku i uruchomieniu go w przeglądarce możliwe będzie sterowanie kamerą za pomocą myszy: lewy przycisk - obrót kamery, prawy przycisk - przesuwanie w płaszczyźnie równoległej, kółko myszy oddalanie/zbliżanie. Ładowanie modeli z Blendera do Three.js Eksport modeli z Blendera do Three.js Blender domyślnie nie wspiera formatu plików używanego przez Three.js, dlatego do biblioteki dołączony jest specjalnie napisany eksporter, który instaluje się jako dodatek do Blendera. Instalacja dodatku przebiega następująco: 1. Skopiowanie dołączonego katalogu io_mesh_threejs do katalogu scripts/addons Blendera. W przypadku ściągnięcia całej biblioteki Three.js znajduje się on w: folder z biblioteką threejs > utils > exporters > Blender. Pełna ścieżka instalacji zależy od używanego systemu operacyjnego: Windows: C:\Users\USERNAME\AppData\Roaming\Blender Foundation\Blender\2.6X\scripts\addons lub C:\Program Files\Blender Foundation\Blender\2.6X\scripts\addons OSX: zależna od katalogu, w którym zainstalowana jest aplikacja; w przypadku instalacji w katalogu Applications: /Applications/Blender/blender.app/Contents/MacOS/2.6X/scripts/addons Linux: /home/username/.config/blender/2.6x/scripts/addons lub /usr/lib/blender/scripts/addons 2. Aktywacja dodatku w Blenderze. W tym celu należy wybrać: File > User Preferences > Addons i w polu wyszukiwania wpisać three. Nastepnie należy zaznaczyć pole wyboru przy Import-Export: Three.js format. 7

3. Model stworzony przy użyciu Blendera można wyeksportować do formatu tekstowego przy pomocy File > Export > Three.js (js). Funkcje anonimowe w JavaScript Funkcja anonimowa rożni się od zwykłej funkcji tym, że nie ma nazwy. Jest deklarowana i natychmiast wywoływana w konkretnym miejscu w kodzie, później nie można się do niej odwołać. Przykład zastosowania funkcji anonimowej do ładowania modelu znajduje się w następnym akapicie. Funkcje anonimowe są często stosowane, ponieważ poprawiają czytelność kodu i przyspieszają jego wykonanie. Są stosowane w działaniach, które wykonują się tylko raz podczas działania skryptu, np. ładowanie modelu z pliku. Import wyeksportowanych modeli w Three.js Biblioteka Three.js posiada wbudowany loader, który umożliwia import modeli zapisanych w tekstowym formacie JSON. Najpierw należy zadeklarować zmienną globalną przechowującą referencję do wczytanego modelu na przykład: var malpa; Loader, przy ładowaniu pliku korzysta z funkcji anonimowej: var zrodlo = "monkey.js"; var loader = new THREE.JSONLoader(); loader.load( zrodlo, function(geometriamodelu){ var malpamaterial = new THREE.MeshBasicMaterial({color: 0x00ff00); malpa = new THREE.Mesh(geometriaModelu, malpamaterial); malpa.position.set(0,0,0); malpa.scale.set(10,10,10); scena.add(malpa); ); Najpierw deklarowana jest zmienna przechowująca ścieżkę do ładowanego pliku, następnie tworzona jest instancja loadera i wywoływana jest jego metoda load(). Przyjmuje ona dwa parametry, pierwszy to ścieżka do modelu, który należy wczytać, a drugi to funkcja anonimowa, która przyjmuje za parametr geometrię modelu wczytaną z pliku. Działanie kodu wewnątrz funkcji anonimowej jest oczywiste: najpierw tworzony jest materiał, później na jego podstawie i geometrii przekazanej przez parametr funkcji anonimowej tworzony jest nowy obiekt, który następnie jest dodawany do sceny. Warto podkreślić, że po wyjściu z funkcji anonimowej wszystkie zmienne użyte w jej wnętrzu staną się niedostępne, więc jeśli nie zostałaby utworzona zmienna globalna przechowująca odwołanie do modelu, model zostałby dodany do sceny i wyświetlany, ale nie można by się do niego w żaden sposób odwołać. Działanie loadera w threejs opiera się o mechanizm AJAX (ang. Asynchronous JavaScript and XML, asynchroniczny JavaScript i XML), który umożliwia asynchroniczne ładowanie poszczególnych elementów strony internetowej. Kod zawarty wewnątrz loadera wykonuje się niezależnie od pozostałej części skryptu, inaczej niż w przypadku klasycznego programowania strukturalnego, w którym kod jest wykonywany linia po linii, a wykonanie kolejnej linii zacznie się dopiero po zakończeniu wykonywania poprzedniej linii. Z tego powodu kod wykonywany asynchronicznie może być znacznie trudniejszy do debugowania. 8

Po zapisaniu pliku i uruchomieniu go w przeglądarce internetowej powinien wyświetlić się zielony model małpy wyeksportowanej z dołączonego pliku monkey.blend i wczytanego z pliku tekstowego JSON monkey.js. Modelowanie powierzchni zwierciadlanych Jak już wspomniano we wstępie do niniejszej instrukcji, raytracing jest zbyt kosztowną techniką, żeby stosować ją w animacjach, które muszą wykonywać się w czasie rzeczywistym. Powierzchnię zwierciadlaną można jednak uzyskać korzystając z wspomnianego już cube mappingu, umieszczając wirtualny sześcian na miejscu obiektu zwierciadlanego i wykonując rendering otoczenia na każdej z jego ścian (patrz Rysunek 1). Tak przygotowaną teksturę należy później nałożyć na obiekt. Biblioteka Three.js posiada gotowy obiekt kamery do cube mappingu. Należy zadeklarować nową zmienną globalną: var kameralustrzana; i w funkcji init() przypisać ją do nowej kamery i dodać ją do sceny: kameralustrzana = new THREE.CubeCamera( 0.1, 5000, 512 ); scena.add( kameralustrzana ); Parametry przyjmowane przez konstruktor to: near obiekty bliższe niż wartośc near nie będą renderowane far obiekty dalsze niż wartośc far nie będą renderowane cuberesolution rozdzielczość kamery; im mniejsza wartość tym mniej dokładne odwzorowanie otoczenia i wrażenie bardziej matowej powierzchni. Następnie należy utworzyć nowy materiał, który będzie zawierał teksturę będącą obrazem z kamery. Umożliwia to parametr envmap: var materiallustrzany = new THREE.MeshBasicMaterial( { envmap: kameralustrzana.rendertarget ); Aby przypisać ten materiał do modelu, należy wrócić do anonimowej funkcji ładującej model i zamienić: var malpamaterial = new THREE.MeshBasicMaterial({color: 0x00ff00); malpa = new THREE.Mesh(geometriaModelu,malpaMaterial); na: malpa = new THREE.Mesh(geometriaModelu,materialLustrzany); Zmienna malpamaterial nie będzie już potrzebna, ponieważ materiał dla obiektu został utworzony poza funkcją anonimową. Jak już wspomniano, w przypadku wykorzystania cube mappingu, konieczne jest aby kamera była ustawiona dokładnie tam, gdzie obiekt, dlatego należy wewnątrz funkcji anonimowej przypisać położeniu kamery realizującej cube mapping położenie obiektu: kameralustrzana.position = malpa.position; 9

Po zapisaniu pliku i uruchomieniu go w przeglądarce załadowany model będzie czarny, ponieważ w każdej klatce animacji należy renderować obraz z kamery realizującej odbicie lustrzane. W tym celu w funkcji render() należy dodać instrukcję uaktualniającą kamerę. Żeby zapobiec sytuacji, w której część obiektu zasłania kamerę powodując powstanie artefaktów na powierzchni obiektu, należy przed uaktualnieniem kamery ukryć obiekt, natomiast po uaktualnieniu, ponownie go pokazać, używając właściwości visible: malpa.visible=false; kameralustrzana.updatecubemap( renderer, scena ); malpa.visible=true; Żeby sprawdzić poprawność działania mapowania środowiskowego można w funkcji animate() dodać obrót modelu: malpa.rotation.x+=0.01; Po zapisaniu pliku i uruchomieniu go w przeglądarce powinien wyświetlić się obracający się model głowy małpy z odbiciem środowiska na powierzchni. Systemy cząsteczkowe Podstawy systemów cząsteczkowych Systemy cząsteczkowe są techniką pozwalającą stosunkowo niewielkim nakładem pracy symulować wiele zjawisk fizycznych, takich jak: ogień, dym, poruszająca się woda, śnieg, deszcz itp. System cząsteczkowy składa się z wielu bardzo prostych elementów, które są animowane niezależnie od siebie. Ze względu na fakt, że aby uzyskać dobry efekt, cząsteczek musi być bardzo dużo, stosuje się wiele metod optymalizacji renderingu. Jedną z nich jest, stosowana w bibliotece Three.js, rezygnacja z geometrii cząsteczki. Są one płaskie i zawsze zwrócone w stronę kamery. W omawianym przykładzie system cząsteczkowy zostanie użyty do tworzenia prostych fajerwerków. System cząsteczkowy tak, jak każdy element w bibliotece Three.js wymaga zdefiniowania geometrii i materiału. Należy zdefiniować dwie nowe zmienne nielokalne fajerwerk, odpowiadającą za wskaźnik do modelu oraz materialfajerwerku, odpowiadającą za przechowywanie materiału: var fajerwerk, materialfajerwerku; Zmienna przechowująca geometrię nie jest potrzebna, ponieważ w omawianym przykładzie, będzie ona tworzona dynamicznie. Następnie w funkcji init(), należy przypisać im wartości: materialfajerwerku = new THREE.ParticleSystemMaterial({ size: 8, map: THREE.ImageUtils.loadTexture( 'tekstury/gwiazdka.png' ), opacity: 1.0, transparent: true, depthtest: false ); fajerwerk = new THREE.ParticleSystem( new THREE.SphereGeometry(30,15,15), materialfajerwerku ); scena.add(fajerwerk); 10

Materiał Fajerwerku jest typu ParticleSystem, co oznacza, że reprezentuje on system cząsteczkowy. Zdefiniowane parametry odpowiadają kolejno za: size rozmiar cząsteczki (domyślnie 1). map tekstura, która będzie wyświetlana. W tym przypadku gwiazdka. Jeśli tekstura nie byłaby zdefiniowana wyświetlany jest kwadrat. Jest to rozwiązanie akceptowalne, jeżeli rozmiar cząsteczki jest mały. opacity stopień przezroczystości cząsteczki w skali 0-1, gdzie 1 oznacza całkowicie nieprzezroczystą. transparent zmienna logiczna, jeśli ma wartość true, umozliwia sterowanie stopniem przezroczystości. depthtest parametr określający, czy cząsteczki mają mieć sprawdzany test głębii. Wartość false przyspiesza rendering i zapobiega powstawaniu artefaktów na krawędzi cząsteczek. Następnie stworzony zostaje system cząsteczkowy na bazie geometrii sfery i wcześniej zdefiniowanego materiału. Cząsteczki pojawiają się w miejsce wierzchołków geometrii. Ostatnim krokiem jest dodanie gotowego systemu do sceny (Rysunek 5). Rysunek 5: Scena z dodanym systemem cząsteczkowym 11

Kolejnym krokiem będzie symulacja efektu wybuchu. Najprostszym wyjściem jest sterowanie skalą systemu, w tym celu utworzone zostaną dwie nowe zmienne globalne skala, odpowiadająca za aktualną skalę systemu oraz maxskala, która będzie zapobiegać rozrostowi fajerwerku w nieskończoność. var skala=1, maxskala=150; Następnie tak przygotowane zmienne należy wykorzystać do sterowania rozmiarem systemu cząsteczkowego. Żeby zwiększyć czytelność kodu, poza funkcą init() zdefiniowane zostaną dwie nowe funkcje resetfajerwerku() i animacjafajerwerku(). function resetfajerwerku(){ skala=1; function animacjafajerwerku(){ skala+=10; fajerwerk.scale.set(skala, skala, skala); if (skala>maxskala) { resetfajerwerku(); Działanie kodu obu funkcji jest oczywiste. Funkcja animacjafajerwerku() zwiększa skalę i na jej podstawie ustawia nową skalę Fajerwerku. Następnie sprawdza czy przekroczona została wartość graniczna, jeśli tak, to wywołana zostaje funkcja resetfajerwerku(), która na obecnym etapie tylko ustawia wartość zmiennej skala z powrotem na 1. Aby rozpocząć animację Fajerwerku należy w funkcji animate() dodać wywołanie funkcji animacjafajerwerku(): function animate() { requestanimationframe( animate ); animacjafajerwerku(); kontrolakamery.update(); render(); Ostatnim krokiem jest zmiana promienia sfery w geometrii Fajerwerku, ponieważ rozrasta się on zdecydowanie za szybko. Należy zamienić: fajerwerk = new THREE.ParticleSystem( new THREE.SphereGeometry(30,15,15), materialfajerwerku ); na: fajerwerk = new THREE.ParticleSystem( new THREE.SphereGeometry(1,15,15), materialfajerwerku ); Po zapisaniu pliku i uruchomieniu go w przeglądarce gwiazdy dookoła małpy powinny pulsować. 12

Liczby losowe w JavaScript Emisję fajerwerku można opisać w bardzo prosty sposób. Wymagane będą do tego dwie nowe zmienne globalne prędkosc odpowiadająca za prędkość lotu fajerwerku i kierunekfajerwerku będąca jego kierunkiem ruchu: var kierunekfajerwerku, szybkosc=10; Następnie, aby tor ruchu każdego z fajerwerków był inny, należy zainicjalizować wektor kierunekfajerwerku trzema losowymi wartościami dzięki poleceniu Math.random(), które zwraca losową liczbę z przedziału (0-1): kierunekfajerwerku = new THREE.Vector3(-1+Math.random()*2, 0.8+Math.random()*0.2, 1+Math.random()*2) Zakres zmienności składowych wektora jest równy odpowiednio dla osi x i z: (-1,1), a dla osi y (0.81). Dzięki tak dobranym parametrom, fajerwerki będą zawsze leciały w kierunku górnej części skyboxa. Następnie należy uaktualnić funkcję animacjafajerwerku() do postaci: function animacjafajerwerku() { if (fajerwerk.position.y <500){ fajerwerk.position.x+=kierunekfajerwerku.x*szybkosc; fajerwerk.position.y+=kierunekfajerwerku.y*szybkosc; fajerwerk.position.z+=kierunekfajerwerku.z*szybkosc; else { skala+=10; fajerwerk.scale.set(skala, skala, skala); if (skala>maxskala) { resetfajerwerku(); Po zapisaniu pliku i uruchomieniu go w przeglądarce internetowej fajerwerk zostanie wystrzelony raz, a później będzie pulsował w górnej części skyboxa. Żeby stworzyć wyrzutnię fajerwerków, należy uaktualnić funkcję resetfajerwerku() do postaci: function resetfajerwerku(){ scena.remove(fajerwerk); fajerwerk = new THREE.ParticleSystem( new THREE.SphereGeometry(1,15,15), materialfajerwerku ); fajerwerk.position.set(0,0,0); scena.add(fajerwerk); skala=1; fajerwerk.scale.set(skala, skala, skala); kierunekfajerwerku = new THREE.Vector3(-1+Math.random()*2, 0.8+Math.random()*0.2, -1+Math.random()*2); 13

Najpierw ze sceny usuwany jest fajerwerk, żeby nie dopuścić do wycieku pamięci przy tworzeniu kolejnych fajerwerków, później na jego miejsce tworzony jest nowy i ustalana jest jego pozycja i skala początkowa, a następnie losowany jest nowy kierunek ruchu. Każdy z fajerwerków może wybuchać w trochę inny sposób. W tym celu można dodać małe składowe losowe do współrzędnych każdej cząsteczki. Do funkcji animacjafajerwerku(), w części odpowiadającej za zachowanie cząsteczek po wybuchu, należy dopisać pętlę iterującą po wszystkich cząsteczkach i dodającą bardzo małe losowe wartości do pozycji każdej z nich: for( var i=0; i<fajerwerk.geometry.vertices.length; i++) { fajerwerk.geometry.vertices[i].x +=(-0.01+Math.random()*0.02); fajerwerk.geometry.vertices[i].y +=(-0.01+Math.random()*0.02); fajerwerk.geometry.vertices[i].z +=(-0.01+Math.random()*0.02); fajerwerk.geometry.verticesneedupdate = true; Działanie powyższej pętli jest proste. W każdej klatce animacji do współrzędnych pozycji każdej cząsteczki dodawane są losowe wartości z przedziału (-0.01-0.01), powodując lekkie zaburzenia geometrii po wybuchu. Aby efekt tych zniekształceń był widoczny należy ustawić zmienną sygnalizującą konieczność uaktualnienia wierzchołków geometrii, co jest realizowane poleceniem: fajerwerk.geometry.verticesneedupdate = true; Parametry cząsteczek zależne od odległości Obecnie cząsteczki po wybuchu oddalają się od centrum wybuchu i po przekroczeniu maksymalnej wartości skali gwałtownie znikają. Dodana zostanie przezroczystość cząsteczek zależna od skali, a przez to od czasu i od odległości od miejsca wybuchu, a także w podobny sposób zmienny kolor. W funkcji animacjafajerwerku() należy dodać aktualizację przezroczystości i koloru na przykład: fajerwerk.material.color.r fajerwerk.material.color.g fajerwerk.material.color.b fajerwerk.material.opacity = = = = 1; 1-(skala/maxSkala); 1; 1-(skala/maxSkala); Dzięki temu w miarę oddalania się cząsteczek od miejsca wybuchu zwiększać się będzie przezroczystość i zmniejszać składowa koloru zielonego, co skutkować będzie fioletowym kolorem wybuchu. Ostatnim krokiem jest aktualizacja funkcji resetfajerwerku(), w której należy dopisać instrukcję odpowiadającą za ustawianie początkowej wartości przezroczystości: fajerwerk.material.opacity = 1; Po zapisaniu pliku i uruchomieniu go w przeglądarce powinien uruchomić się pokaz fioletowych fajerwerków. 14

Zadania 1. Znaleźć w Internecie i wczytać inną teksturę dla skyboxa. 2. Dodać sterowanie połyskiem materiału za pomocą suwaka. Rozdzielczość kamery powinna być zawsze potęgą liczby 2. 3. Wyeksportować dowolny model z Blendera i wczytać go z wykorzystaniem techniki prezentowanej w instrukcji. 4. Zmienić materiał modelu tak, aby zamodelować kolorowe szkło używane do produkcji bombek choinkowych materiał odbijający otoczenie, wrażliwy na światło i posiadający określony kolor (Rysunek 6). 5. Za pomocą systemów cząsteczkowych dodać kilka fajerwerków wystrzeliwanych jeden po drugim. Rysunek 6: Materiał z zadania 4. 15