11 Dreidimensionale Grafiken und Animationen mit Three.js
Die Bibliothek Three.js dient zur Darstellung von dreidimensionalen Grafiken und Animationen.
Bei Three.js handelt es sich um eine JavaScript-Bibliothek, mit deren Hilfe dreidimensionale Grafiken (3D-Grafiken) ohne zusätzliche Programme in einem Browser dargestellt werden können. Diese 3D-Grafiken können auch Animationen beinhalten. Three.js basiert auf der WebGL (= Web Graphics Library), einer Programmierschnittstelle für Grafiken, die Bestandteil von vielen aktuellen Browsern ist.
Bei der Erzeugung einer Grafik mit Three.js kommen folgende Programmbestandteile zum Einsatz:
-
eine Zeichnungsfläche im HTML-Dokument, in der eine Grafikszene dargestellt wird,
-
eine Grafikszene, in der 3D-Objekte angeordnet werden,
-
ein oder mehrere 3D-Objekte,
-
eine Kamera, durch die wir auf die Grafikszene schauen, und
-
eine Lichtquelle zur Beleuchtung der 3D-Objekte.
Zurzeit (im März 2018) gibt es Three.js in der Revision 90. Die Datei three.min.js mit der gesamten Bibliothek hat eine Größe von ca. 517 KB. Sie finden sie zusammen mit den Beispieldateien im Downloadpaket zum Buch. In den folgenden Beispielen wird auf diese Datei zugegriffen. Sie befindet sich im selben Verzeichnis wie die Beispieldateien.
Etwaige aktuellere Versionen finden Sie über http://www.threejs.org. Über den Link Download laden Sie dort die Datei three.js-master.zip mit einer Größe von ca. 226 MB herunter. Im Unterverzeichnis build finden Sie die Datei three.min.js.
In diesem Kapitel werden nur einige der umfangreichen Möglichkeiten von Three.js gezeigt.
11.1 Eine erste 3D-Grafik
Anhand der Darstellung eines Würfels werden die einzelnen Elemente einer 3D-Grafik verdeutlicht, siehe Abbildung 11.1.
Abbildung 11.1 Ein Würfel als erstes 3D-Objekt
Falls wir mit der Kamera genau von vorne auf den Würfel schauen würden, wäre nur die Vorderfläche sichtbar. Daher schauen wir mit der Kamera von rechts oben auf den Würfel. Die Lichtquelle befindet sich an einem Punkt in der Nähe der Kamera, ebenfalls rechts oberhalb des Würfels. Auf diese Weise sind drei Flächen des Würfels in unterschiedlicher Ausleuchtung sichtbar.
11.1.1 Das 3D-Koordinatensystem
Zum Verständnis des Aufbaus der 3D-Grafik müssen wir uns zunächst mit dem Aufbau eines 3D-Koordinatensystems beschäftigen. Darin kann jeder Punkt im 3D-Raum mithilfe seiner x-Koordinate, seiner y-Koordinate und seiner z-Koordinate eindeutig bezeichnet werden.
Die Koordinaten x=0, y=0 und z=0 bezeichnen das Zentrum des Systems. Dieser Punkt befindet sich standardmäßig in der Mitte des Bildschirms.
-
Rechts der Mitte ist der Wert der x-Koordinate positiv, links der Mitte negativ. Die x-Achse unseres Systems verläuft von links nach rechts in der Bildschirmebene.
-
Oberhalb der Mitte ist der Wert der y-Koordinate positiv, unterhalb der Mitte negativ. Die y-Achse unseres Systems verläuft von unten nach oben in der Bildschirmebene.
-
Die z-Achse unseres Systems verläuft senkrecht durch die Bildschirmebene, von einem Punkt hinter dem Bildschirm auf uns als Betrachter zu. Vor dem Bildschirm ist der Wert der z-Koordinate positiv, hinter dem Bildschirm negativ.
In Abbildung 11.2 sehen Sie das 3D-Koordinatensystem mit den drei Achsen. Zur Verdeutlichung des 3D-Raums in der zweidimensionalen Ebene (2D-Ebene) des Buchs wird eine perspektivische Darstellung gewählt. Aus demselben Grund wird in meinen Beispielen eine perspektivische Kamera für die Darstellung der 3D-Grafiken in der 2D-Ebene des Bildschirms verwendet. Bei der perspektivischen Darstellung erscheinen Objekte, die entlang der z-Achse weiter hinten liegen, für den Betrachter kleiner, so wie man es aus der Realität gewohnt ist.
Abbildung 11.2 3D-Koordinatensystem mit x-, y- und z-Achse
11.1.2 Der Aufbau des Programms
Es folgt der Code des Programms, in dem die Objekte der Bibliothek Three.js genutzt werden. Diese Objekte im Programmcode nenne ich vereinfacht ThreeJS-Objekte, im Unterschied zu den 3D-Objekten, die auf dem Bildschirm zu sehen sind. Der Aufbau meiner 3D-Grafiken ist immer ähnlich, so dass die umfangreiche Erläuterung dieses ersten Programms auch hilfreich für die weiteren Programme dieses Kapitels ist.
<!DOCTYPE html><html><head><meta charset="utf-8">
<title>Erste 3D-Grafik</title>
<script src="three.min.js"></script>
</head>
<body>
<script>
/* Zeichnungsfläche */
var zeichnung = new THREE.WebGLRenderer();
zeichnung.setSize(window.innerWidth*0.9, window.innerHeight*0.9);
zeichnung.setClearColor(0xcccccc);
document.body.appendChild(zeichnung.domElement);
/* 3D-Szene */
var szene = new THREE.Scene();
/* 3D-Objekt */
var geometrie = new THREE.BoxGeometry(200, 200, 200);
var material = new THREE.MeshLambertMaterial( {color:0xff4040} );
var objekt = new THREE.Mesh(geometrie, material);
szene.add(objekt);
/* Kamera */
var kamera = new THREE.PerspectiveCamera(45,
window.innerWidth/window.innerHeight, 1, 100000);
kamera.position.set(300, 300, 500);
kamera.lookAt(objekt.position);
/* Licht */
var licht = new THREE.PointLight();
licht.position.set(300, 150, 200);
szene.add(licht);
/* Zeichnen */
zeichnung.render(szene, kamera);
</script>
</body></html>
Listing 11.1 Datei »th_grafik.htm«
11.1.3 Die Zeichnungsfläche und die Grafikszene
Als Erstes wird die Bibliothek in der Datei three.min.js eingebunden. Das ThreeJS-Objekt des Typs WebGLRenderer stellt eine Zeichnungsfläche zur Darstellung der Grafikszene bereit, den Canvas. Mithilfe der Methode setSize() wird die Größe des Canvas eingestellt. Ich nutze dafür jeweils 90% der Breite und der Höhe des Browserfensters, mithilfe der Werte der Eigenschaften innerWidth und innerHeight des window-Objekts. Die Methode setClearColor() bestimmt mithilfe einer hexadezimalen Ziffernfolge die RGB-Anteile der Hintergrundfarbe. Die Standardhintergrundfarbe ist Schwarz. Die Eigenschaft domElement liefert den Canvas. Der Canvas wird dem Dokument hinzugefügt.
Das ThreeJS-Objekt des Typs Scene stellt die Grafikszene bereit, in der die 3D-Objekte angeordnet werden.
11.1.4 Das 3D-Objekt mit Geometrie und Material
Ein 3D-Objekt besitzt eine Form, die Geometrie. Die Geometrie eines 3D-Objekts wird aus vielen einzelnen Dreiecksflächen aufgebaut. Die Bibliothek Three.js stellt eine Reihe von vorgefertigten, häufig genutzten Geometrien zur Verfügung, u. a. die einer Kugel, eines Quaders oder eines Kegels. Diese fertigen Geometrien ersparen viel Aufbauarbeit.
Ein Quader wird mithilfe eines ThreeJS-Objekts des Typs BoxGeometry erzeugt. Der Konstruktor erwartet mindestens drei Parameter, zur Angabe der Breite (in x-Richtung), der Höhe (in y-Richtung) und der Tiefe (in z-Richtung) des Quaders. Wählen wir drei gleiche Werte, dann erhalten wir den Sonderfall eines Würfels.
Ein 3D-Objekt besitzt ein Oberflächenmaterial. Die verschiedenen Materialien reagieren unterschiedlich auf bestimmte Lichttypen. Ein ThreeJS-Objekt des Typs MeshLambertMaterial hat eine matte Oberfläche und vermittelt mit der richtigen Lichtquelle einen anschaulichen räumlichen Eindruck. Die Eigenschaft color dient zur Einstellung der RGB-Anteile der Farbe der Oberfläche.
Mithilfe eines ThreeJS-Objekts des Typs Mesh wird das 3D-Objekt in der gewünschten Geometrie und mit dem gewünschten Oberflächenmaterial erzeugt. Es wird keine bestimmte Position für das Objekt angegeben. Daher befindet es sich am Nullpunkt des Koordinatensystems.
Die Methode add() fügt das 3D-Objekt zur Grafikszene hinzu. Erst dann kann es dargestellt werden.
11.1.5 Die Kamera
Es gibt verschiedene Kameratypen. Ein ThreeJS-Objekt des Typs PerspectiveCamera stellt eine Kamera bereit, die uns einen perspektivischen Blick auf die Grafikszene ermöglicht. Diese Kamera steht auf der Spitze einer Pyramide, die eine rechteckige Grundfläche besitzt. In Abbildung 11.3 wird die Kamera durch einen dicken Punkt auf der rechten Seite verdeutlicht. Die Kamera schaut durch die Pyramide hindurch bis zur Grundfläche, die hier auf der linken Seite liegt. Alles was außerhalb der Pyramide liegt, ist in der Grafikszene nicht zu sehen. Der Konstruktor benötigt die folgenden vier Parameter:
-
fov (= field of view): Das ist der Sichtwinkel in Grad. Eine natürliche Perspektive wird bei 45 Grad erreicht.
-
aspect (= aspect ratio): Das ist das Seitenverhältnis, also das Verhältnis der Breite zur Höhe der Grundfläche der rechteckigen Pyramide. Es empfiehlt sich, das Seitenverhältnis des Browserfensters zu nehmen.
-
near (= near plane): Das ist die »nahe Ebene«, ein (in Abbildung 11.3 gestrichelter) Querschnitt durch die Pyramide. Alles, was vor dieser Ebene liegt, ist in der Grafikszene nicht zu sehen.
-
far (= far plane): Das ist die »ferne Ebene«. Gleichzeitig ist das die (in Abbildung 11.3 gepunktete) Grundfläche der Pyramide. Alles, was hinter dieser Ebene liegt, ist in der Grafikszene ebenfalls nicht zu sehen.
Abbildung 11.3 Perspektivische Kamera mit Ebenen
Mithilfe eines ThreeJS-Objekts des Typs position haben Sie Zugriff auf die Eigenschaft der Position eines ThreeJS-Objekts. Sie können die Koordinaten mithilfe der Eigenschaften x, y oder z des position-Objekts einzeln abrufen oder einstellen. Die Methode set() dient zur Einstellung aller drei Koordinaten. Die hier gewählten Werte x=300, y=300 und z=500 positionieren die Kamera rechts oben vorne, bezogen auf den Nullpunkt des Koordinatensystems.
Im Standardfall ist die Blickrichtung der Kamera genau geradeaus. Mithilfe der Methode lookAt() wird die Blickrichtung geändert, damit die Kamera zum Nullpunkt schaut.
11.1.6 Die Lichtquelle und die Darstellung
Es gibt verschiedene Typen von Lichtquellen. Ein ThreeJS-Objekt des Typs PointLight stellt eine punktförmige helle Lichtquelle bereit, die gleichmäßig in alle Richtungen strahlt, ähnlich wie eine Glühbirne. Die Standardlichtfarbe ist Weiß. Die Lichtquelle wird in der Nähe der Kamera positioniert, also ebenfalls rechts oben vorne. Falls Sie die Lichtquelle von der Kamera aus hinter dem 3D-Objekt positionieren würden, wären die sichtbaren Flächen des Würfels schwarz.
Die Methode add() fügt das Licht zur Grafikszene hinzu. Erst dann hat es eine Auswirkung.
Als Letztes wird die Grafikszene gemeinsam mit der Kamera mithilfe der Methode render() innerhalb der Zeichnungsfläche gerendert, d. h. gezeichnet bzw. dargestellt.