WebVR Partie 5 : Conception et mise en œuvre

Publié: 2022-03-11

J'adore faire en sorte que les projets soient "réalisés". Nous sommes arrivés à la fin de notre voyage - et à la naissance de notre simulation de gravité céleste en WebVR.

Dans ce dernier article, nous allons brancher notre code de simulation haute performance (articles 1, 2, 3) dans un visualiseur WebVR basé sur le visualiseur de canevas (article 4).

  1. "Problème à n corps" Intro et Architecture
  2. Les Web Workers nous procurent des threads de navigateur supplémentaires
  3. WebAssembly et AssemblyScript pour notre code de goulot d'étranglement de performance O(n²)
  4. Visualisation des données sur le canevas
  5. Visualisation de données WebVR

Il s'agit d'un article plus long, nous allons donc ignorer certains détails techniques abordés précédemment. Consultez les articles précédents si vous souhaitez une orientation, ou lisez la suite dangereusement.

Nous avons exploré le changement de paradigme du navigateur d'un environnement d'exécution JavaScript à un seul thread à un environnement d'exécution hautes performances multi-thread (travailleurs Web) (WebAssembly). Ces fonctionnalités d'informatique de bureau performante sont disponibles dans les applications Web progressives et le modèle de distribution SaaS.

Démo WebVR
Démo WebVR, exemple de code

La réalité virtuelle créera des environnements de vente et de marketing attrayants et sans distraction pour communiquer, persuader et mesurer l'engagement (suivi oculaire et interaction). Les données seront toujours des zéros et des uns, mais le résumé exécutif et l'expérience client attendus seront WebVR - tout comme nous créons aujourd'hui des expériences de tableau de bord mobile pour le Web plat.

Ces technologies permettent également l'informatique de périphérie de navigateur distribuée. Par exemple, nous pourrions créer une application Web pour exécuter nos calculs WebAssembly pour des millions d'étoiles dans une simulation. Un autre exemple est une application d'animation qui rend les créations d'autres utilisateurs pendant que vous éditez les vôtres.

Le contenu de divertissement est en tête de l'adoption de la réalité virtuelle, tout comme le divertissement mené sur mobile. Cependant, une fois que la réalité virtuelle sera normale (comme l'est aujourd'hui la conception axée sur le mobile), ce sera l'expérience attendue (conception axée sur la réalité virtuelle). C'est une période très excitante pour être concepteur et développeur - et la réalité virtuelle est un paradigme de conception complètement différent.

Vous n'êtes pas un concepteur VR si vous ne pouvez pas saisir. C'est une déclaration audacieuse, et aujourd'hui, c'est la plongée profonde dans la conception VR. Ce champ est en train d'être inventé pendant que vous lisez ceci. Mon objectif est de partager mes expériences en matière de logiciels et de films pour amorcer la conversation "VR-first design". Nous apprenons tous les uns des autres.

Avec ces prédictions grandioses à l'esprit, je voulais réaliser ce projet en tant que démo technique professionnelle - WebVR est un excellent choix pour cela !

WebVR et Google A-Frame

Le référentiel git WebVR est un fork de la version canvas pour plusieurs raisons. Cela facilite l'hébergement du projet sur les pages Github, et WebVR a nécessité quelques modifications qui auraient encombré la version canevas et ces articles.

Si vous vous souvenez de notre premier post sur l'architecture, nous avons délégué l'intégralité de la simulation à nBodySimulator .

`nBodySimulator`

