Erstellen Sie mit A-Frame und Tone.js ein audiovisuelles VR-Erlebnis

Hallo Habr! Ich präsentiere Ihnen die Übersetzung des Artikels „Erstellen einer audiovisuellen VR-Erfahrung im Web mit A-Frame und Tone.js“ von Sean Sullivan.

Firefox Realität in Oculus Go

A-Frame ist ein Framework zum Erstellen von virtueller Realität im Web. Mit nur einem Link kann jeder mit einem VR-Helm oder einem VR-fähigen Smartphone in den 3D-Raum eintauchen. Tone.js ist eine JavaScript-Bibliothek zum Erstellen von Sounds. Mal sehen, was passiert, wenn sie kombiniert werden.

Zunächst erstellen wir eine Umgebung, mit A-Frame ist dies sehr einfach. Mit nur einfachem HTML können wir einen ganzen 3D-Raum erstellen, dafür benötigen wir eine aframe-environment-Komponente . Nachfolgend finden Sie das grundlegende Markup für unsere Zwecke.

<!DOCTYPE html>
<html>
<head>
  <title>Basic Scene with Environment - A-Frame</title>
  <meta name="description" content="Basic Scene with Environment - A-Frame">
  <script src="https://aframe.io/releases/1.0.4/aframe.min.js">  </script>
  <script src="https://unpkg.com/aframe-environment-component@1.1.0/dist/aframe-environment-component.min.js"></script>
</head>
<body>
  <a-scene environment="preset: starry">
    <a-camera>
      <a-entity cursor="fuse: true; fuseTimeout: 500"
            position="0 0 -1"
            geometry="primitive: ring; radiusInner: 0.02; radiusOuter: 0.03"
            material="color: black; shader: flat">
      </a-entity>    
    </a-camera>
  </a-scene>
</body>
</html>

Achten Sie auf das Element:
<a-entity cursor>
Es ist in unserer Zelle. Wenig später wird er Ihnen erlauben, mit unserem Synthesizer zu kommunizieren. Bevor Sie beginnen, sollten Sie jedoch sicherstellen, dass das Projekt korrekt geladen ist.

Wenn Sie die Seite öffnen, sollten Sie einen dreidimensionalen Himmel, Sterne und ein Gitter auf der Erde sehen. All dies wurde von aframe-environment-component erstellt, als wir die Umgebung definiert haben:

<a-scene environment=”preset: starry”>

Falls gewünscht, kann die Umgebung geändert werden. Fügen Sie einfach eine weitere Vorlage hinzu. Zum Zeitpunkt dieses Schreibens stehen 16 verschiedene Umgebungsvorlagen Ihrer Wahl zur Verfügung.

Sternenhimmel

Ich mag es, dass unser Synthesizer im Weltraum ist, der Weltraum ist cool. Machen wir unsere Umwelt mehr wie die Oberfläche eines Planeten.

Zuerst entfernen wir das Gitter und fügen die Textur der Erde hinzu, wobei wir Folgendes ändern:

<a-scene environment="preset: starry">

auf der

<a-scene environment="preset: starry; grid: none; groundTexture: walkernoise">

Nachdem wir die Seite jetzt gestartet haben, werden wir sehen, dass unser Planet noch zu dunkel ist, um etwas auf der Erde zu sehen. Beheben Sie dies, indem Sie unserer Szene eine Lichtquelle hinzufügen.

<a-entity light="type: ambient; color: #CCC"></a-entity>

Damit sollte die Szene ungefähr so ​​aussehen:

Szene mit Licht

Nachdem wir die Umgebung herausgefunden haben, beginnen wir mit der Entwicklung eines Synthesizers.

Komponentenerstellung


A-Frame basiert auf einem Entity-Component-System . Sie können damit Komponenten erstellen und zu Entitäten in unserer Szene hinzufügen.

Erstellen wir eine synth.js- Datei für unsere Komponente.

AFRAME.registerComponent('synth', {
  schema: {
    //   .
  },

  init: function () {
    //     .
  },

  update: function () {
    //     .
  },

  remove: function () {
    //       .
  },
  tick: function (time, timeDelta) {
    //     ()  .
  }
});

Wie Sie sehen können, sind Lebenszyklusmethoden in A-Frame integriert. Dies erleichtert das Hinzufügen von Interaktivität zu unseren WebVR-Projekten. Die Komponentenbasis ist fertig. Schauen wir uns den Prozess zum Erstellen eines Synthesizers mit Tone.js an.

Tone.js


Tone.js - ein Framework zum Erstellen interaktiver Musik in einem Browser, ist ein Wrapper für die Web-Audio-API. Das Erstellen eines Synthesizers mit ton.js ist einfach - schreiben Sie einfach eine Zeile:

var synth = new Tone.Synth().toMaster()

Wir werden jedoch einen Oszillator erstellen und mehrere Parameter hinzufügen, um die weitere Anpassung zu vereinfachen:

const synth = new Tone.Synth({
  volume: -15, // -15dB
  oscillator: {
    type: 'triangle' //   -  ""
  },
  envelope: {
    attack: 0.05, //  -  
    release: 2 //   - 
  }
}).toMaster()

