Erste Schritte mit Three.js

Paul Lewis

Einführung

Ich habe Three.js für einige meiner Experimente verwendet. Es löst die Probleme, die beim Einstieg in die 3D-Technologie im Browser auftreten können. Mit Cinema4D können Sie unter anderem Kameras, Objekte, Lichter und Materialien erstellen. Außerdem haben Sie die Möglichkeit, den Renderer auszuwählen, mit dem die Szene gerendert werden soll. Sie können also festlegen, ob die Szene mit dem Canvas von HTML 5, WebGL oder SVG gerendert werden soll. Und da es Open Source ist, können Sie sich sogar am Projekt beteiligen. Aber jetzt konzentriere ich mich darauf, was ich durch das Experimentieren mit der Engine gelernt habe, und zeige Ihnen einige der Grundlagen.

Three.js ist zwar ein tolles Tool, aber manchmal kann es zu Problemen kommen. Normalerweise müssen Sie viel Zeit mit den Beispielen verbringen, Reverse-Engineering betreiben und (in meinem Fall auf jeden Fall) nach bestimmten Funktionen suchen und gelegentlich Fragen über GitHub stellen. Wenn du Fragen hast, sind Mr. doob und AlteredQualia sehr hilfreich.

1. Grundlagen

Ich gehe davon aus, dass Sie zumindest grundlegende Kenntnisse in 3D und eine angemessene Beherrschung von JavaScript haben. Falls nicht, sollten Sie sich etwas mit dem Thema vertraut machen, bevor Sie damit herumspielen, da es etwas verwirrend sein kann.

In unserer 3D-Welt werden wir einige der folgenden Elemente haben, deren Erstellung ich Ihnen zeigen werde:

  1. Eine Szene
  2. Renderer
  3. Kamera
  4. Ein oder zwei Objekte (mit Materialien)

Sie können natürlich einige coole Dinge damit machen. Ich hoffe, dass Sie das tun und mit 3D in Ihrem Browser experimentieren.

2. Support

Nur ein kurzer Hinweis zur Unterstützung in den Browsern. Der Chrome-Browser von Google ist meiner Erfahrung nach der beste Browser, was die unterstützten Renderer und die Geschwindigkeit der zugrunde liegenden JavaScript-Engine angeht. Chrome unterstützt Canvas, WebGL und SVG und ist blitzschnell. Firefox liegt mit Version 4 auf dem zweiten Platz. Die JavaScript-Engine von Edge ist zwar etwas langsamer als die von Chrome, aber auch hier ist die Unterstützung für die Rendering-Technologien großartig. Opera und Safari arbeiten daran, WebGL-Unterstützung hinzuzufügen, aber ihre aktuellen Versionen unterstützen nur Canvas. Der Internet Explorer (Version 9 und höher) unterstützt nur Canvas-Rendering. Ich habe nichts davon gehört, dass Microsoft WebGL-Funktionen hinzufügen möchte.

3. Den Rahmen schaffen

Ich gehe davon aus, dass Sie einen Browser ausgewählt haben, der alle Rendering-Technologien unterstützt, und dass Sie mit Canvas oder WebGL rendern möchten, da dies die gängigeren Optionen sind. Canvas wird zwar breiter unterstützt als WebGL, aber WebGL wird auf der GPU Ihrer Grafikkarte ausgeführt. Das bedeutet, dass sich Ihre CPU auf andere Aufgaben konzentrieren kann, die nicht mit dem Rendering zusammenhängen, z. B. auf Physik oder Nutzerinteraktionen.

Unabhängig vom ausgewählten Renderer muss das JavaScript für die Leistung optimiert werden. 3D ist keine leichte Aufgabe für einen Browser (und es ist großartig, dass es überhaupt möglich ist). Achten Sie also darauf, wo sich Engpässe in Ihrem Code befinden, und entfernen Sie sie nach Möglichkeit.

Angenommen, Sie haben three.js heruntergeladen und in Ihre HTML-Datei eingefügt. Wie richten Sie dann eine Szene ein? Ein Beispiel:

// 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);

Es ist gar nicht so schwierig.

4. Mesh erstellen

Wir haben also eine Szene, eine Kamera und einen Renderer (in meinem Beispielcode habe ich mich für einen WebGL-Renderer entschieden), aber nichts, was wir zeichnen könnten. Three.js unterstützt das Laden verschiedener Standarddateitypen. Das ist praktisch, wenn Sie Modelle aus Blender, Maya, Cinema4D oder anderen Programmen ausgeben. Der Einfachheit halber (es geht ja darum, loszulegen) Ich werde über Primitive sprechen. Primitive sind geometrische Netze, relativ einfache wie Kugeln, Ebenen, Würfel und Zylinder. Mit Three.js können Sie diese Arten von Primitiven ganz einfach erstellen:

// 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);

Alles klar, aber was ist mit dem Material für die Kugel? Im Code haben wir die Variable sphereMaterial verwendet, sie aber noch nicht definiert. Zuerst müssen wir uns eingehender mit den Materialien befassen.

5. Material