Le poste de travailleur Web a montré que nBodySimulator a une fonction step() appelée toutes les 33 ms de la simulation. step() appelle calculateForces() pour exécuter notre code de simulation WebAssembly O(n²) (article 3), puis met à jour les positions et repeint. Dans notre article précédent créant une visualisation canvas, nous l'avons implémentée avec un élément canvas, à partir de cette classe de base :

 /** * Base class that console.log()s the simulation state. */ export class nBodyVisualizer { constructor(htmlElement) { this.htmlElement = htmlElement this.resize() this.scaleSize = 25 // divided into bodies drawSize. drawSize is log10(mass) // This could be refactored to the child class. // Art is never finished. It must be abandoned. } resize() {} paint(bodies) { console.log(JSON.stringify(bodies, null, 2)) } }

Définir le défi de l'intégration

Nous avons la simulation. Maintenant, nous voulons intégrer WebVR - sans ré-architecturer notre projet. Quels que soient les ajustements que nous apportons à la simulation, ils se produisent toutes les 33 ms dans le fil principal de l'interface utilisateur dans la fonction paint(bodies) .

C'est ainsi que nous mesurerons "fait". Je suis excité - mettons-nous au travail !

Comment créer une réalité virtuelle

Tout d'abord, nous avons besoin d'un dessin :

  • De quoi est faite la VR ?
  • Comment s'exprime le design WebVR ?
  • Comment pouvons-nous interagir avec lui ?

La Réalité Virtuelle remonte à la nuit des temps. Chaque histoire de feu de camp est un petit monde virtuel d'exagérations farfelues masquées par des détails insignifiants.

Nous pouvons multiplier par 10 notre histoire autour d'un feu de camp en ajoutant des éléments visuels et audio stéréoscopiques en 3D. Mon instructeur de budgétisation de la production cinématographique avait l'habitude de dire: «Nous ne payons que pour l'affiche. Nous ne construisons pas la réalité.

Si vous connaissez le DOM du navigateur, vous saurez qu'il crée une structure hiérarchique arborescente.

Un graphe scénique flat-web
Un « graphe de scène » à plat.

Implicitement dans la conception du Web, le spectateur regarde de « l'avant ». Regarder de côté révélerait les éléments DOM sous forme de lignes, et de l'arrière, nous verrions simplement la <body> car elle masque ses enfants.

Une partie de l'expérience immersive de la réalité virtuelle permet à l'utilisateur de contrôler son point de vue, son style, son rythme et l'ordre des interactions. Ils n'ont pas à faire attention à quoi que ce soit en particulier. Si vous déplacez ou faites pivoter la caméra par programme, ils vont littéralement vomir à cause du mal de la réalité virtuelle.

Veuillez noter que le mal de la réalité virtuelle n'est pas une blague. Nos yeux et nos oreilles internes détectent le mouvement. C'est très important pour un animal qui marche debout. Lorsque ces capteurs de mouvement ne sont pas d'accord, notre cerveau suppose naturellement que notre bouche a de nouveau mangé des bêtises et vomit. Nous étions tous des enfants autrefois. Beaucoup a déjà été écrit sur cet instinct de survie en réalité virtuelle. Le titre "Epic Fun" est gratuit sur Steam, et les montagnes russes sont la meilleure démo de maladie VR que j'ai trouvée.

La réalité virtuelle est exprimée sous la forme d'un « graphe de scène ». Un graphe scénique a le même motif arborescent que le DOM pour masquer les détails et la complexité d'un environnement 3D convaincant. Cependant, au lieu de faire défiler et de router, nous positionnons le spectateur là où il souhaite tirer l'expérience vers lui.

Voici le graphique de la scène Hello World du cadre WebVR A-Frame de Google :

 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Hello, WebVR! • A-Frame</title> <meta name="description" content="Hello, WebVR! • A-Frame"> <script src="https://aframe.io/releases/0.9.2/aframe.min.js"></script> </head> <body> <a-scene background="color: #FAFAFA"> <a-box position="-1 0.5 -3" rotation="0 45 0" color="#4CC3D9" shadow></a-box> <a-sphere position="0 1.25 -5" radius="1.25" color="#EF2D5E" shadow></a-sphere> <a-cylinder position="1 0.75 -3" radius="0.5" height="1.5" color="#FFC65D" shadow></a-cylinder> <a-plane position="0 0 -4" rotation="-90 0 0" width="4" height="4" color="#7BC8A4" shadow></a-plane> </a-scene> </body> </html>

Ce document HTML crée un DOM dans le navigateur. Les balises <a-*> font partie du cadre A-Frame et <a-scene> est la racine du graphe de scène. Ici, nous voyons quatre primitives 3D affichées dans la scène.

Scène A-Frame dans un navigateur Web plat
Scène A-Frame dans un navigateur Web plat.

Tout d'abord, notez que nous visualisons la scène à partir d'un navigateur Web plat. Le petit masque en bas à droite invite l'utilisateur à passer en mode stéréoscopique 3D.

Scène A-Frame en réalité virtuelle
Scène A-Frame en réalité virtuelle - une image pour chaque œil.

En théorie, vous devriez être capable de :

  1. Ouvrez ceci sur votre téléphone
  2. Tenez votre téléphone devant votre visage
  3. Délectez-vous de la splendeur d'une nouvelle réalité !

Je n'ai jamais réussi à faire fonctionner cela sans les lentilles sophistiquées d'un casque VR. Vous pouvez obtenir un casque VR pour un téléphone Android à bas prix (un appareil de base basé sur Google Cardboard), cependant, pour développer du contenu, je suggère un HMD (Head Mounted Display) autonome tel que Oculus Quest.

Tout comme la plongée sous-marine ou le parachutisme, la réalité virtuelle est un sport à engrenages.

"Cliff" d'apprentissage des concepteurs de réalité virtuelle

Réalité avec gravité et lumière
Bienvenue dans cette réalité confortable avec gravité et lumière.

Notez que la scène A-Frame Hello World a un éclairage et une caméra par défaut :

  • Les faces du cube sont de couleurs différentes - le cube s'auto-ombrage.
  • Le cube projette une ombre sur le plan - il y a une lumière directionnelle.
  • Il n'y a pas d'espace entre le cube et l'avion - c'est un monde avec gravité.

Ce sont des indices critiques qui disent au spectateur : "Détendez-vous, cette chose sur votre visage est tout à fait normale."

Notez également que cette configuration par défaut est implicite dans le code de la scène Hello World ci-dessus. A-Frame fournit judicieusement une valeur par défaut raisonnable, mais prenez note - la caméra et l'éclairage sont le gouffre que les concepteurs de Web plat doivent traverser pour créer la réalité virtuelle.

Nous prenons la configuration d'éclairage par défaut pour acquise. Par exemple, les boutons :

Boutons

Remarquez à quel point cet éclairage implicite est omniprésent dans le design et la photographie. Même le bouton "flat design" n'a pas pu échapper à l'éclairage par défaut du Web - il projette une ombre vers le bas et vers la droite.

La conception, la communication et la mise en œuvre des configurations d'éclairage et de caméra sont la falaise d'apprentissage du concepteur WebVR. Le « Langage du film » est un ensemble de normes culturelles - exprimées sous la forme de différentes configurations de caméra et d'éclairage - qui communiquent émotionnellement l'histoire au public. Les professionnels du cinéma qui conçoivent/déplacent les lumières et la caméra autour d'une scène sont le département de la préhension.

Retour à notre réalité virtuelle

Maintenant, revenons au travail. Notre scène WebVR céleste a un schéma similaire :

 <!DOCTYPE> <html> <head> <script src="https://aframe.io/releases/0.9.2/aframe.min.js"></script> <script src="https://unpkg.com/[email protected]/dist/aframe-event-set-component.min.js"></script> <script src="main.js"></script> </head> <body> <a-scene> <a-sky color="#222"></a-sky> <a-entity geometry="primitive: circle; radius: 12" position="0 0 -.5" material="color: #333; transparent: true; opacity: 0.5"> <a-sphere color="black" radius=."02"></a-sphere> </a-entity> <a-entity></a-entity> <a-entity geometry="primitive: plane; width: 2; height: auto" position="0 -10 .3" rotation="55 0 0" material="color: blue" text="value: Welcome Astronaut!..."> </a-entity> <a-entity position="0 -12 .7" rotation="55 0 0"> <a-camera> <a-cursor color="#4CC3D9" fuse="true" timeout="1"></a-cursor> </a-camera> </a-entity> </a-scene> </body> </html>

Ce document HTML charge le framework A-Frame et un plugin d'interaction. Notre scène commence à <a-scene> .

À l'intérieur, nous commençons avec un élément <a-sky color="#222"></a-sky> pour colorer en arrière-plan tout ce que nous ne définissons pas dans la scène.

Ensuite, nous créons un «plan orbital» auquel le spectateur «s'accroche» alors qu'il vole à travers notre monde étrange et inconnu. Nous créons ceci comme un disque et une petite sphère noire à (0,0,0). Sans cela, tourner me semblait "sans fondement" :

 <a-entity geometry="primitive: circle; radius: 12" position="0 0 -.5" material="color: #333; transparent: true; opacity: 0.5"> <a-sphere color="black" radius=."02"></a-sphere> </a-entity>

Ensuite, nous définissons une collection où nous pouvons ajouter/supprimer/repositionner des entités A-Frame.

 <a-entity></a-entity>

C'est la compensation pour la paint(bodies) de nBodyVisualizer pour faire son travail.

Ensuite, nous créons la relation entre le spectateur et ce monde. En tant que démo technologique, le but de ce monde est de permettre au spectateur d'explorer WebVR et la technologie de navigateur qui le permet. Un simple récit "d'astronaute" crée un sens du jeu, et ce panneau stellaire est un autre point de référence pour la navigation.

 <a-entity geometry="primitive: plane; width: 2; height: auto" position="0 -10 .3" rotation="55 0 0" material="color: blue" text="value: Welcome Astronaut!\n ..."> </a-entity>

Cela complète notre graphique de scène. Enfin, je voulais une sorte d'interaction sur une démo téléphonique entre l'utilisateur et ce monde tourmenté. Comment pouvons-nous recréer le bouton "Jeter des débris" en VR ?

Le bouton est un élément primordial de tout design moderne - où sont les boutons VR ?

Interactions en WebVR

La réalité virtuelle a ses propres « au-dessus » et « au-dessous du pli ». La première interaction d'un spectateur se fait via son avatar ou sa caméra. Ce sont toutes les commandes pour zoomer.

Si vous lisez ceci sur un ordinateur de bureau, vous pouvez utiliser WASD pour déplacer et la souris pour faire pivoter la caméra. Cette exploration révèle des informations mais n'exprime pas votre volonté.

Real Reality possède quelques fonctionnalités très importantes que l'on ne trouve pas souvent sur le Web :

  • Perspective - les objets deviennent visiblement plus petits à mesure qu'ils s'éloignent de nous.
  • Occlusion - les objets sont masqués et révélés en fonction de leur position.

VR simule ces fonctionnalités pour créer l'effet 3D. Ils peuvent également être utilisés en réalité virtuelle pour révéler des informations et une interface - et pour créer l'ambiance avant de présenter les interactions. J'ai trouvé que la plupart des gens n'avaient besoin que d'une minute pour profiter de l'expérience avant d'aller de l'avant.

Dans WebVR, nous interagissons dans l'espace 3D. Nous avons deux outils de base pour cela :

  • Collision - un événement 3D passif déclenché lorsque deux objets partagent le même espace.
  • Projection - un appel de fonction 2D actif répertoriant tous les objets croisant une ligne.

La collision est l'interaction la plus "ressemblant à la réalité virtuelle"

En réalité virtuelle, une « collision » est exactement ce à quoi cela ressemble : lorsque deux objets partagent le même espace, A-Frame crée un événement.

Pour que l'utilisateur "appuie" sur un bouton, nous devons lui donner un pion et quelque chose pour appuyer sur le bouton.

Malheureusement, WebVR ne peut pas encore assumer les contrôleurs - de nombreuses personnes regarderont une version Web plate sur leur ordinateur de bureau ou leur téléphone, et beaucoup utiliseront un casque comme Google Cardboard ou Gear VR de Samsung pour afficher une version stéréoscopique.

Si l'utilisateur n'a pas de contrôleurs, il ne peut pas tendre la main et "toucher" les choses, donc toute collision devra être avec son "espace personnel".

Nous pourrions donner au joueur un pion en forme d'astronaute pour se déplacer, mais forcer l'utilisateur dans un miasme tourbillonnant de planètes semble un peu rebutant et contraire à l'espace de notre conception.

La projection est un clic 2D "de type Web" dans un espace 3D

Outre "collision", nous pouvons également utiliser "projection". Nous pouvons projeter une ligne à travers notre scène et voir ce qu'elle touche. L'exemple le plus courant est le "rayon de téléportation".

Un rayon de téléportation trace une ligne dans le monde pour montrer où un joueur peut se déplacer. Cette "projection" cherche des endroits où atterrir. Il renvoie un ou plusieurs objets dans le chemin de la projection. Voici un exemple de rayon de téléportation :

Un rayon de téléportation dans le contenu par défaut d'Unreal Engine
Un rayon de téléportation dans le contenu par défaut d'Unreal Engine.

Notez que le rayon est en fait implémenté comme une parabole pointant vers le bas. Cela signifie qu'il se croise naturellement avec le "sol" comme un objet lancé. Cela définit également naturellement une distance de téléportation maximale. Les limites sont les choix de conception les plus importants en réalité virtuelle. Heureusement, la réalité a de nombreuses limites naturelles.

La projection "aplatit" le monde 3D en 2D afin que vous puissiez pointer sur des éléments pour cliquer dessus comme une souris. Les jeux de tir à la première personne sont des jeux élaborés de "clic 2D" sur des boutons extrêmement frustrants - souvent avec une histoire élaborée pour expliquer pourquoi ce n'est pas normal que ces boutons vous "cliquent" en retour.

Il y a tellement d'armes à feu dans la réalité virtuelle parce que les armes à feu ont été perfectionnées en tant que souris 3D précises et fiables - et cliquer est ce que les consommateurs savent faire sans apprendre.

La projection offre également la sécurité de la distance dans le rapport à la scène. N'oubliez pas que se rapprocher de quelque chose en réalité virtuelle masquera naturellement toutes les autres choses dont l'importance n'a peut-être pas encore été révélée.

Projection sans contrôleurs à l'aide du "Regard"

Pour créer cette primitive d'interaction dans WebVR sans contrôleurs, nous pouvons projeter le « regard » des téléspectateurs comme un « curseur » de ligne de visée. Ce curseur peut être utilisé par programme pour interagir avec des objets avec un "fusible". Ceci est communiqué au spectateur sous la forme d'un petit cercle bleu. Maintenant, nous cliquons !

Si vous vous souvenez des histoires de feu de camp, plus le mensonge est gros, moins il faut de détails pour le vendre. Une interaction de « regard » évidente et absurde consiste à fixer le soleil. Nous utilisons ce "regard" pour déclencher l'ajout de nouvelles planètes "débris" à notre simulation. Aucun spectateur n'a jamais remis en question ce choix - la réalité virtuelle est assez charmante lorsqu'elle est absurde.

Dans A-Frame, nous exprimons la caméra (le pion invisible des joueurs) et cette ligne de visée "curseur" comme notre gréement de caméra. Placer le <a-cursor> à l'intérieur de la <a-camera> entraîne l'application des transformations de la caméra au curseur. Lorsque le joueur déplace/tourne son pion ( a-camera ), il déplace/tourne également son regard ( a-cursor ).

 // src/index.html <a-entity position="0 -12 .7" rotation="55 0 0"> <a-camera> <a-cursor color="#4CC3D9" fuse="true" timeout="1"></a-cursor> </a-camera> </a-entity>

Le "fusible" du curseur attend qu'une seconde complète de "regard" se soit écoulée avant d'émettre un événement.

J'ai utilisé l'éclairage par défaut pour que vous remarquiez peut-être qu'il y a un "arrière" du soleil non éclairé. Bien que je ne sois pas sorti du plan orbital, je ne pense pas que ce soit ainsi que fonctionne le soleil. Cependant, cela fonctionne pour notre affiche de démonstration technologique de la réalité.

Une autre option serait de mettre l'éclairage à l'intérieur de l'élément de caméra, de sorte qu'il se déplace avec l'utilisateur. Cela créerait une expérience de mineur d'astéroïdes plus intime - et peut-être effrayante. Ce sont des choix de conception amusants.

Nous avons un plan d'intégration

Avec cela, nous avons maintenant nos points d'intégration entre l'A-Frame <a-scene> et notre simulation JavaScript :

A-Frame <a-scene> :

  • Une collection nommée pour les corps : <a-entity></a-entity>

  • Un curseur qui émettra des événements de projection : <a-cursor color="#4CC3D9" fuse="true" timeout="1"></a-cursor>

Notre simulation JavaScript :

  • nBodyVisWebVR.paint(bodies) - ajouter/supprimer/repositionner les entités VR des corps de simulation

  • addBodyArgs(name, color, x, y, z, mass, vX, vY, vZ) pour ajouter de nouveaux corps de débris à la simulation

index.html charge main.js , qui initialise notre simulation un peu comme la version canvas :

 // src/main.js import { nBodyVisualizer, nBodyVisWebVR } from ."/nBodyVisualizer" import { Body, nBodySimulator } from ."/nBodySimulator" window.onload = function() { // Create a Simulation const sim = new nBodySimulator() // this Visualizer manages the UI sim.addVisualization(new nBodyVisWebVR(document.getElementById("a-bodies"), sim)) // making up stable universes is hard // name color xyzm vz vy vz sim.addBody(new Body("star", "yellow", 0, 0, 1, 1e9)) sim.addBody(new Body("hot-jupiter", "red", -1, -1, 1, 1e4, .24, -0.05, 0)) sim.addBody(new Body("cold-jupiter", "purple", 4, 4, .5, 1e4, -.07, 0.04, 0)) // Start simulation sim.start() // Add another sim.addBody(new Body("saturn", "blue", -8, -8, .1, 1e3, .07, -.035, 0)) }

Vous remarquerez ici que nous avons défini le htmlElement du visualiseur sur la collection a-bodies pour contenir les corps.

Gestion par programme des objets A-Frame à partir de JavaScript

Après avoir déclaré notre scène dans index.html , nous sommes maintenant prêts à coder le visualiseur.

Tout d'abord, nous avons configuré nBodyVisualizer pour lire à partir de la liste des corps nBodySimulation et créer/mettre à jour/supprimer des objets A-Frame dans la collection <a-entity></a-entity> .

 // src/nBodyVisualizer.js /** * This is the WebVR visualizer. * It's responsible for painting and setting up the entire scene. */ export class nBodyVisWebVR extends nBodyVisualizer { constructor(htmlElement, sim) { // HTML Element is a-collection#a-bodies. super(htmlElement) // We add these to the global namespace because // this isn't the core problem we are trying to solve. window.sim = sim this.nextId = 0 } resize() {}

Dans le constructeur, nous sauvegardons notre collection A-Frame, définissons une variable globale pour notre événement de regard pour trouver la simulation et initialisons un compteur d'identifiants que nous utiliserons pour faire correspondre les corps entre notre simulation et la scène de A-Frame.

 paint(bodies) { let i // Create lookup table: lookup[body.aframeId] = body const lookup = bodies.reduce( (total, body) => { // If new body, give it an aframeId if (!body.aframeId) body.aframeId = `a-sim-body-${body.name}-${this.nextId++}` total[body.aframeId] = body return total }, {}) // Loop through existing a-sim-bodies and remove any that are not in // the lookup - this is our dropped debris const aSimBodies = document.querySelectorAll(."a-sim-body") for (i = 0; i < aSimBodies.length; i++) { if (!lookup[aSimBodies[i].id]) { // if we don't find the scene's a-body in the lookup table of Body()s, // remove the a-body from the scene aSimBodies[i].parentNode.removeChild(aSimBodies[i]); } } // loop through sim bodies and upsert let aBody bodies.forEach( body => { // Find the html element for this aframeId aBody = document.getElementById(body.aframeId) // If html element not found, make one. if (!aBody) { this.htmlElement.innerHTML += ` <a-sphere class="a-sim-body" dynamic-body ${ (body.name === "star") ? "debris-listener event-set__enter='_event: mouseenter; color: green' event-set__leave='_event: mouseleave; color: yellow'" : ""} position="0 0 0" radius="${body.drawSize/this.scaleSize}" color="${body.color}"> </a-sphere>` aBody = document.getElementById(body.aframeId) } // reposition aBody.object3D.position.set(body.x, body.y, body.z) }) }

Tout d'abord, nous parcourons les corps de simulation pour étiqueter et/ou créer une table de recherche pour faire correspondre les entités A-Frame aux corps de simulation.

Ensuite, nous parcourons les corps A-Frame existants et supprimons ceux qui ont été coupés par la simulation pour sortir des limites. Cela augmente la performance perçue de l'expérience.

Enfin, nous parcourons les corps de simulation pour créer un nouveau <a-sphere> pour les corps manquants et pour repositionner les autres avec aBody.object3D.position.set(body.x, body.y, body.z)

Nous pouvons modifier par programmation des éléments de la scène A-Frame à l'aide des fonctions DOM standard. Pour ajouter un élément à la scène, nous ajoutons une chaîne au innerHTML du conteneur. Ce code a un goût bizarre pour moi mais il fonctionne et je n'ai rien trouvé de mieux.

Vous remarquerez que lorsque nous créons la chaîne à ajouter, nous avons un opérateur ternaire près de "star" pour définir un attribut.

 <a-sphere class="a-sim-body" dynamic-body ${ (body.name === "star") ? "debris-listener event-set__enter='_event: mouseenter; color: green' event-set__leave='_event: mouseleave; color: yellow'" : ""} position="0 0 0" radius="${body.drawSize/this.scaleSize}" color="${body.color}"> </a-sphere>`

Si le corps est une « étoile », nous ajoutons quelques attributs supplémentaires décrivant ses événements. Voici à quoi ressemble notre étoile lorsqu'elle est montée dans le DOM :

 <a-sphere class="a-sim-body" dynamic-body="" debris-listener="" event-set__enter="_event: mouseenter; color: green" event-set__leave="_event: mouseleave; color: yellow" position="0 0 0" radius="0.36" color="yellow" material="" geometry=""></a-sphere>

Trois attributs, debris-listener , event-set__enter et event-set__leave , configurent nos interactions et constituent le dernier tour de notre intégration.

Définition des événements et des interactions A-Frame

Nous utilisons le package NPM "aframe-event-set-component" dans les attributs de l'entité pour changer la couleur du soleil lorsque le spectateur le "regarde".

Ce « regard » est une projection de la position et de la rotation du spectateur, et l'interaction fournit la rétroaction nécessaire indiquant que son regard fait quelque chose.

Notre sphère étoile a maintenant deux événements raccourcis activés par le plugin, event-set__enter et event-set__leave :

 <a-sphere ... event-set__enter="_event: mouseenter; color: green" event-set__leave="_event: mouseleave; color: yellow" … ></a-sphere>

Ensuite, nous décorons notre sphère en étoile avec un debris-listener que nous implémenterons en tant que composant A-Frame personnalisé.

 <a-sphere ... debris-listener="" … ></a-sphere>

Les composants A-Frame sont définis au niveau global :

 // src/nBodyVisualizer.js // Component to add new bodies when the user stares at the sun. See HTML AFRAME.registerComponent('debris-listener', { init: function () { // Helper function function rando(scale) { return (Math.random()-.5) * scale } // Add 10 new bodies this.el.addEventListener('click', function (evt) { for (let x=0; x<10; x++) { // name, color, x, y, z, mass, vx, vy, vz window.sim.addBodyArgs("debris", "white", rando(10), rando(10), rando(10), 1, rando(.1), rando(.1), rando(.1)) } }) } })

Ce composant A-Frame agit comme un écouteur "clic" qui peut être déclenché par le curseur de regard pour ajouter 10 nouveaux corps aléatoires à notre scène.

Résumer:

  1. Nous déclarons la scène WebVR avec A-Frame en HTML standard.
  2. Nous pouvons ajouter/supprimer/mettre à jour par programmation des entités A-Frame dans la scène à partir de JavaScript.
  3. Nous pouvons créer des interactions en JavaScript avec des gestionnaires d'événements via des plugins et des composants A-Frame.

WebVR : Veni, Vidi, Vici

J'espère que vous avez tiré autant de cette démo technologique que moi. Lorsque nous avons appliqué ces fonctionnalités (travailleurs Web et WebAssembly) à WebVR, elles peuvent également être appliquées à l'informatique de pointe du navigateur.

Une énorme vague technologique est arrivée - la réalité virtuelle (VR). Quoi que vous ayez ressenti la première fois que vous avez tenu un smartphone, l'expérience VR pour la première fois offre une expérience émotionnelle 10x dans tous les aspects de l'informatique. Cela ne fait que 12 ans depuis le premier iPhone.

La réalité virtuelle existe depuis bien plus longtemps, mais la technologie nécessaire pour apporter la réalité virtuelle aux utilisateurs moyens est arrivée via la révolution mobile et Oculus Quest de Facebook - pas la révolution PC.

Internet et l'open source comptent parmi les plus grandes merveilles du monde de l'humanité. À tous les créateurs de l'internet plat, je porte un toast à votre courage et à votre sens de l'aventure.

Manifeste! Nous construirons des mondes, car nous avons le pouvoir de créer.

Démo WebVR
Démo Canvas, Démo WebVR, Exemple de code