Fügen Sie diesen Code direkt über unserer Komponente in der Datei synth.js hinzu . Jetzt haben wir einen Synthesizer, aber wir müssen unserer Komponente eine Möglichkeit bieten, darauf zuzugreifen. Erinnern Sie sich an den <a-entity-Cursor>, den wir der Kamera hinzugefügt haben? Dieser Cursor hat den Parameter fuse = "true" . Auf diese Weise können wir verfolgen, wie der Cursor mit Entitäten interagiert. Fügen Sie der Komponente einen EventListener für die Sicherung hinzu.

Wir werden einen EventListener in der init- Methode des Lebenszyklus erstellen und eine neue Methode namens trigger erstellen , die Tone.js auslöst.

...
init: function () {
  //  EventListener     fuse
  this.el.addEventListener('fusing', this.trigger.bind(this))
},
//  ,  tone.js
trigger: function () {
  //tone.js ,     
  synth.triggerAttackRelease(this.data.note, this.data.duration)
},
...

Fügen Sie der Szene eine Synthesizer-Komponente hinzu.


Wir haben die Komponente erstellt. Es ist Zeit, sie der A-Frame-Szene hinzuzufügen.

Zu Beginn habe ich Tone.js und eine Synthesizer-Komponente zu unserem Markup hinzugefügt. Achten Sie auf die Reihenfolge der Verbindungsdateien - synth.js wird nach Tone.js geladen.

...
<script src="https://unpkg.com/tone@13.8.25/build/Tone.js"></script>
<script src="synth.js"></script>
</head>
...

Wir benötigen auch mehrere Entitäten, an die wir die Komponente anhängen werden. Fügen Sie einige Standard-A-Frame-Formen zur Verwendung in unserer Szene hinzu.

<a-scene>
...
<a-box synth="note: E4" position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9"></a-box>
<a-sphere synth="note: C4" position="0 1.25 -5" radius="1.25" color="#EF2D5E"></a-sphere>
<a-cylinder synth="note: G4" position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D"></a-cylinder>
...

Beachten Sie das Synth- Attribut . Dies ist die Komponente, die wir erstellt haben. 'Synth' ist der Name, mit dem wir uns registriert haben
AFRAME.registerComponent ('synth', {})
und wir haben im Komponentendiagramm "note" deklariert. Es gibt auch eine "Dauer" -Eigenschaft - wir können sie verwenden, um die Länge einer Note zu ändern. Zum Beispiel:
synth = "Anmerkung: E4; Dauer: 8n »
spielt 1/8 der gesamten Note, nicht das Standard 1/4.

Nachdem Sie die Szene im Browser geöffnet haben, sehen wir unsere Figuren. Wenn Sie mit der Maus darüber fahren, sollte die Note unserer Synthesizer-Komponente abgespielt werden.

Musikalische Figuren

Verwenden des Oculus Go Controllers


Jetzt funktioniert unsere Szene so - der Cursor befindet sich in der Mitte des Bildschirms. Bei VR-Helmen wird dies als „visuelle“ Steuerung bezeichnet. Durch Drehen des Kopfes bewegt sich der Cursor in die Bewegungsrichtung des Benutzers. Dies ist eine absolut normale Erfahrung und funktioniert gut für viele Projekte. Was aber, wenn wir den Synthesizer mit einem VR-Controller steuern wollen? Bewegen Sie Ihre Arme und machen Sie Musik zum Spaß. Ändern Sie also unsere Szene, um den Oculus Go-Controller zu verwenden.

Fügen Sie unserer Szene zunächst einige Elemente hinzu - den Controller und den Raycaster.

...
<a-entity oculus-go-controls>
<a-entity laser-controls raycaster="far: 200; interval: 100"></a-entity>
...

Hier haben wir eine eigene Entität zur Steuerung von Oculus Go sowie eine für Raycaster, die alle 100 Millisekunden ausgeführt wird.

Ändern wir nun die Synthesizer-Komponente, um Oculus zu steuern. Dazu fügen wir je nach Komponente Raycaster hinzu.

AFRAME.registerComponent('synth', {
  dependencies: ['raycaster'],
...

Ändern Sie dann in der init- Methode den EventListener - er sollte das Ereignis verfolgen:
Raycaster-Kreuzung


init: function () {
  this.el.addEventListener('raycaster-intersection', this.trigger.bind(this))
},
...

Der Beginn der Szene in Oculus Go sollte nun Ihren Controller anzeigen - und die Lasersteuerung sollte den Synthesizer dazu bringen, Noten zu spielen, wenn Sie mit der Maus über die Figuren fahren.

Oculus gehen

Wenn Sie sich das Projekt genauer ansehen möchten, können Sie es ausführen und den Quellcode hier anzeigen - glitch.com/~space-synth-vr

In Gewahrsam


Jetzt haben wir eine einfache Szene mit einem VR-Synthesizer und es gibt eine Vielzahl von Möglichkeiten, sie zu verbessern. Wir können mehr Objekte für die Interaktion, mehr Synthesizer und Effekte für die Komponente hinzufügen. Wir können Objekte basierend auf einigen Ereignissen animieren. Wenn die Szene wächst, sollten Sie über die Leistung nachdenken. Glücklicherweise verfügt A-Frame über viele integrierte Funktionen, die bei diesem Problem helfen können.

Hier sind einige nützliche Links Raycaster

Komponenten Interaktion und Steuerung Tone.js Projekt Source Code Danke für das Lesen.






All Articles