Was ist Three.js?

0 Aktien
0
0
0
0

Einführung

Three.js bietet viele Funktionen und seine Verbindung zu anderen 3D-Bereichen kann mitunter verwirrend sein. Da sich sein Anwendungsbereich ständig weiterentwickelt, ist eine Zusammenfassung schwierig, und diese Beobachtungen sind subjektiv.

JavaScript 3D-Bibliothek

Ziel dieses Projekts ist die Entwicklung einer schlanken, benutzerfreundlichen 3D-Bibliothek. Diese Bibliothek bietet Renderings. , , CSS3D und WebGL.

Dies ist die offizielle Beschreibung aus dem GitHub-Repository. Sie fasst es eigentlich ganz gut zusammen, aber jedes Thema in diesem Satz ist für sich genommen ein sehr umfangreiches Thema, und three.js bietet noch viel mehr.

Die Bibliothek selbst ist in JavaScript geschrieben und für die Verwendung in einer JavaScript-Umgebung vorgesehen. In den meisten Fällen bedeutet dies, dass sie clientseitig – in einem Webbrowser auf einem Gerät – ausgeführt wird. Mit Node.js und Headless-Browsern kann sie aber auch serverseitig eingesetzt werden. Man denkt zunächst an Rendering – vielleicht an die Anzeige von Vorschaubildern auf dem Server, es könnte sich aber auch einfach um eine 3D-Berechnung handeln, da three.js über eine umfangreiche Mathematikbibliothek verfügt. Der Begriff 3D ist sehr weit gefasst. Er kann vieles bedeuten. Meistens denken wir dabei an “Grafik”.

Die meisten three.js-Projekte, die wir sehen, beinhalten 3D-Grafiken in Echtzeit, bei denen die Interaktion des Nutzers zu unmittelbarem visuellem Feedback führt. Andere Arten von 3D-Grafiken sind entweder verschiedene Effekte oder künstliche Charaktere in Filmen oder verschiedene «Renderings», die man in Printmedien oder in Online-Katalogen sieht (beispielsweise ist die Website von IKEA voller 3D-Grafiken, da alle Produktfotos computergeneriert sind).

Ein Teilbereich davon ist die 3D-Mathematik. 3D-Grafiken sind ohne Mathematik nicht möglich, und Programmiersprachen verstehen 3D-Konzepte nicht standardmäßig. Hier kommt eine Bibliothek ins Spiel, die diese mathematischen Operationen abstrahiert, sie gegebenenfalls optimiert und eine High-Level-Schnittstelle wie Matrix4 oder .dot() bereitstellt.

Three.js verfügt über eine eigene Mathematikbibliothek mit Klassen speziell für 3D-Mathematik. Es gibt zwar eigenständige Bibliotheken, die sich ausschließlich mit dieser Mathematik befassen, aber bei Three ist sie nur ein Teilbereich eines viel größeren Systems.

Das Rendern ist eine weitere wichtige Aufgabe der Bibliothek, aber auch hier gestaltet sich die Sache etwas komplizierter. WebGL ist sehr speziell und hebt sich deutlich von anderen Bibliotheken ab.

Bei Canvas, SVG und CSS liegt die Verantwortung für das 3D-Rendering vollständig bei den Entwicklern. Diese APIs verfügen zwar über zahlreiche Bibliotheken zum Zeichnen nicht-dreidimensionaler Objekte oder führen diese sogar standardmäßig aus (CSS zeichnet 2D-Rechtecke, Canvas verschiedene 2D-Formen), aber für das eigentliche 3D-Rendering sind spezielle Kenntnisse und mathematisches Verständnis erforderlich.

Der Clou liegt vor allem in der Abstraktion der Benutzeroberfläche. Zum Beispiel in der Verwaltung des 3D-Zustands eines Elements. <div> Die Umwandlung in 3D über CSS ist sehr schwierig. Es erfordert viel Logik, um die Canvas-API dazu zu bringen, etwas zu zeichnen, das wie 3D aussieht. WebGL ist wesentlich komplexer.

