Wprowadzenie
W przypadku niektórych eksperymentów użyłem Three.js, który świetnie radzi sobie z problemami związanymi z tworzeniem grafiki 3D w przeglądarce. Za jego pomocą możesz tworzyć kamery, obiekty, światła, materiały i inne elementy. Możesz też wybrać mechanizm renderowania, czyli zdecydować, czy chcesz, aby scena była wyświetlana za pomocą płótna HTML 5, WebGL lub SVG. A ponieważ jest to oprogramowanie open source, możesz nawet wziąć udział w projekcie. Teraz jednak skupię się na tym, czego dowiedziałem się, gdy używałem go jako silnika, i przedstawię Ci kilka podstaw.
Pomimo wszystkich zalet biblioteki Three.js mogą pojawić się sytuacje, w których będziesz mieć z nią problemy. Zazwyczaj trzeba poświęcić sporo czasu na przykłady, inżynierię wsteczną i (w moim przypadku) wyszukiwanie konkretnych funkcji oraz od czasu do czasu zadawanie pytań na GitHubie. Jeśli masz pytania, Mr. doob i AlteredQualia mogą być bardzo pomocne.
1. Podstawy
Zakładam, że masz przynajmniej podstawową wiedzę na temat grafiki 3D i umiejętność obsługi JavaScriptu. Jeśli nie, warto się trochę dowiedzieć, zanim zaczniesz korzystać z tych funkcji, ponieważ mogą one być nieco mylące.
W naszym świecie 3D znajdziemy m.in. te elementy, które omówię w trakcie tworzenia:
- scena
- mechanizm renderowania,
- Aparat
- 1–2 obiekty (z materiałami)
Możesz oczywiście zrobić kilka fajnych rzeczy. Mam nadzieję, że zaczniesz eksperymentować z 3D w przeglądarce.
2. Pomoc
Krótka uwaga na temat obsługi w przeglądarkach. Z moich doświadczeń wynika, że przeglądarka Google Chrome jest najlepsza pod względem obsługiwanych procesorów oraz szybkości silnika JavaScript. Chrome obsługuje Canvas, WebGL i SVG, a także działa błyskawicznie. Firefox zajmuje drugie miejsce, głównie dzięki wprowadzeniu wersji 4. Silnik JavaScript wydaje się być nieco wolniejszy niż w Chrome, ale znowu obsługa technologii renderowania jest świetna. Opera i Safari są w trakcie dodawania obsługi WebGL, ale ich obecne wersje obsługują tylko canvas. Internet Explorer (wersja 9 i nowsza) obsługuje tylko renderowanie na płótnie. Nie słyszałem, aby Microsoft planował dodać obsługę WebGL.
3. Wstęp
Zakładam, że używasz przeglądarki obsługującej wszystkie technologie renderowania i chcesz renderować za pomocą Canvas lub WebGL, ponieważ są to standardowe opcje. Canvas jest obsługiwany na większej liczbie urządzeń niż WebGL, ale warto pamiętać, że WebGL działa na procesorze graficznym karty graficznej, co oznacza, że procesor CPU może się skoncentrować na innych zadaniach niezwiązanych z renderowaniem, takich jak symulacja fizyki czy interakcja z użytkownikiem.
Niezależnie od wybranego modułu renderowania pamiętaj, że kod JavaScript musi być zoptymalizowany pod kątem wydajności. Grafika 3D to niełatwe zadanie dla przeglądarki (i to, że jest to w ogóle możliwe, jest niesamowite), więc dokładnie sprawdź, gdzie w kodu znajdują się wąskie gardła, i jeśli to możliwe, je usuń.
Zakładając, że pobierasz i dodajesz do pliku HTML plik three.js, jak konfigurujesz scenę? W ten sposób:
// set the scene size
var WIDTH = 400,
HEIGHT = 300;
// set some camera attributes
var VIEW_ANGLE = 45,
ASPECT = WIDTH / HEIGHT,
NEAR = 0.1,
FAR = 10000;
// get the DOM element to attach to
// - assume we've got jQuery to hand
var $container = $('#container');
// create a WebGL renderer, camera
// and a scene
var renderer = new THREE.WebGLRenderer();
var camera = new THREE.PerspectiveCamera(
VIEW_ANGLE,
ASPECT,
NEAR,
FAR );
var scene = new THREE.Scene();
// the camera starts at 0,0,0 so pull it back
camera.position.z = 300;
// start the renderer
renderer.setSize(WIDTH, HEIGHT);
// attach the render-supplied DOM element
$container.append(renderer.domElement);
To naprawdę nie jest trudne.
4. Tworzenie siatki
Mamy więc scenę, kamerę i render (w tym przykładzie wybrałem renderowanie WebGL), ale nie mamy nic do narysowania. Three.js obsługuje wczytywanie kilku różnych standardowych typów plików, co jest bardzo przydatne, jeśli generujesz modele z Blendera, Mayi, Cinema4D lub innego programu. Aby zachować prostotę (w końcu chodzi o to, aby zacząć od czegoś prostego), Porozmawiamy o prostych obiektach. Pierwiastki to siatki geometryczne, stosunkowo proste, takie jak kule, płaszczyzny, sześciany i walca. Three.js umożliwia łatwe tworzenie tych typów prymitywów:
// set up the sphere vars
var radius = 50, segments = 16, rings = 16;
// create a new mesh with sphere geometry -
// we will cover the sphereMaterial next!
var sphere = new THREE.Mesh(
new THREE.SphereGeometry(radius,
segments,
rings),
sphereMaterial);
// add the sphere to the scene
scene.add(sphere);
Wszystko w porządku, ale co z materiałem na kulę? W kodzie użyliśmy zmiennej sphereMaterial, ale nie zdefiniowaliśmy jej jeszcze. Najpierw musimy porozmawiać o materiałach.
5. Materiały
Bez wątpienia jest to jedna z najbardziej przydatnych części Three.js. Udostępnia ona kilka typowych (i bardzo przydatnych) materiałów, które możesz zastosować do swoich siatek:
- „Podstawowy” – co oznacza, że renderowanie jest „nieskompresowane”.
- Lambert
- Phong
Jest ich więcej, ale ze względu na prostotę pozwolę Ci odkryć je samodzielnie. W przypadku WebGL te materiały mogą być szczególnie przydatne. Dlaczego? Ponieważ w WebGL musisz pisać shadery dla wszystkich renderowanych obiektów. Cienie są ogromnym tematem sam w sobie, ale w skrócie są one napisane w języku GLSL (OpenGL Shader Language), który mówi GPU, jak coś powinno wyglądać. Oznacza to, że musisz symulować matematykę oświetlenia, odbicia itp. Może to bardzo szybko stać się bardzo skomplikowane. Dzięki Three.js nie musisz tego robić, jeśli nie chcesz, ponieważ abstrahuje ono od tego za Ciebie. Jeśli jednak chcesz pisać shadery, możesz to zrobić za pomocą materiału MeshShaderMaterial, więc jest to elastyczne rozwiązanie.
Na razie jednak zastosujmy do kuli materiał Lamberta:
// create the sphere's material
var sphereMaterial = new THREE.MeshLambertMaterial(
{
// a gorgeous red.
color: 0xCC0000
});
Warto też pamiętać, że podczas tworzenia materiału możesz określić inne właściwości niż kolor, np. wyrównanie czy mapy środowiska. Sprawdź stronę Wiki, aby poznać różne właściwości, które możesz ustawić w materiałach, a także w dowolnym obiekcie udostępnianym przez silnik. Niedawno pojawiła się też strona threejs.org, która zapewnia bardziej atrakcyjny widok interfejsu API.
6. Światła!
Gdybyś teraz wyrenderował scenę, zobaczyłbyś czerwony okrąg. Chociaż zastosowaliśmy materiał Lamberta, w scenie nie ma światła, więc domyślnie Three.js wróci do pełnego światła rozproszonego, które jest takie samo jak kolorowanie płaskie. Naprawimy to za pomocą prostego punktu świetlnego:
// create a point light
var pointLight = new THREE.PointLight( 0xFFFFFF );
// set its position
pointLight.position.x = 10;
pointLight.position.y = 50;
pointLight.position.z = 130;
// add to the scene
scene.add(pointLight);
7. Renderuj
Wszystko jest już skonfigurowane do renderowania. Ale musimy to zrobić:
// draw!
renderer.render(scene, camera);
Prawdopodobnie będziesz musiał renderować więcej niż raz, więc jeśli chcesz użyć pętli, powinieneś użyć metody requestAnimationFrame. Jest to zdecydowanie najlepsza metoda obsługi animacji w przeglądarce. Nie jest jeszcze w pełni obsługiwany, dlatego zdecydowanie zalecam zapoznanie się z przeróbką Paul Irisha.
8. Właściwości wspólne obiektów
Jeśli poświęcisz trochę czasu na przejrzenie kodu Three.js, zauważysz, że wiele obiektów „dziedziczy” z Object3D. Jest to obiekt podstawowy, który zawiera przydatne właściwości, takie jak informacje o pozycji, rotacji i skali. W szczególności sfera jest siatką, która dziedziczy po obiekcie 3D swoje właściwości: geometrię i materiały. Dlaczego o tym wspominam? Niewiele jest sensu w tym, aby na ekranie wyświetlała się kula, która nic nie robi. Warto jednak przyjrzeć się tym właściwościom, ponieważ umożliwiają one dowolną manipulację szczegółami siatek i materiałów.
// sphere geometry
sphere.geometry
// which contains the vertices and faces
sphere.geometry.vertices // an array
sphere.geometry.faces // also an array
// its position
sphere.position // has x, y and z properties
sphere.rotation // same
sphere.scale // ... same
9. Dirty Little Secrets
Chcę tylko szybko zwrócić uwagę na pewną kwestię dotyczącą Three.js: jeśli zmodyfikujesz np. wierzchołki siatki, zauważysz, że w pętli renderowania nic się nie zmienia. Dlaczego? Ponieważ Three.js (o ile mi wiadomo) przechowuje dane siatki w pamięci podręcznej w celu optymalizacji. Musisz tylko poinformować Three.js, że coś się zmieniło, aby mogła ponownie obliczyć wszystko, co jest potrzebne. Aby to zrobić:
// changes to the vertices
sphere.geometry.__dirtyVertices = true;
// changes to the normals
sphere.geometry.__dirtyNormals = true;
I znowu jest ich więcej, ale te 2 są najbardziej przydatne. Oczywiście należy oznaczać tylko te elementy, które uległy zmianie, aby uniknąć niepotrzebnych obliczeń.
Podsumowanie
Mam nadzieję, że ten krótki wstęp do Three.js okazał się przydatny. Nie ma nic lepszego niż brudne ręce i próbowanie czegoś nowego. Obsługa 3D w natywną w przeglądarce jest bardzo fajna, a korzystanie z silnika takiego jak Three.js eliminuje wiele problemów i umożliwia tworzenie naprawdę fajnych rzeczy. Aby Ci pomóc, zamieszczam kod źródłowy w tym artykule z laboratorium. Możesz go wykorzystać jako materiał referencyjny. Jeśli podobał Ci się ten artykuł, daj nam znać na Twitter.