Crie uma experiência de VR audiovisual usando o A-Frame e o Tone.js

Olá Habr! Apresento a você a tradução do artigo “Criando uma experiência de áudio / visual VR na Web com A-Frame e Tone.js”, de Sean Sullivan.

Realidade do Firefox no Oculus Go

A-Frame é uma estrutura para criar realidade virtual na web. Usando apenas um link, qualquer pessoa com um capacete ou smartphone habilitado para VR pode mergulhar no espaço 3D. Tone.js é uma biblioteca JavaScript para criar sons. Vamos ver o que acontece se eles forem combinados.

Para começar, criaremos um ambiente, com o quadro A é muito simples. Usando apenas HTML básico, podemos criar um espaço 3D inteiro, para isso precisamos de um componente ambiente-ambiente . Abaixo está a marcação básica para nossos propósitos.

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

Preste atenção ao elemento:
<a-entity cursor>
Está dentro da nossa cela. Um pouco mais tarde, ele permitirá que você se comunique com o nosso sintetizador. Mas antes de começar, verifique se o projeto está carregado corretamente.

Ao abrir a página, você verá um céu tridimensional, estrelas e uma grade na terra. Tudo isso foi criado pelo aframe-environment-component quando definimos o ambiente:

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

Se desejar, o ambiente pode ser alterado, basta adicionar outro modelo. No momento da redação deste artigo, existem 16 modelos de ambiente diferentes à sua escolha.

Céu estrelado

Eu gosto que o nosso sintetizador esteja no espaço, o espaço é legal. Vamos tornar nosso ambiente mais parecido com a superfície de um planeta.

Primeiro, removeremos a grade e adicionaremos a textura da terra, mudando:

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

no

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

Ao lançar a página agora, veremos que nosso planeta ainda está escuro demais para ver qualquer coisa na Terra. Corrija isso adicionando uma fonte de luz à nossa cena.

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

Com isso, a cena deve ficar assim:

Cena com luz

agora que descobrimos o ambiente, vamos começar a desenvolver um sintetizador.

Criação de componentes


O A-Frame é construído em um sistema de componente de entidade . Permite criar componentes e adicioná-los a entidades em nossa cena.

Vamos criar um arquivo synth.js para o nosso componente.

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

  init: function () {
    //     .
  },

  update: function () {
    //     .
  },

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

Como você pode ver, os métodos de ciclo de vida são incorporados ao A-Frame, facilitando a adição de interatividade aos nossos projetos WebVR. A base do componente está pronta, vamos dar uma olhada no processo de criação de um sintetizador com o Tone.js.

Tone.js


Tone.js - uma estrutura para criar música interativa em um navegador, é um invólucro para a API de áudio da Web. Criar um sintetizador com tone.js é simples - basta escrever uma linha:

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

Mas criaremos um oscilador e adicionaremos vários parâmetros para simplificar ainda mais a personalização:

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

Adicione esse código diretamente sobre o nosso componente no arquivo synth.js . Agora temos um sintetizador, mas precisamos fornecer ao nosso componente uma maneira de acessá-lo. Lembra do <cursor de uma entidade> que adicionamos à câmera? Este cursor possui um parâmetro fuse = "true" . Isso nos permitirá acompanhar como o cursor interage com as entidades. Adicione um EventListener ao componente para fusível. Criaremos

um EventListener no método init do ciclo de vida e criaremos um novo método chamado trigger que dispara Tone.js.

...
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)
},
...

Adicione um componente sintetizador à cena.


Criamos o componente, é hora de adicioná-lo à cena A-Frame.

Para começar, adicionei o Tone.js e um componente sintetizador à nossa marcação. Preste atenção na ordem de conexão dos arquivos - o synth.js é carregado após o Tone.js.

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

Também precisamos de várias entidades às quais anexaremos o componente. Adicione algumas formas A-Frame padrão para usar em nossa cena.

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

Observe o atributo synth . Este é o componente que criamos. 'Synth' é o nome com o qual registramos
AFRAME.registerComponent ('synth', {})
e declaramos "nota" no diagrama de componentes. Há também uma propriedade "duration" - podemos usá-la para alterar o tamanho de uma nota. Por exemplo:
synth = "nota: E4; duração: 8n »
tocará 1/8 da nota inteira, não o padrão 1/4.

Agora, depois de abrir a cena no navegador, veremos nossas figuras e, quando você passar o mouse sobre elas, a nota do nosso componente sintetizador deve ser reproduzida.

Figuras musicais

Usando o controlador Oculus Go


Agora nossa cena funciona assim - o cursor está fixo no centro da tela. Nos capacetes VR, isso é chamado de controle "visual". Girando a cabeça, o cursor se moverá na direção do movimento do usuário. Esta é uma experiência absolutamente normal e funciona bem para muitos projetos. Mas e se quisermos controlar o sintetizador usando um controlador VR? Movendo os braços e fazendo a música parecer divertida, vamos mudar nossa cena para usar o controlador Oculus Go.

Primeiro, adicione algumas entidades à nossa cena - o controlador e o raycaster.

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

Aqui, temos nossa própria entidade para controlar o Oculus Go, bem como uma para o raycaster, que será executado a cada 100 milissegundos.

Agora vamos modificar o componente sintetizador para controlar o Oculus. Fazemos isso adicionando o raycaster, dependendo do nosso componente.

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

Em seguida, no método init , altere o EventListener - ele deve rastrear o evento:
raycaster-interseção


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

O início da cena no Oculus Go agora deve mostrar seu controlador - e o controle a laser deve iniciar o sintetizador tocando notas quando você passa o mouse sobre as figuras.

Oculus go

Se você quiser dar uma olhada no projeto, execute-o e veja o código-fonte aqui - glitch.com/~space-synth-vr

Em custódia


Agora temos uma cena simples com um sintetizador de VR e há um grande número de oportunidades para melhorá-lo. Podemos adicionar mais objetos para interação, mais sintetizadores e efeitos para o componente. Podemos animar objetos com base em alguns eventos. À medida que a cena cresce, você deve pensar em desempenho. Felizmente, o A-Frame possui muitos recursos internos que podem ajudar com esse problema.

Aqui estão alguns links úteis Raycaster

Components Interaction and Control Tone.js. Código-fonte do projeto Obrigado por ler.






All Articles