Three abstrahiert all diese APIs zu etwas so Einfachem wie render(), aber dazu benötigt es eine generische Repräsentation dessen, was die "3D-Welt" ist.

Szenendiagramm

Man kann einen Bereich in three.js identifizieren, der als allgemeine Abstraktion der «3D-Welt» dient. Ein Szenengraph ist eine Datenstruktur, die beschreibt, wie Objekte in einer 3D-Szene (Welt) zueinander in Beziehung stehen. Er muss nicht zwingend dreidimensional sein, da er eine praktische Möglichkeit bietet, jede Vektorgrafikhierarchie zu beschreiben. Genauer gesagt handelt es sich um einen Baum, der von Knoten mit einem Wurzelknoten ausgeht. In three.js ist die Basisklasse für diese Datenstruktur `Object3D`.

Dies entspricht nahezu exakt dem DOM-Baum. THREE.Scene ist ähnlich. <body> Alles andere ist ein Zweig. Im DOM können wir Elemente platzieren, aber unsere Möglichkeiten sind relativ begrenzt. Rotationen erfolgen üblicherweise um eine Achse, und wir bewegen Elemente nach links/rechts oder oben/unten. In einem 3D-Szenengraphen haben wir deutlich mehr Freiheitsgrade.

Szene drei ähnelt eher einem virtuellen DOM. Wir führen unsere Operationen durch und setzen den Zustand in diesem Baum. Wenn wir eine visuelle Momentaufnahme dieses Zustands benötigen (z. B. in einer Endlosschleife oder bei einer Benutzerinteraktion/Zustandsänderung), rufen wir `render(scene)` auf. Bei einer Änderung soll nicht der gesamte DOM-Baum aktualisiert werden, sondern nur das Element. Wir müssen die gesamte Ansicht löschen und dann alles neu zeichnen, selbst wenn sich nur ein einziges Element an seiner Position ändert.

