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:

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.

Ein Würfel als erstes 3D-Objekt

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.

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.

3D-Koordinatensystem mit x-, y- und z-Achse

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:

Perspektivische Kamera mit Ebenen

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.