Dies ist ohne Zweifel einer der nützlichsten Teile von Three.js. Es bietet eine Reihe gängiger (und sehr praktischer) Materialien, die Sie auf Ihre Meshes anwenden können:

  1. „Basic“ – bedeutet, dass das Objekt ohne Beleuchtung gerendert wird
  2. Lambert
  3. Phong

Es gibt noch mehr, aber aus Gründen der Einfachheit möchte ich Sie bitten, diese selbst zu entdecken. Bei WebGL können diese Materialien besonders hilfreich sein. Warum? Weil Sie in WebGL Shader für alles schreiben müssen, was gerendert wird. Shader sind ein großes Thema für sich, aber kurz gesagt: Sie werden in GLSL (OpenGL Shader Language) geschrieben, was der GPU mitteilt, wie etwas aussehen soll. Das bedeutet, dass Sie die Mathematik von Beleuchtung, Reflexion usw. nachahmen müssen. Das kann sehr schnell sehr kompliziert werden. Mit Three.js müssen Sie das nicht tun, wenn Sie es nicht möchten, da diese Funktion für Sie abstrahiert wird. Wenn Sie jedoch Shader schreiben möchten, ist das auch mit einem MeshShaderMaterial möglich. Die Einrichtung ist also flexibel.

Fürs Erste wenden wir jedoch ein Lambert-Material auf die Kugel an:

// create the sphere's material
var sphereMaterial = new THREE.MeshLambertMaterial(
{
// a gorgeous red.
color: 0xCC0000
});

Außerdem gibt es neben der Farbe noch andere Eigenschaften, die Sie beim Erstellen eines Materials angeben können, z. B. weichzeichnende oder Umgebungskarten. Auf der Wiki-Seite finden Sie Informationen zu den verschiedenen Eigenschaften, die Sie für die Materialien und für alle Objekte festlegen können, die die Engine zur Verfügung stellt. Außerdem gibt es seit Kurzem threejs.org, eine ansprechendere Ansicht der API.

6. Lichter!

Wenn Sie die Szene jetzt rendern würden, würde ein roter Kreis angezeigt. Obwohl wir ein Lambert-Material angewendet haben, gibt es kein Licht in der Szene. Daher wechselt Three.js standardmäßig zu einem vollen Umgebungslicht, was der gleichen Wirkung wie eine flache Färbung entspricht. Beheben wir das mit einem einfachen Lichtpunkt:

// 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. Rendern

Wir haben jetzt alles für das Rendern eingerichtet. Aber wir müssen genau das tun:

// draw!
renderer.render(scene, camera);

Sie werden die Animation aber wahrscheinlich mehrmals rendern wollen. Wenn Sie also eine Schleife verwenden, sollten Sie requestAnimationFrame verwenden. Das ist bei weitem die intelligenteste Methode, Animationen im Browser zu verarbeiten. Es wird noch nicht vollständig unterstützt. Ich empfehle Ihnen daher, sich den Shim von Paul Irish anzusehen.

8. Gemeinsame Objekteigenschaften

Wenn Sie sich den Code für Three.js ansehen, werden Sie feststellen, dass viele Objekte von Object3D „erben“. Dies ist ein Basisobjekt mit einigen sehr nützlichen Eigenschaften wie Position, Drehung und Maßstab. Insbesondere ist unsere Kugel ein Mesh, das von Object3D abgeleitet wird und dem eigene Properties hinzugefügt werden: Geometrie und Materialien. Warum erwähne ich diese? Es ist unwahrscheinlich, dass Sie nur eine Kugel auf dem Bildschirm haben möchten, die nichts tut. Diese Eigenschaften sind es wert, untersucht zu werden, da Sie damit die zugrunde liegenden Details der Meshes und Materialien im laufenden Betrieb bearbeiten können.

// 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

Ich möchte nur kurz auf eine kleine Falle bei Three.js hinweisen: Wenn Sie beispielsweise die Eckpunkte eines Meshes ändern, sehen Sie in Ihrem Render-Loop, dass sich nichts ändert. Warum? Das liegt daran, dass Three.js (soweit ich das beurteilen kann) die Daten für ein Mesh als Art Optimierung im Cache speichert. Sie müssen Three.js lediglich mitteilen, dass sich etwas geändert hat, damit es alles neu berechnen kann. Dazu haben Sie folgende Möglichkeiten:

// changes to the vertices
sphere.geometry.__dirtyVertices = true;

// changes to the normals
sphere.geometry.__dirtyNormals = true;

Es gibt noch mehr, aber diese beiden sind meiner Meinung nach am nützlichsten. Sie sollten natürlich nur die Änderungen markieren, um unnötige Berechnungen zu vermeiden.

Fazit

Ich hoffe, dass Ihnen diese kurze Einführung in Three.js weitergeholfen hat. Es gibt nichts Besseres, als selbst Hand anzulegen und etwas auszuprobieren. Ich kann es nur wärmstens empfehlen. Native 3D-Inhalte im Browser sind sehr unterhaltsam. Mit einer Engine wie Three.js können Sie sich viel Kopfzerbrechen ersparen und wirklich coole Dinge erstellen. Zur Veranschaulichung habe ich den Quellcode in diesem Lab-Artikel zusammengefasst, damit Sie ihn als Referenz verwenden können. Wenn dir das gefallen hat, lass es mich auf Twitter wissen.