WebGL mit Three.js Modelle und Animation

3D-Grafiken im Browser sind seit ihrer Einführung ein heißes Thema. Aber wenn Sie Ihre Apps mit einfachem alten WebGL erstellen würden, würde dies ewig dauern. Deshalb sind einige wirklich nützliche Bibliotheken entstanden. Three.js ist eine der beliebtesten, und ich werde Ihnen in dieser Serie zeigen, wie Sie sie am besten nutzen können, um beeindruckende 3D-Erlebnisse für Ihre Benutzer zu schaffen.

Ich erwarte, dass Sie ein grundlegendes Verständnis des 3D-Raums haben, bevor Sie mit dem Lesen dieses Tutorials beginnen, da ich keine Themen wie Koordinaten und Vektoren erläutern werde.


Vorbereitung

Wie üblich beginnen wir mit dem Code, den Sie zuvor erstellt haben. Laden Sie die von mir bereitgestellten Assets herunter und packen Sie sie aus, und Sie können loslegen.


Schritt 1: Ein Wort zum Exportieren von Modellen in Blender

Bevor wir mit dem Programmieren beginnen, werde ich etwas erklären, mit dem viele Leute Probleme haben. Wenn Sie ein Modell in Blender erstellt haben und es in das Three.js-Format exportieren möchten, sollten Sie Folgendes beachten:

  • Entfernen Sie zuerst die Elternschaft. Der Three.js-Exporter exportiert keine Animationen, wenn Sie ihn verlassen (dies gilt auch für den Armature Modifier).
  • Zweitens, Gruppenscheitelpunkte. Wenn Sie möchten, dass der Knochen beliebige Scheitelpunkte verschiebt, müssen Sie diese gruppieren und der Gruppe den Namen des Knochens geben.
  • Drittens können Sie nur eine Animation haben. Das hört sich vielleicht nach einem großen Problem an, aber ich werde die Problemumgehung später erklären.

Beim Exportieren müssen Sie außerdem sicherstellen, dass diese Optionen im Exporter ausgewählt sind: Enthäuten, Knochen und Skelettanimation.


Schritt 2: Importieren des Modells

Wie bei so ziemlich allem in Three.js ist das Importieren von Modellen sehr einfach. Es gibt eine besondere Klasse, THREE.JSONLoader das wird alles für uns tun. Natürlich werden nur JSON-Modelle geladen, aber es wird empfohlen, sie zu verwenden, damit ich diesen Lader nur abdecken kann (andere funktionieren ziemlich ähnlich). Lassen Sie uns es zuerst initialisieren:

 var loader = neuer THREE.JSONLoader; var Animation;

Keine Argumente nötig. Wir müssen auch definieren eine Variable für die Animation, damit wir später darauf zugreifen können. Jetzt können wir das Modell laden:

 loader.load ('./ model.js', Funktion (Geometrie, Materialien) var skinnedMesh = neu THREE.SkinnedMesh (Geometrie, neues THREE.MeshFaceMaterial (Materialien)); skinnedMesh.position.y = 50; skinnedMesh.scale. Set (15, 15, 15); scene.add (skinnedMesh); animate (skinnedMesh););

Das Belastung Die Methode akzeptiert zwei Parameter: einen Pfad zum Modell und eine Rückruffunktion. Diese Funktion wird aufgerufen, wenn das Modell geladen wird (in der Zwischenzeit können Sie dem Benutzer einen Ladebalken anzeigen). Eine Callback-Funktion wird mit zwei Parametern aufgerufen: der Geometrie des Modells und seiner Materialien (diese werden mit exportiert). Im Callback erstellen wir das Mesh, diesmal aber THREE.SinnedMesh, die Animationen unterstützt.

Als Nächstes bewegen wir das Modell um 50 Einheiten nach oben, um es auf die Oberseite unseres Würfels zu legen, 15 Mal zu skalieren (da ich in Blender eher kleine Modelle erstelle) und der Szene hinzufügen. Als nächstes rufen wir die animieren Funktion zur Einrichtung und Wiedergabe der Animation.


Schritt 3: Animation

Jetzt richten wir die Animation ein. Dies ist die Quelle für die animieren Funktion:

 Funktion animate (skinnedMesh) var materials = skinnedMesh.material.materials; für (var k in materials) materials [k] .skinning = true;  THREE.AnimationHandler.add (skinnedMesh.geometry.animation); animation = new THREE.Animation (skinedMesh, "ArmatureAction", THREE.AnimationHandler.CATMULLROM); animation.play (); 

Zuerst müssen wir das Skinning (Animationen) in allen Materialien des Modells aktivieren. Als nächstes müssen wir die Animation vom Modell zu hinzufügen DREI.AnimationHandler und das erstellen DREI.Animation Objekt. Die Parameter sind in der folgenden Reihenfolge angeordnet: Das zu animierende Mesh, der Animationsname im Modell und der Interpolationstyp (nützlich, wenn Sie ein kompliziertes Modell wie einen menschlichen Körper haben, bei dem das Mesh glatt gebogen werden soll). Zum Schluss spielen wir die Animation.

Wenn Sie jetzt den Browser öffnen, sehen Sie, dass sich das Modell nicht bewegt:

Um dies zu beheben, müssen wir unserer Zeile eine Zeile hinzufügen machen Funktion, direkt unterhalb der Partikelsystem Drehung:

 if (Animation) Animation.Update (Delta);

