Erstellen eines plattformübergreifenden WebGL-Spiels mit Babylon.js
Veröffentlicht: 2022-03-10Hier ist eine Herausforderung für Sie: Wie wäre es, wenn Sie am Wochenende ein 3D-Spiel erstellen? Babylon.js ist ein JavaScript-Framework zum Erstellen von 3D-Spielen mit HTML5, WebGL und Web Audio , das von Ihnen und dem Babylon.js-Team entwickelt wurde. Um die neue Version 2.3 der Bibliothek zu feiern, haben wir uns entschieden, eine neue Demo namens „Sponza“ zu erstellen, um zu zeigen, was heutzutage mit der WebGL-Engine und HTML5 möglich ist, wenn es darum geht, großartige Spiele zu entwickeln.
Die Idee war, auf allen von WebGL unterstützten Plattformen ein konsistentes, ähnliches, wenn nicht identisches Erlebnis zu schaffen und zu versuchen, die Funktionen nativer Apps zu erreichen. In diesem Artikel erkläre ich, wie alles zusammenarbeitet, zusammen mit den verschiedenen Herausforderungen, denen wir gegenüberstanden, und den Lektionen, die wir beim Erstellen gelernt haben.
Weiterführende Literatur zu SmashingMag:
- Erstellen von Shadern mit Babylon.js
- Verwenden der Gamepad-API in Webspielen
- Einführung in die polygonale Modellierung und Three.js
- So erstellen Sie eine reaktionsschnelle 8-Bit-Drum-Maschine
Um dieses Ziel zu erreichen, verwendet Sponza eine Reihe von HTML5-Funktionen wie WebGL, Web Audio sowie Pointer Events (jetzt dank jQuery PEP polyfill weitgehend unterstützt), Gamepad API, IndexedDB, HTML5 AppCache, CSS3-Übergang/Animation, Flexbox und Fullscreen API. Sie können die Sponza-Demo auf Ihrem Desktop, Handy oder Xbox One testen.
Entdecken Sie die Demo
Zuerst beginnen Sie mit einer automatisch animierten Sequenz, in der Sie demjenigen, der die Szene erstellt hat, die Credits geben. Die meisten Mitglieder des Teams kommen aus der Demoszene. Sie werden feststellen, dass dies ein wichtiger Teil der Kultur der 3D-Entwickler ist. Auf meiner Seite war ich bei Atari, während David Catuhe bei Amiga war, was immer noch eine regelmäßige Quelle für Konflikte zwischen uns ist, ob Sie es glauben oder nicht. Ich habe ein bisschen codiert, aber hauptsächlich die Musik in meiner Demogruppe komponiert. Ich war ein großer Fan von Future Crew und insbesondere von Purple Motion, meinem absoluten Lieblingskomponisten für Demoszenen. Aber weichen wir nicht vom Thema ab.
Für Sponza sind hier die Mitwirkenden:
- Michel Rousseau alias „Mitch“ hat als 3D-Künstler bemerkenswerte visuelle Animationen und Rendering-Optimierungen durchgeführt. Es nahm das Sponza-Modell, das kostenlos von Crytek auf ihrer Website bereitgestellt wurde, und verwendete den 3DS Max-Exporter, um das zu generieren, was Sie sehen.
- David Catuhe alias „deltakosh“ und ich haben den Kernteil der Babylon.js-Engine erstellt und auch den gesamten Code für die Demo (benutzerdefinierter Loader, Spezialeffekte für den Demo-Modus mit Fade-to-Black-Post-Prozessen usw.) sowie ein neuer Kameratyp namens „ UniversalCamera “, der alle Arten von Eingaben auf generische Weise verarbeitet.
- Ich habe die Musik mit Renoise und der EastWest Symphonic Orchestra Soundbank komponiert. Wenn Sie interessiert sind, habe ich meinen Arbeitsablauf und meinen Prozess bereits im Artikel zum Komponieren der Musik für das Windows 8-Spiel World Monger mit dem Renoise-Tracker und den East West VST-Plug-Ins geteilt
- Julien Moreau-Mathis hat uns dabei geholfen, ein neues Tool zu entwickeln, das 3D-Künstlern hilft, die Arbeit zwischen den Modellierungstools (3DS Max, Blender) und dem Endergebnis abzuschließen. Michel nutzte es zum Beispiel, um verschiedene animierte Kameras zu testen und abzustimmen und Partikel in die Szene einzufügen.
Wenn Sie bis zum Ende des automatischen Ablaufs bis zum „epischen Finish“ warten, werden Sie automatisch in den interaktiven Modus geschaltet. Wenn Sie den Demomodus umgehen möchten, klicken Sie einfach auf das Kamerasymbol oder drücken Sie A
auf Ihrem Gamepad.
Wenn Sie sich auf einem Mac oder PC befinden, können Sie sich im interaktiven Modus mit Tastatur/Maus wie in einem FPS-Spiel innerhalb der Szene bewegen. Wenn Sie ein Smartphone verwenden, können Sie sich mit einer einzigen Berührung bewegen (und 2
, um die Kamera zu drehen). Schließlich können Sie auf einer Xbox One das Gamepad verwenden (oder den Desktop, wenn Sie ein Gamepad daran anschließen). Unterhaltsame Tatsache: Auf einem Windows-Touch-PC können Sie potenziell 3 Arten von Eingaben gleichzeitig verwenden.
Im interaktiven Modus ist die Atmosphäre anders. Sie haben drei zufällig in der 3D-Umgebung positionierte Sturm-Audioquellen, Windstöße und Feuerknallen an jeder Ecke. Bei unterstützten Browsern (Chrome, Firefox, Opera und Safari) können Sie sogar zwischen dem normalen Lautsprechermodus und dem Kopfhörermodus wechseln, indem Sie auf das entsprechende Symbol klicken. Es verwendet dann das binaurale Audio-Rendering von Web Audio für eine realistischere Audiosimulation – wenn Sie über Kopfhörer zuhören.
Um ein vollständiges App-ähnliches Erlebnis zu haben, haben wir Symbole und Kacheln für alle Plattformen generiert. Das bedeutet zum Beispiel, dass Sie unter Windows 8 ⁄ 10 die Web-App an das „Start“-Menü anheften können. Wir haben sogar mehrere Größen verfügbar:
Zuerst offline!
Sobald die Demo vollständig geladen wurde, können Sie Ihr Telefon in den Flugzeugmodus schalten, um die Verbindung zu unterbrechen, und auf das Sponza-Symbol klicken. Die Web-App bietet weiterhin das komplette Erlebnis mit WebGL-Rendering, 3D-Web-Audio und Touch-Unterstützung. Schalten Sie es auf Vollbild um und Sie werden den Unterschied zwischen der Demo und einer nativen App-Erfahrung buchstäblich nicht spüren können.
Wir verwenden dafür die IndexedDB-Schicht, die nativ in Babylon.js verfügbar ist. Die Szene (JSON-Format) und die Ressourcen (JPG/PNG-Texturen sowie MP3 für die Musik und Sounds) werden in IDB gespeichert. Die mit dem HTML5-Anwendungscache gekoppelte IDB-Schicht stellt dann das Offline-Erlebnis bereit. Um mehr über diesen Teil zu erfahren und wie Sie Ihr Spiel konfigurieren, um ähnliche Ergebnisse zu erzielen, können Sie den Artikel über die Verwendung von IndexedDB zum Umgang mit Ihren 3D-WebGL-Assets: Teilen von Feedbacks und Tipps zu Babylon.JS und Caching-Ressourcen in IndexedDB in Babylon.js lesen
Xbox One genießt die Show
Zu guter Letzt funktioniert die gleiche Demo einwandfrei in MS Edge auf Ihrer Xbox One:
Drücken Sie A
, um in den interaktiven Modus zu wechseln. Die Xbox One benachrichtigt Sie, dass Sie sich jetzt mit Ihrem Gamepad in der 3D-Szene bewegen können:
Fassen wir also kurz zusammen.
Dieselbe Codebasis funktioniert auf Mac, Linux, Windows auf MS Edge, Chrome, Firefox, Opera und Safari, auf iPhone/iPad, auf Android-Geräten mit Chrome oder Firefox, Firefox OS und auf Xbox One! Ist das nicht cool? In der Lage zu sein, so viele Geräte mit einem vollwertigen nativen Erlebnis direkt von Ihrem Webserver aus anzusprechen?
Ich habe meine Begeisterung über das Potenzial der Technologie bereits in einem früheren Artikel über Das Web: die nächste Spielgrenze?
Hacken Sie die Szene mit dem Debug-Layer
Wenn Sie verstehen möchten, wie Michel die Magie der 3D-Modellierung beherrscht, können Sie die Szene mit dem Babylon.js- Debug-Layer -Tool hacken. Um es auf einem Computer mit einer Tastatur zu aktivieren, drücken Sie CMD/CTRL + SHIFT + D
und wenn Sie ein Gamepad auf einem PC oder einer Xbox verwenden, drücken Sie Y
. Bitte beachten Sie, dass die Anzeige des Debug-Layers aufgrund der Kompositionsaufgabe, die die Rendering-Engine ausführen muss, etwas Leistung kostet. Die angezeigten FPS sind also etwas weniger wichtig als die tatsächlichen FPS, die Sie ohne die angezeigte Debug-Ebene haben.
Testen wir es zum Beispiel auf einem PC.
Bewegen Sie sich in die Nähe des Löwenkopfes und schneiden Sie den Bump-Kanal von der Pipeline unseres Shaders ab:
Sie sollten sehen, dass der Kopf jetzt weniger realistisch ist. Spielen Sie mit dem anderen Kanal, um zu überprüfen, was los ist.
Sie können auch die dynamische Blitz-Engine abschalten oder die Kollisions-Engine deaktivieren, um durch die Wände zu fliegen oder sich zu bewegen. Deaktivieren Sie zum Beispiel das Kontrollkästchen „ Kollisionen “ und fliegen Sie in den ersten Stock. Platzieren Sie die Kamera vor den roten Fahnen. Sie können sehen, wie sie sich leicht bewegen. Michel hat die Bones/Skeletons-Unterstützung von Babylon.js verwendet, um sie zu verschieben. Deaktivieren Sie jetzt die Option „ Skelette “ und sie sollten sich nicht mehr bewegen:
Endlich können Sie den Maschenbaum in der oberen rechten Ecke anzeigen. Sie können sie aktivieren oder deaktivieren, um die von Michel geleistete Arbeit vollständig zu unterbrechen:
Das Entfernen der Geometrien, der Shader-Kanäle oder einiger Optionen der Engine kann Ihnen bei der Fehlerbehebung bei der Leistung auf einem bestimmten Gerät helfen, um zu sehen, was derzeit zu viel kostet. Sie können auch überprüfen, ob Sie CPU-beschränkt oder GPU-beschränkt sind, obwohl Sie in WebGL aufgrund der Mono-Threading-Natur von JavaScript meistens CPU-beschränkt sind. Schließlich ist das Tool auch sehr nützlich, um Ihnen zu helfen, zu erfahren, wie eine Szene vom 3D-Künstler erstellt wurde.
Übrigens funktioniert es auch auf der Xbox One ziemlich gut:
Herausforderungen
Auf dem Weg dorthin sahen wir uns einer Reihe von Problemen und Herausforderungen gegenüber, um die Demo zu erstellen. Schauen wir uns einige von ihnen im Detail an.
WebGL-Leistung und plattformübergreifende Kompatibilität
Die Programmierseite war wahrscheinlich am einfachsten zu bewältigen, da sie vollständig von der Babylon.js-Engine selbst gehandhabt wird. Wir verwenden eine benutzerdefinierte Shader-Architektur, die sich an die Plattform anpasst, indem wir versuchen, den besten Shader zu finden, der für den aktuellen Browser/GPU verfügbar ist, indem wir verschiedene Fallbacks verwenden. Die Idee ist, die Qualität und Komplexität der Rendering-Engine zu verringern, bis wir es schaffen, etwas Sinnvolles auf dem Bildschirm anzuzeigen.
Babylon.js basiert hauptsächlich auf WebGL 1.0, um zu garantieren, dass die darauf aufgebauten 3D-Erlebnisse so ziemlich überall laufen. Es wurde unter Berücksichtigung der Web-Philosophie entwickelt, daher verbessern wir den Shader-Kompilierungsprozess schrittweise. Dies ist für den 3D-Künstler völlig transparent, der sich die meiste Zeit nicht mit diesen Komplexitäten befassen möchte.
Dennoch spielt der 3D-Künstler eine sehr wichtige Rolle bei der Leistungsoptimierung. Sie muss die Plattform, auf die sie abzielt, die unterstützten Funktionen und Einschränkungen kennen. Sie können keine Assets aus AAA-Spielen nehmen, die für High-End-GPUs und DirectX 12 entwickelt wurden, und sie einfach in ein Spiel integrieren, das auf einer WebGL-Engine läuft. Ich würde argumentieren, dass das Targeting von WebGL heute ziemlich ähnlich ist wie die Arbeit, die Sie tun müssen, um für Erfahrungen auf mobilen Geräten zu optimieren, mit einer Prise zusätzlichem JavaScript, das stark monothreaded sein muss.
Mitch ist genau darin sehr gut: die Texturen optimieren, den Blitz vorab berechnen, um ihn in die Texturen einzubacken, die Anzahl der Draw Calls so weit wie möglich zu reduzieren usw. Er hat jahrelange Erfahrung hinter sich und hat die verschiedenen Generationen von gesehen 3D-Hardware und -Engines (von PowerVR/3DFX bis zu den heutigen GPUs), die wirklich dazu beigetragen haben, die Demo zu verwirklichen.
Ein bisschen von diesen Grundlagen hat er bereits in seinen Artikeln zu Real Time 3D: Making a demo for WebGL Purposes – Basics geteilt und bereits mehrfach bewiesen, dass man mit kleinen integrierten GPUs, z Demoszenen von Mansion, Hill Valley oder Espilit. Wenn Sie interessiert sind, nehmen Sie sich die Zeit, seinen Vortrag über NGF2014 – Erstellen von 3D-Assets für die mobile Welt und das Web, die Sichtweise eines 3D-Designers, aus der er seine Erfahrungen teilte, und wie er es geschafft hat, die Hill Valley-Szene zu optimieren, anzusehen weniger als 1 fps bis 60 fps.
Das ursprüngliche Ziel von Sponza war es, zwei Szenen zu bauen. Eine für den Desktop und eine für Mobilgeräte mit weniger Komplexität, kleineren Texturen und einfacheren Meshes und Geometrien. Aber während unserer Tests stellten wir schließlich fest, dass die Desktop-Version auch auf Mobilgeräten ziemlich gut lief, da sie auf einem iPhone 6s oder einem Android OnePlus 2 bis zu 60 fps erreichen kann. Wir entschieden uns dann, nicht weiter an der einfacheren mobilen Version zu arbeiten.
Aber auch hier wäre es wahrscheinlich besser gewesen, einen sauberen Mobile-First-Ansatz für Sponza zu haben, um 30fps+ auf vielen Mobilgeräten zu erreichen, und dann die Szene für High-End-Mobilgeräte und -Desktops zu verbessern. Dennoch scheinen die meisten Rückmeldungen, die wir bisher auf Twitter erhalten haben, darauf hinzudeuten, dass das Endergebnis auf den meisten Geräten sehr gut funktioniert. Zugegebenermaßen wurde Sponza auf einer HD4000-GPU (Intel Core i5 integriert) optimiert, die mehr oder weniger den GPUs tatsächlicher High-End-Mobilgeräte entspricht.
Wir waren sehr zufrieden mit der Leistung, die wir erreicht haben. Sponza verwendet unseren Shader mit aktiviertem Ambient , Diffuse , Bump , Specular und Reflection . Wir haben einige Partikel , um kleine Feuer an jeder Ecke zu simulieren, animierte Knochen für die roten Fahnen, 3D-positionierte Geräusche und Kollisionen , wenn Sie sich im interaktiven Modus bewegen.
Technisch gesehen haben wir 98 Meshes in der Szene verwendet , die bis zu 377781 Vertices, 16 Actives Bones und über 60 Partikel generieren, die bis zu 36 Draw Calls generieren könnten. Was haben wir gelernt? Eines ist sicher: Weniger Draw Calls sind der Schlüssel zu optimaler Performance, vor allem im Web.
Der Lader
Für Sponza wollten wir einen neuen Loader erstellen, der sich von dem Standardlader unterscheidet, den wir auf der BabylonJS-Website verwenden, um eine saubere und ausgefeilte Web-App zu haben. Ich habe Michel dann gebeten, etwas Neues vorzuschlagen.
Er schickte mir zuerst den folgenden Bildschirm:
Tatsächlich sieht der Bildschirm auf den ersten Blick sehr schön aus. Aber dann fragen Sie sich vielleicht, wie Sie es auf allen Geräten auf wirklich reaktionsschnelle Weise zum Laufen bringen können? Finden wir es heraus.
Lassen Sie uns zuerst über die Hintergründe sprechen. Der von Michel erzeugte Unschärfeeffekt war nett, funktionierte aber nicht bei allen Fenstergrößen und Auflösungen gut, da er etwas Moiré erzeugte. Ich habe es dann durch einen „klassischen“ Screenshot der Szene ersetzt. Ich wollte jedoch, dass der Hintergrund den Bildschirm vollständig ausfüllt, ohne schwarze Balken und ohne das Bild zu dehnen, um das Verhältnis zu brechen.
Die Lösung kommt hauptsächlich von CSS background-size: cover
+ Zentrieren des Bildes auf der X- und Y-Achse. Als Ergebnis haben wir dann die Erfahrung, die ich gesucht habe, unabhängig vom verwendeten Bildschirmverhältnis:
Die anderen Teile verwenden die gute alte prozentbasierte CSS-Positionierung. Okay, wenn das sortiert ist, wie gehen wir mit der Typografie um – die Schriftgröße sollte auf der Größe des Ansichtsfensters basieren. Natürlich können wir dafür Viewport-Einheiten verwenden. vw
und vh
(wobei 1vw 1 % der Breite des Darstellungsbereichs und 1vh 1 % der Höhe des Darstellungsbereichs entspricht) werden recht gut von allen Browsern unterstützt, insbesondere von allen WebGL-kompatiblen Browsern. (Es gibt auch einen Artikel über Viewport Sized Typography im Smashing Magazine, dessen Lektüre ich Ihnen wärmstens empfehle.)
Schließlich spielen wir mit der opacity
des Hintergrundbilds, um es von 0
auf 1
zu verschieben, basierend auf dem aktuellen Download-Prozess, der sich von 0 auf 100 % bewegt.
Oh, übrigens, die Textanimationen werden einfach mit CSS-Übergängen oder Animationen in Kombination mit einem Flexbox-Layout erstellt, um eine einfache, aber effiziente Möglichkeit zur Anzeige in der Mitte oder an jeder Ecke zu haben.
Transparenter Umgang mit allen Eingaben
Unsere WebGL-Engine erledigt die ganze Arbeit auf der Rendering-Seite, um die Visuals auf allen Plattformen korrekt anzuzeigen. Aber wie können wir garantieren, dass sich der Benutzer unabhängig vom verwendeten Eingabetyp innerhalb der Szene bewegen kann?
In der vorherigen Version von Babylon.js unterstützten wir alle Arten von Eingaben und Benutzerinteraktionen: Tastatur/Maus, Touch, virtuelle Touch-Joysticks, Gamepad, Geräteorientierungs-VR (für Card Board) und WebVR, jeweils über eine dedizierte Kamera. Sie können unsere Dokumentation lesen, um mehr darüber zu erfahren.
Touch wird universell mit der Pointer-Events-Spezifikation verwaltet, die über das jQuery-PEP-Polyfill (Generieren von Touch-Events für die App bei Bedarf) an alle Plattformen weitergegeben wird. Um mehr über Pointer Events zu erfahren, lesen Sie weiter Unifying touch and mouse: how Pointer Events will cross-browser touch support easy
Dann zurück zur Demo. Die Idee für Sponza war, eine einzigartige Kamera zu haben, die alle Benutzerszenarien gleichzeitig handhaben kann: Desktop, Mobilgerät und Konsole.
Am Ende haben wir die UniversalCamera entwickelt . Um ehrlich zu sein, es war so offensichtlich und einfach zu erstellen, dass ich immer noch nicht weiß, warum wir es nicht schon früher gemacht haben. Die UniversalCamera ist mehr oder weniger eine Gamepad-Kamera, die die TouchCamera erweitert, die die FreeCamera erweitert.
Die FreeCamera stellt die Tastatur/Maus-Logik bereit; Die TouchCamera stellt die Touch-Logik bereit, und die letzte Erweiterung stellt die Gamepad-Logik bereit.
Die UniversalCamera wird jetzt standardmäßig in Babylon.js verwendet. Wenn Sie durch die Demos blättern, können Sie sich in allen Szenen mit Maus, Touch und Gamepad bewegen. Auch hier können Sie den Code studieren, um zu sehen, wie genau es gemacht wird.
Synchronisieren der Übergänge mit Musik
In diesem Teil haben wir uns die meisten Fragen gestellt. Sie haben vielleicht bemerkt, dass die Einführungssequenz mit bestimmten Bereichen des Musik-Playtracks synchronisiert ist . Die ersten Zeilen werden angezeigt, wenn einige der Trommeln einsetzen, und die abschließende Endsequenz wechselt schnell von einer Kamera zur anderen bei jeder Note des Horninstruments, das wir verwenden.
Das Synchronisieren von Audio mit der WebGL-Rendering-Schleife ist nicht einfach. Auch dies ist die Monothread-Natur von JavaScript, die diese Komplexität erzeugt. Die Artikel zur Einführung in die HTML5-Webworker: der JavaScript-Multithreading-Ansatz teilen einige Einblicke dahinter. Es ist wirklich wichtig, das Problem zu verstehen, um das globale Problem zu verstehen, mit dem wir konfrontiert sind, aber hier auf Details einzugehen, würde den Rahmen dieses Artikels sprengen.
Wenn Sie in Demoszenen (und Videospielen) die Grafik mit den Sounds/der Musik synchronisieren möchten, werden Sie normalerweise vom Audio-Stack angetrieben. Zwei Ansätze werden häufig verwendet:
- Generieren Sie Metadaten, die in die Audiodateien eingefügt werden und die dann einige Ereignisse „aufrufen“ könnten, wenn Sie einen bestimmten Teil davon erreichen.
- Echtzeitanalyse des Audiostreams über FFT oder ähnliche Technologien, um interessante Spitzen oder BPM-Änderungen zu erkennen, die wiederum Ereignisse für die visuelle Engine generieren würden.
Diese Ansätze funktionieren besonders gut in Umgebungen mit mehreren Threads wie C++. Aber in JavaScript haben wir mit Web Audio zwei Probleme:
- JavaScript, das mono-threaded ist und uns leider die meiste Zeit über Webworker nicht wirklich helfen wird,
- Web Audio hat keine Ereignisse , die an den UI-Thread zurückgesendet werden könnten, selbst wenn Web Audio vom Browser in einem separaten Thread verarbeitet wird.
Web Audio hat einen viel präziseren Timer als JavaScript. Es wäre fantastisch gewesen, diesen separaten Timer in einem separaten Thread verwenden zu können, um die Ereignisse zurück zum UI-Thread zu leiten. Aber heute geht das (noch?) nicht.
Auf der anderen Seite rendern wir die Szene mit WebGL und der Methode „ requestAnimationFrame
“. Das bedeutet, dass wir im „besten Fall“ einen Fensterzeitraum von 16 ms haben. Wenn Sie einen vermissen, müssen Sie bis zu 16 ms warten, um auf den nächsten Frame reagieren zu können, um die Tonsynchronisation widerzuspiegeln (z. B. um einen „Fade-to-Black“-Effekt zu starten).
Ich habe dann darüber nachgedacht, die Synchronisationslogik in die requestAnimationFrame
Schleife einzufügen. Ich untersuchte die seit dem Beginn der Sequenz verbrachte Zeit und untersuchte die Option, das Bild so anzupassen, dass es auf ein Audioereignis reagiert. Die gute Nachricht ist, dass Web-Audio den Ton rendert, was auch immer im Haupt-UI-Thread vor sich geht. Beispielsweise können Sie sicher sein, dass der 12-Sekunden-Zeitstempel der Musik genau 12 Sekunden nach Beginn der Musikwiedergabe eintrifft, selbst wenn die GPU Schwierigkeiten beim Rendern der Szene hat.
Am Ende haben wir uns schließlich für die wahrscheinlich einfachste Lösung entschieden: die Verwendung von setTimeout()
Aufrufen! Ja, ich weiß. Wenn Sie sich die meisten Artikel da draußen ansehen, einschließlich des Artikels, auf den ich oben verlinkt habe, werden Sie feststellen, dass er ziemlich unzuverlässig ist. Aber in unserem Fall wissen wir, sobald die Szene zum Rendern bereit ist, dass wir alle unsere Ressourcen (Texturen und Sounds) heruntergeladen und unsere Shader kompiliert haben. Wir sollten uns nicht zu sehr über unerwartete Ereignisse ärgern, die den UI-Thread sättigen. GC könnte ein Problem sein , aber wir haben auch viel Zeit damit verbracht, in der Engine dagegen anzukämpfen: Reduzierung des Drucks auf den Garbage Collector durch Verwendung der F12-Entwicklerleiste von Internet Explorer 11.
Wir wissen jedoch, dass diese Lösung alles andere als ideal ist. Wenn Sie zu einem anderen Tab wechseln oder Ihr Telefon sperren und einige Sekunden später wieder entsperren, kann dies zu Problemen im Synchronisierungsteil der Demo führen. Wir könnten diese Probleme beheben, indem wir die Page Visibility API verwenden, zB indem wir die Rendering-Schleife, verschiedene Sounds pausieren und die nächsten Zeitrahmen für die Aufrufe von setTimeout()
neu berechnen.
Aber vielleicht haben wir etwas verpasst; vielleicht, und sogar wahrscheinlich, gab es einen besseren Ansatz, um mit diesem Problem umzugehen. Wir würden gerne Ihre Gedanken und Vorschläge im Kommentarbereich hören, wenn Sie der Meinung sind, dass es einen besseren Weg gibt, dasselbe Problem zu lösen.
Handhabung von Web-Audio auf iOS
Die letzte Herausforderung, die ich mit Ihnen teilen möchte, ist die Art und Weise, wie Web Audio von iOS auf iPhone und iPad gehandhabt wird. Wenn Sie nach Artikeln zum Thema „Web-Audio + iOS“ suchen, werden Sie feststellen, dass viele Leute Schwierigkeiten haben, Sounds auf iOS abzuspielen. Nun, was ist da los?
iOS hat eine bemerkenswerte Unterstützung von Web Audio – sogar den binauralen Audiomodus. Apple hat jedoch entschieden, dass eine Webseite ohne die Interaktion eines bestimmten Benutzers standardmäßig keinen Ton wiedergeben kann. Diese Entscheidung wurde wahrscheinlich getroffen, um zu vermeiden, dass Werbung oder irgendetwas anderes den Benutzer durch das Abspielen unerwünschter Töne stört.
Was bedeutet das für Webentwickler? Nun, Sie müssen zuerst den Web-Audio-Kontext von iOS nach der Berührung eines Benutzers entsperren – bevor Sie versuchen, einen Ton abzuspielen. Andernfalls bleibt Ihre Webanwendung verzweifelt stumm.
Leider ist die einzige Möglichkeit, die ich gefunden habe, diese Überprüfung durchzuführen, wenn ein Benutzerplattform-Sniffing-Ansatz durchgeführt wird, da ich keine Möglichkeit zur Funktionserkennung gefunden habe, um dies zu tun. Das ist nichts weniger als eine schreckliche und keine kugelsichere Technik, aber ich konnte keine andere Lösung finden, die das Problem lösen würde. Der Code? Bitte schön!
Wenn Sie kein iPad/iPhone/iPod verwenden, steht der Audiokontext sofort zur Verfügung. Andernfalls entsperren wir den Audiokontext von iOS, indem wir beim touchend- Ereignis einen Code abspielen, der einen leeren Sound generiert. Sie können sich für das onAudioUnlocked- Event anmelden, wenn Sie darauf warten möchten, bevor Sie Ihr Spiel starten. Wenn Sie also Sponza auf einem iPhone/iPad starten, sehen Sie diesen letzten Bildschirm am Ende der Ladesequenz:
Durch Berühren einer beliebigen Stelle auf dem Bildschirm wird der Audio-Stack von iOS entsperrt und die „Show“ gestartet.
Auf geht's! Ich hoffe, dass Ihnen ein paar Einblicke hinter die Entwicklung der Demo gefallen haben. Um mehr zu erfahren, lesen Sie den vollständigen Quellcode dieser Demo auf unserem GitHub. Offensichtlich ist alles Open Source und Sie können die Hauptdateien auf GitHub finden: index.js und babylon.demo.ts.
Abschließend hoffe ich wirklich, dass Sie jetzt noch mehr davon überzeugt sind, dass das Internet definitiv eine großartige Plattform für Spiele ist! Bleiben Sie dran, denn wir arbeiten gerade an neuen Demos, die hoffentlich auch ziemlich beeindruckend sein werden.
Dieser Artikel ist Teil der Webentwicklungsreihe von Microsoft-Tech-Evangelisten und -Ingenieuren zu praktischem JavaScript-Lernen, Open-Source-Projekten und Best Practices für Interoperabilität, einschließlich Microsoft Edge-Browser.Wir empfehlen Ihnen, verschiedene Browser und Geräte einschließlich Microsoft Edge – dem Standardbrowser für Windows 10 – mit kostenlosen Tools auf dev.microsoftedge.com zu testen, einschließlich F12-Entwicklertools – sieben verschiedene, vollständig dokumentierte Tools, die Ihnen beim Debuggen, Testen und Verbessern helfen Beschleunigen Sie Ihre Webseiten. Besuchen Sie auch den Edge-Blog, um von Microsoft-Entwicklern und -Experten auf dem Laufenden und informiert zu bleiben.