Getting Started - three js

three.js ist eine Bibliothek zum Erstellen von 3D-Grafik-basierten Programmen mit Javascript/Typescript. Die Bibliothek bietet einen großen Funktionsumfang und ist mit gängigen Technologien aus der Computergrafik kompatibel, z. B. OpenGL, GLTF, etc.

Step 0: Node.js installieren

Um ein Projekt zu initialisieren, ist zunächst die Installation von Node.js nötig.
Node.JS kann über den folgenden Link installiert werden: https://nodejs.org/en

Die erfolgte Installation kann über den folgenden Befehl im Terminal getestet werden:

node -v

Step 1: NPM Projekt initialisieren

Um three.js zu nutzen, kann man NPM als Package Manager nutzen.
Erstelle dazu einen neuen Ordner für dein Projekt, navigiere per Terminal in diesen Ordner und führe den folgenden Befehl aus. Der Setup-Assistent von NPM wird dann einige Rückfragen stellen und das Projekt initialisieren.

npm init

Anschließend existiert eine neue Datei package.jsonim Projektordner, die Informationen zum Projekt und zu den genutzten Paketen enthält.

Step 2: three.js installieren

three.js lässt sich einfach über NPM im Projekt installieren. Führe dazu den folgenden Befehl im Terminal in deinem Projektordner aus.

npm install --save three

Step 3: Buildtool installieren

Um die Entwicklung und den Build von unserem Projekt zu erleichtern, nutzen wir ein Buildtool, z. B. vite. Vite wird nur für die Entwicklung genutzt und ist nicht Teil des fertigen Produkts. Mit der Nutzung eines Buildtools wird die Nutzung von imports auf npm Pakete und lokale Javascript-Dateien wesentlich erleichtert.
Führe zur Installation von vite den folgenden Befehl im Terminal in deinem Projektordner aus.

npm install --save-dev vite

Step 4: Dateien anlegen

Jedes three.js-Projekt besteht aus mindestens zwei Dateien: main.jsund index.html. Die main.js-Datei enthält dabei den Javascript-Code inkl. three.js-Funktionen und die index.html-Datei enthält den HTML-Code zum Laden des Javascript-Codes und zum Anzeigen der Seite.
Die folgenden Dateien können als Vorlage einfach in deinen Projektordner kopiert werden:

main.js

import * as THREE from 'three';

index.html

<!DOCTYPE html> 
<html lang="en"> 
	<head> 
		<meta charset="utf-8"> 
		<title>My first three.js app</title> 
		<style> 
			body { margin: 0; } 
		</style> 
	</head> 
	<body> 
		<script type="module" src="/main.js"></script> 
	</body> 
</html>

Zusätzlich kann noch ein Ordner publicangelegt werden, die Dateien (z. B. Resourcen) enthält, die ohne Veränderung direkt vom Webserver ausgeliefert werden.

Step 5: Projekt lokal ausführen

Um das Projekt lokal zu starten, kann der folgende Befehl im Terminal genutzt werden:

npx vite

Im Terminal erscheint danach ein Hinweis auf die URL, die für die lokale Entwicklung bereitgestellt wird, standardmäßig localhost:5173.

Zusätzlich kann der Befehl auch in der package.json als start-Befehl hinterlegt werden, sodass das Projekt dann auch über npm start gestartet werden kann. Dazu muss die folgende Zeile in der package.json hinterlegt werden:

...
"scripts": {
...
  "start": "npx vite",
},
...

Step 6: Erste Schritte in three.js

Um etwas in three.js zu rendern, sind drei grundlegende Dinge nötig: Scene, Cameraund Renderer.

import * as THREE from 'three'; 

const scene = new THREE.Scene(); 
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); 
const renderer = new THREE.WebGLRenderer(); 

renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement );

Step 7: Würfel rendern

Um einzelne Elemente in three.js zu rendern werden meist Geometries genutzt. Für einen Würfel nutzen wir die BoxGeometry.

Box Geometry:
Zunächst erstellen wir die BoxGeometry mit der entsprechenden Größe und ordnen anschließend ein Oberflächenmaterial zu. MeshBasicMaterial ist dabei eine einfache, einfarbige Oberfläche. Alternativ könnte man hier dann auch Texturen verwenden.

const geometry = new THREE.BoxGeometry( 2, 1, 3 ); 
const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); 
const cube = new THREE.Mesh( geometry, material ); 
scene.add( cube ); 
camera.position.z = 7;