Dadurch wird die Zeit für die Animation aktualisiert DREI.AnimationHandler weiß, welcher Frame gerendert werden soll. Öffnen Sie nun den Browser und Sie sollten den oberen Würfel nach links und rechts sehen lassen:


Schritt 4: Mehrere Animationen

Ja, es gibt eine Problemumgehung für nur eine Animationssequenz in einem Modell, aber Sie müssen diese bearbeiten. Die Idee ist, dass Sie jede Animation zu einer Sequenz hinzufügen. Wenn diese beendet ist, beginnt die nächste. Nachdem Sie Ihr Modell exportiert haben, müssen Sie als Nächstes den Animationscode ändern. Nehmen wir an, wir haben eine stehende Animation von Anfang bis zur dritten Sekunde und eine gehende Animation von der dritten Sekunde bis zum Ende. Dann in unserem machen Funktion müssen wir prüfen, in welcher Sekunde sich die Animation befindet, und wenn sie die Endzeit der aktuellen Sequenz erreicht, stoppen Sie sie und spielen Sie sie von Anfang an ab:

 var currentSequence = 'standing'; Funktion (Rendern) … if (Animation) animation.update (Delta); if (currentSequence == 'standing') if (animation.currentTime> 4) animation.stop (); Animation.play (falsch, 0); // spiele die Animation nicht in einer Schleife ab 0s else if (currentSequence == 'walking') if (animation.currentTime <= 4 || animation.currentTime > 8) animation.stop (); Animation.play (falsch, 4); // spiele die Animation nicht in einer Schleife ab 4s

Sie müssen daran denken, die Animationen nicht in einer Schleife und zum richtigen Zeitpunkt zu starten. Dies wird natürlich fehlerhaft sein, wenn die Framerate des Benutzers wirklich niedrig ist, da das Delta höher sein wird animation.currentTime kann viel höher als der Grenzwert für eine bestimmte Sequenz sein, was dazu führt, dass ein Teil der nächsten Sequenz abgespielt wird. Es wird jedoch nur wahrnehmbar, wenn die Deltas etwa 300 bis 500 ms betragen.

Jetzt das ändern animieren Funktion, um die Laufanimation abzuspielen, fügen Sie diese Argumente einfach dem hinzu animation.play Funktion:

 Animation.play (falsch, 0);

Erlauben Sie dem Benutzer auch, zwischen den Animationen mit der Taste zu wechseln ein Schlüssel. Fügen Sie diesen Code am Ende der Datei direkt vor dem ein machen() Anruf:

 document.addEventListener ('keyup', Funktion (e) if (e.keyCode == 'A'.charCodeAt (0)) currentSequence = (currentSequence ==' stehend '?' Gehen ':' stehend '); );

Schritt 5: An Knochen befestigen

Diese Technik ist besonders in RPGs nützlich, kann aber auch auf andere Genres angewendet werden. Es beinhaltet befestigen ein anderes Objekt am Knochen des animierten Objekts: Kleidung, Waffen usw.

Beginnen wir mit der Modifizierung unserer loader.load Ruf zurück. Fügen Sie diesen Code unter ein scene.add (skinnedMesh '):

 item = new THREE.Mesh (new THREE.CubeGeometry (100, 10, 10), neues THREE.MeshBasicMaterial (color: 0xff0000)); item.position.x = 50; pivot = new THREE.Object3D (); Drehpunktsatz (0,15, 0,15, 0,15); Pivot.add (Element); pivot.useQuaternion = true; skinnedMesh.add (Pivot);

Das Artikel Mesh simuliert etwas, das Sie an ein animiertes Objekt anhängen möchten. Damit es sich um einen bestimmten Punkt dreht und nicht um den Mittelpunkt herum, fügen wir es einem hinzu schwenken Objekt und verschieben Sie es um 50 Einheiten (die Hälfte der Breite) nach rechts. Wir müssen es skalieren 0,15, weil es dem hinzugefügt wird skinedMesh das hat eine Skala von fünfzehn. Schließlich, bevor es zu unserem animierten Objekt hinzugefügt wird, weisen wir es an, Quaternionen zu verwenden.

Quaternionen sind im Grunde ein Zahlensystem. Da Three.js jedoch alles für uns erledigt, müssen Sie sich nicht mit diesem Thema befassen, wenn Sie nicht wollen (schauen Sie sich aber die Wikipedia-Seite an). Sie dienen zum Drehen von Objekten ohne die Gefahr einer Kardanverriegelung.

Jetzt in der machen Funktion müssen wir die Position und Rotation des Objekts aktualisieren:

 pivot.position = new THREE.Vector3 (). getPositionFromMatrix (skinnedMesh.bones [2] .skinMatrix); pivot.quaternion.setFromRotationMatrix (skinnedMesh.bones [2] .skinMatrix);

Lassen Sie mich erklären, was hier passiert. Zuerst setzen wir die Position auf den letzten Knochen des Modells. Wir benutzen die skinMatrix Eigenschaft, um es zu berechnen. Dann verwenden wir dieselbe Eigenschaft, um die Quaternion für die schwenkenRotation. Danach können Sie den Browser öffnen und Sie sollten den roten Balken unseres Modells sehen:


Fazit

Ich hoffe, Sie haben aus diesem Tutorial ein paar neue interessante Techniken gelernt. Experimentieren Sie wie immer mit der von uns erstellten App. Im nächsten (und letzten) Tutorial dieser Serie zeige ich Ihnen die wahre Kraft der OpenGL / WebGL-Shader.