Eins <div> In einem <div> Ähnlich der Eltern-Kind-Beziehung THREE.Mesh(&#039;sun&#039;)-&gt;THREE.Mesh(&#039;earth&#039;) könnte eine CSS-Regel vergleichbar mit einem THREE.Material sein, bei dem eine Beschreibung wie color:&#039;red den Effekt auslöst und ein Objekt rot färbt. Schließlich könnte der Aufruf von threeRenderer.render(scene) dem Laden einer HTML-Seite mit CSS-Regeln durch den Browser entsprechen.

Mesh, Scene, Camera und Light sind allesamt Unterklassen dieser generischen Klasse. Dadurch können Sie der “Szene” ein “Objekt” oder der “Kamera” ein “Licht” hinzufügen.

Eine einfache Struktur kann sehr flach sein. Der Wurzelknoten kann als “Welt” betrachtet werden und kann “Boden”, “Haus”, “Sonne” und “Kamera” als seine Kinder haben.

THREE.Scene('world')
|-THREE.Mesh('ground')
|-THREE.Mesh('house')
|-THREE.Light('sun')
|-THREE.Camera('main')

Diese Informationen reichen aus, um einen Renderer mit einem visuellen Ergebnis zu versorgen. In manchen Szenen gibt es zwei Raster, die unterschiedliche Dinge darstellen: den Boden und das Haus auf dem Hügel. Eine Lichtquelle definiert die Beleuchtungsart (Morgenlicht, Mittagslicht, Blitzlicht), und ein Objekt (die Kamera) bestimmt unseren Blickwinkel, unsere Sicht auf die Welt.

Die Ergebnisse können variieren, beispielsweise ist CSS auf eine sehr einfache Darstellung beschränkt, während WebGL Schatten und generell eine hohe Wiedergabetreue bieten kann.

Mithilfe dieser Struktur wird die 3D-Welt verwaltet. Um zu simulieren, wie sich Tageslicht in verschiedenen Jahreszeiten auf ein Haus auswirkt, ändern wir programmatisch Position und Richtung des Lichts. Der Szenengraph stellt diesen “Positions”-Hook bereit, aber für die eigentliche Animation ist eigene Logik erforderlich. Eine einfache Möglichkeit zur Animation einer 3D-Szene bietet three.js mit einer “Tweening”-Bibliothek.

All das trifft vermutlich nur theoretisch zu, und die Szenendarstellung lässt sich möglicherweise nicht beliebig ändern. Dies liegt jedoch hauptsächlich an der Überlappung der “Materialien” mit dem Szenengraphen und deren Kopplung an die Renderings. Beispielsweise ist es nicht möglich, eine Szene zu schattieren. <div> Oder es erscheint nicht als Metall, was ein WebGL-Material beschreiben kann, aber es kann rot gemacht werden, was alle Materialien können.

Im Kern ist Object3D immer noch generisch, und die räumliche und hierarchische Beziehung der Knoten zueinander wird durch einen “Szenengraphen” beschrieben.

In einfachen Worten: Dies ist die Szenenvariable, die Sie erhalten, nachdem Sie scene.add(my_foo) mehrmals aufgerufen haben.

WebGL

WebGL ist extrem spezifisch und wird wahrscheinlich in etwa 99 % aller bestehenden three.js-Anwendungen verwendet. Es ist ein umfangreiches Thema, daher wäre es sinnvoll, zunächst einen kurzen Überblick über die Alternativen zu geben.

Canvas, CSS, SVG

Das sind alles APIs. Es handelt sich dabei um eine Schnittstelle, mit der Sie als Programmierer dem Browser mitteilen können, wie er bestimmte Dinge darstellen soll. CSS ist die gebräuchlichste Schnittstelle im Web, denn ohne sie sieht alles wie reiner Text aus. Ursprünglich hatte CSS nichts mit 3D zu tun.

Canvas verwendet zwar dasselbe WebGL-Element zum Zeichnen, hat aber einen anderen Kontext. Dieser Kontext heißt eigentlich “2D”, aber da 3D ohnehin nur eine Illusion ist und wir immer eine Art 2D-Oberfläche zeichnen, ob real oder virtuell, können wir diesen Kontext auch zum Zeichnen von 3D-Grafiken verwenden.

SVG ist eine weitere Nicht-3D-API, die typischerweise zur Beschreibung von Logos oder Symbolen verwendet wird. Da sie jedoch grundlegende Elemente wie Linien darstellen kann, lässt sie sich auch in einem 3D-Kontext verwenden (z. B. als Overlay auf einer Karte oder als räumlich orientierte UI- oder HUD-Elemente).

Gemeinsames Merkmal ist, dass keines dieser Konzepte für die 3D-Darstellung gedacht ist. Ein weiteres wichtiges Merkmal ist ihr abstrakter Charakter – sie waren ursprünglich für andere Zwecke konzipiert. Beispielsweise können alle drei einen Kreis zeichnen. Bei Canvas ist dies eine explizite Form, bei CSS muss man eventuell abgerundete Ecken verwenden, aber das Endergebnis ist ein sehr direkter Zugriff auf einen Kreis.

WebGL ist sehr hardwarenah und hat wenig Erfahrung mit 3D-Grafik. 3D-Grafik erfordert spezifische mathematische Berechnungen, und zwar sehr viele. Denken Sie nur einmal an einen hochauflösenden Bildschirm und die Anzahl seiner Pixel. Wenn für jedes Pixel berechnet werden muss, wie eine bestimmte Lichtmenge die Oberfläche beeinflusst, und das 60 Mal pro Sekunde, summiert sich das zu einer beträchtlichen Anzahl an Berechnungen.

Grafikprozessor

Die meisten Computer, wie Laptops, Desktop-PCs, Mobiltelefone und sogar Smartwatches, verfügen über eine Hardwareeinheit, die 3D-Operationen effizient berechnen und interaktive Grafiken darstellen kann. Diese Einheit wird Grafikprozessor (GPU) genannt.

Er unterscheidet sich vom Hauptprozessor, weil er für andere Zwecke gebaut wurde – für spezifische mathematische Operationen, die parallel ausgeführt werden.

So wie wir JavaScript für die Browserprogrammierung verwenden, verwenden wir WebGL für die Grafikkartenprogrammierung.

Das stimmt zwar im Prinzip, aber in der Praxis sind es zwei völlig unterschiedliche Dinge. WebGL besteht sowohl aus JavaScript-Code (den Anweisungen) als auch aus einer komplett anderen Sprache, die die eigentlichen Berechnungen durchführt (GLSL). Man kann durchaus Parallelen zwischen HTML und JavaScript und deren Zusammenspiel auf einer Webseite ziehen.

Zweidimensional und dreidimensional

Nicht nur 3D-Anwendungen profitieren von dieser Hardwarebeschleunigung. Auch die Videoverarbeitung eignet sich dafür. Sie können die Grafikkarte so programmieren, dass sie Farben oder das Bild in einem Live-Videostream ändert.

WebGL ist eine sehr hardwarenahe Technologie und daher generisch. Es kennt weder 2D- noch 3D-Grafik, aber es kennt Speicher, Puffer, Befehlswarteschlangen, Shader usw.

Parallele Programmierung unterscheidet sich von der Programmierung in JavaScript. Ein häufiges Problem ist der Zugriff verschiedener Threads auf eine gemeinsam genutzte Variable.

Dieses andere Paradigma bedeutet, dass es eine völlig andere Sprache namens GLSL gibt. Es handelt sich um eine Shading-Sprache, die in nahezu jeder Low-Level-Grafik-API enthalten ist. Hier wird die eigentliche Logik für diese komplexen Berechnungen implementiert, und der einzige Vorteil besteht darin, dass kein Maschinencode geschrieben werden muss.

Der andere Teil der WebGL-API sind die JavaScript-Bindings, über die man der GPU Anweisungen gibt. Ein Shader weist an, “Berechnungen A durchzuführen”, und ein Binding führt diese eine Million Mal aus.

Es obliegt dem Programmierer, zu berechnen, was A ist. Es könnte etwas mit 3D zu tun haben oder ein Kernel sein, der das Video unscharf macht.

Wenn man anfängt, diese Berechnungen und diese Befehle zu abstrahieren, erhält man three.js.

Renderings, die zusammenarbeiten

Ein besonders sinnvoller Anwendungsfall ist die Kombination verschiedener Renderer, um Objekte in 3D darzustellen. WebGL kann zwar komplexe Berechnungen durchführen und sehr realistische Bilder erzeugen, ist aber bei der Darstellung von Text und Linien weniger effektiv. Eine zusätzliche Ebene für gerenderten Text lässt sich mit CSS und Canvas-Renderern realisieren, während Pfade und Linien mithilfe von SVG dargestellt werden können.

THREE.WebGLRenderer

Diese gesamte Low-Level-Logik wird durch eine WebGLRenderer-Klasse in three.js abstrahiert. Dadurch wird der Würfel in eine Reihe von Zahlen im GPU-Speicher umgewandelt.

Ironischerweise ist es der einzige three.js-Renderer, der keine 3D-Grafik benötigt, aber dennoch die beste Option dafür. Die anderen Renderer simulieren 3D mithilfe von 2D-APIs, während WebGL 3D bewusst mit einer generischen parallelen Rechen-API realisiert. Das schließt jedoch nicht aus, dass man ihn ausschließlich zur Verarbeitung eines Live-Videostreams verwenden könnte. Er abstrahiert ausreichend von WebGL, um dafür nützlich zu sein, allerdings nutzt man wahrscheinlich nur ein Drittel der Bibliothek. Man könnte beispielsweise eine extrem reaktionsschnelle Benutzeroberfläche mit WebGL entwickeln oder ein Jump-’n’-Run-Spiel im Stil von Super Mario, für das three.js weiterhin ein hervorragendes Werkzeug wäre.

Die Tatsache, dass Sie nur ein Drittel der Bibliothek verwenden, bedeutet, dass ein anderes Tool für diesen Zweck besser geeignet sein könnte, oder dass Sie einfach eine Teilmenge von three.js erstellen könnten. Sowohl das Super-Mario- als auch das Videoverarbeitungsbeispiel benötigen möglicherweise nur PlaneGeometry und eventuell einen Materialtyp.

drei Mathematik

JavaScript-Code, der bestimmte mathematische Operationen in 3D durchführt. JavaScript verfügt standardmäßig über `Math.pow()`, jedoch nicht über `Quaternion.inverse()`. Mit diesen Klassen können wir Algorithmen schreiben, die kein Rendering benötigen – beispielsweise ein Spielserver, der überprüft, wer auf wen schießt, indem er viele Strahlen aussendet, ohne etwas zu zeichnen.

drei Szenengraph

Eine Familie von Object3D-Unterklassen bildet eine Baumdatenstruktur, die eine “3D-Welt” und die Beziehungen der Objekte darin beschreibt. Sie ist konzeptionell abstrakt, lässt sich aber durch spezifische Rendering-Methoden visualisieren, sobald man sich mit dem Code auseinandersetzt.

drei Renderings

Die Schicht, die diesen generischen Graphen in eine visuelle Darstellung auf dem Bildschirm oder in einem Puffer übersetzt (z. B. wird er serverseitig erstellt). Sie verwendet verschiedene Technologien, um dieses Ziel zu erreichen.

THREE-WebGLRenderer

Ein spezieller Renderer, der Hardwarebeschleunigung ermöglicht und viele 3D-Konzepte beherrscht, aber auch für 2D (und sogar allgemeine Berechnungen) verwendet werden kann. Meiner Meinung nach sind dies die Hauptbausteine von three.js. Ich verwende meist den Begriff “3D” anstelle von “Grafik”, aber das gilt nur für den WebGLRenderer.

Three.js ist keine Spiele-Engine.

Nicht jeder, der 3D-Grafiken im Web benötigt, entwickelt Spiele. Game-Engines optimieren typischerweise weit mehr als nur die Beschreibung und Darstellung von 3D-Welten. Unterschiedliche Spiele haben unterschiedliche Anforderungen, und die Physik- und Rendering-Systeme für Echtzeitstrategie- und Ego-Shooter unterscheiden sich wahrscheinlich stark. All das bedeutet mehr Code, und für jemanden, der lediglich ein 3D-Modell für einen Produktkatalog erstellen möchte, ist das nicht nur unnötig, sondern auch unerwünscht. Natürlich könnte man eine eigene Game-Engine entwickeln und drei Module für das Rendering und die Erstellung von Engine-Blöcken verwenden.

Three.js lädt nicht viel.

Der Core verfügt zwar über mehrere Loader für bestimmte Assets, aber alle gängigen Formate wie glTF oder FBX sind unabhängig. Three.js ist es egal, wie die Assets stammen, solange sie korrekt geparst und zu einem 3D-Objekt verarbeitet werden. Für Three.js gibt es keinen Unterschied zwischen einem Mesh aus einer glTF-Datei und einer prozedural generierten Kugel. Viele kreative Beispiele verwenden Würfel und Kugeln und laden außer Three.js selbst nichts. Die Core-Loader sind sehr generisch und laden Bilder und Dateien. Sie repräsentieren Three.js-Objekte wie Materialien oder Texturen direkt. Formatspezifische Loader basieren auf diesen Bausteinen.

 

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Das könnte Ihnen auch gefallen