Render Loop:
Damit der Würfel nun tatsächlich auch auf der Seite zu sehen ist, muss man nun noch ein Render Loopbenutzen, dass den Renderer auffordert, die Inhalte auch tatsächlich zu rendern.

function animate() { 
	requestAnimationFrame( animate ); 
	renderer.render( scene, camera ); 
} 

animate();

Step 8: Würfel animieren

Füge dazu diesen Code in deiner animate()-Methode ein:

cube.rotation.x += 0.05; 
cube.rotation.y += 0.05;

Step 9: AxesHelper

three.js bietet einen AxesHelper, um sich die einzelnen Achsen der Szene anzeigen zu lassen.
Dieser lässt sich über zwei Zeilen ähnlich zu anderen Objekten einfach in die Szene einfügen.
Dies hilft beim Debugging und bei der Erstellung der Szene.

const axesHelper = new THREE.AxesHelper( 5 ); 
scene.add( axesHelper );

Step 10: Maus-Steuerung

Das Event mousemove kann in JavaScript genutzt werden, um die Mausbewegung als Event zu verarbeiten und darauf zu reagieren. Damit lässt sich z. B. die Rotation per Mousebewegung steuern:

window.addEventListener('mousemove', e => mouseMove(e))

function mouseMove(e) {
	cube.rotation.x = e.clientY / 100
	cube.rotation.y = e.clientX / 100
}

Auch die Verarbeitung von click-Events ist möglich, um z. B. die Farbe bei jedem Mausklick zu ändern:

window.addEventListener('click', e => mouseClick(e))

function mouseClick(e) {
	cube.material.color.setHex(Math.random() * 0xffffff)
}

Step 11: Kamerasteuerung

Eine weitere Form der Interaktivität ist die Steuerung der Kameraposition. Dies kann man z. B. über Tastatureingaben (Pfeiltasten, wsad, ...) umsetzen.
Dazu wird wieder die Event-Listener-Struktur von JavaScript genutzt, um die Tastatureingaben abzufangen und entsprechend zu verarbeiten.

window.addEventListener("keydown", (e) => keyDown(e));

function keyDown(e) {
	switch (e.key) {
		case "w":
			camera.position.y += 0.2;
			break;
		case "s":
			camera.position.y -= 0.2;
			break;
		case "a":
			camera.position.x -= 0.2;
			break;
		case "d":
			camera.position.x += 0.2;
			break;
		case "q":
			camera.position.z += 0.2;
			break;
		case "e":
			camera.position.z -= 0.2;
			break;
	}
}

Step 12: Texturen

Texturen können als normale Bilddateien abgelegt werden. Dazu bietet es sich an, die Texturen im Ordner texturesund dann in entsprechende Unterordner mit sprechenden Namen, in diesem Fall z. B. cubeabzulegen.

Anschließend kann man die Texturen in three.js über den TextureLoader laden und im Material über den Parameter map setzen.

const texture = new THREE.TextureLoader().load( "textures/cube/aa.jpg" );
const material = new THREE.MeshBasicMaterial({ color: 0xffff00, map: texture});

Komplettes Code-Beispiel

Hier findest du das vollständige Code-Beispiel zum Kopieren:

Wie geht es jetzt weiter?

Weitere Formen
Weitere Informationen zu three.js findest du in der three.js-Doku.
Dort findest du auch andere Geometry-Objekte, wie z. B. die Capsule oder die Sphere. Auf jeder der Doku-Seiten ist eine kurze Beschreibung und eine animierte Vorschau des Objekts zu finden.

Texte
Texte kannst du am einfachsten über die Kombination HTML+CSS in dein Projekt einbinden.
Erstelle dazu einfach ein divmit dem Text in HTML und style es entsprechend über CSS, damit es über deinen three.js-Elementen liegt. Dazu kannst du den z-index in CSS nutzen.
Alternativ gäbe es auch die Möglichkeit in three.js eine TextGeometry zu nutzen.

Interaktivität
Verschiedene Events können entweder über spezielle Libraries oder einfach über window.addEventListener('click', e => methode(e)) direkt in JavaScript. In der zugeordneten Methode im EventListener können dann die Parameter für das Rendering entsprechend angepasst werden. Ein gutes Tutorial zur Nutzung von EventListenern in JavaScript findet ihr hier: Link (w3schools.com)

Impressum