Créez une scène de base dans A-Frame



De l'auteur de la traduction: dans l'article précédent, nous avons discuté des concepts de base d'A-Frame. Pour continuer le cycle, je voulais créer une leçon qui illustrerait les principales caractéristiques de A-Frame, mais j'ai réalisé qu'il était préférable de traduire l'article à partir du site officiel, qui, à mon avis, est très bien écrit, et il n'y a tout simplement aucun sens à répéter un tel article.

Faisons une scène de base dans A-Frame pour comprendre comment fonctionne le framework. Nous avons besoin d'une compréhension initiale du HTML. Dans cette leçon, nous apprendrons:

  • comment ajouter des objets 3D à l'aide de primitives;
  • comment transformer des objets dans un espace tridimensionnel à l'aide de mouvements, de rotations et d'échelles;
  • comment ajouter un environnement;
  • comment ajouter des textures;
  • Comment ajouter une interactivité de base via des événements et des animations
  • comment ajouter du texte.

Vous pouvez jouer avec le code ici

Commençons par HTML


<html> <head> <script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script> </head> <body> <a-scene> </a-scene> </body> </html> 

Nous connectons le cadre A via la balise <script> ajoutée à la section <head>. Le code de la bibliothèque se trouve sur le CDN. Une connexion A-Frame doit être ajoutée avant <a-scene> car A-Frame enregistre des éléments HTML personnalisés qui doivent être définis avant que <a-scene> ne soit ajouté au DOM, sinon la scène restera vide.

Ensuite, nous ajoutons la balise <a-scene> au corps du document <body>. <a-scène> est l'élément par lequel la scène est contrôlée. En ajoutant des éléments à <a-scene>, nous les ajoutons à la scène 3D réelle. <a-scene> est responsable de tout ce dont vous avez besoin: installe WebGL, <canvas>, caméra, lumière, rendu (tiroir), ainsi que tout ce qui concerne la prise en charge de WebVR sur des plates-formes telles que HTC Vive, Oculus Rift, Samsung GearVR, Oculus Go et Google Cardboards.

Ajouter des objets


En utilisant <a-scene>, nous ajoutons des objets 3D en utilisant des primitives A-Frame standard, par exemple <a-box>. Nous pouvons utiliser <a-box> comme un élément HTML standard, en y ajoutant des attributs pour la personnalisation. Voici quelques autres primitives standard disponibles dans A-Frame: <a-cylinder>, <a-plane>, <a-sphere>.

Dans l'exemple de code suivant, nous allons ajouter une couleur <a-box>. Plus d'attributs pour <a-box> peuvent être trouvés ici .



Il convient de noter que les primitives dans A-Frame ne sont que des wrappers pour certains composants. C'est pratique, mais vous devez comprendre que sous <a-box> se trouve <a-entity> avec la géométrie et les composants de matériau:

 <a-entity id="box" geometry="primitive: box" material="color: red"></a-entity> 

Dans tous les cas, puisque la caméra et le cube ajoutés à la scène sont au même point 0,0,0 , nous ne pourrons pas voir le cube tant que nous n'aurons pas changé sa position. Pour ce faire, c'est assez simple: il vous suffit de changer l'attribut position pour déplacer notre cube dans l'espace.

Transformez un objet en 3D


Parlons d'abord de l'espace 3D. A-Frame utilise un système de coordonnées droitier. La direction par défaut de la caméra est: l'axe X positif va vers la droite, l'axe Y positif monte et l'axe Z positif revient de l'écran vers nous:



A-Frame mesure la distance en mètres (pas les pixels comme dans React360) car l'API WebVR renvoie les données de position et de pose en mètres. Lorsque vous concevez une scène VR, il est très important de prendre en compte les tailles réelles des objets. Un cube d'une hauteur de 10 mètres peut sembler normal sur les écrans de nos ordinateurs, mais il sera trop massif lorsqu'il sera immergé dans la réalité virtuelle.

Les unités de rotation A-Frame sont des degrés (pas des radians comme dans Three.js), donc elles seront automatiquement converties en radians quand elles atteindront Three.js. La règle de droite est utilisée pour déterminer le sens de rotation positif. Pointez le doigt de la main droite le long de la direction positive de n'importe quel axe, puis la direction dans laquelle nos doigts sont pliés et sera le sens de rotation positif.

Pour déplacer, faire pivoter ou mettre à l'échelle notre cube, nous pouvons modifier la position , la rotation et les composants d' échelle (représentés par les attributs de la balise <a-box>), respectivement. Commençons par appliquer la rotation et la mise à l'échelle:

 <a-scene> <a-box color="red" rotation="0 45 45" scale="2 2 2"></a-box> </a-scene> 

Cela devrait faire tourner notre cube à des angles donnés et l'étirer deux fois dans tous les axes.

Transformation des ancêtres et des descendants


Le graphique de scène dans A-Frame est implémenté en HTML. Chaque élément d'une telle structure peut avoir plusieurs descendants et un seul ancêtre. Tout descendant dans une telle structure hérite des propriétés de transformation (position, rotation, échelle) de son ancêtre.

Par exemple, nous pouvons ajouter une sphère en tant que descendant d'un cube:

 <a-scene> <a-box position="0 2 0" rotation="0 45 45" scale="2 4 2"> <a-sphere position="1 0 3"></a-sphere> </a-box> </a-scene> 

La position de la sphère sur la scène sera 1 2 3 , pas 1 0 3 , car par défaut la sphère est dans les coordonnées de son ancêtre, c'est-à-dire que le cube est 0 2 0 . Ce point dans ce cas sera un point de référence pour une sphère qui a ses coordonnées 1 0 3 . Il en va de même pour la rotation et l'échelle. Si l'un des attributs du cube est modifié, cette modification affectera automatiquement tous les descendants (dans notre cas, la portée).

Si nous ajoutions un cylindre comme descendant d'une sphère, les transformations du cylindre seraient calculées en fonction des transformations de ses ancêtres: le cube et la sphère.

Nous plaçons notre cube devant la caméra


Rendons maintenant notre cube visible à notre caméra. Nous pouvons déplacer notre cube de 5 mètres dans l'axe Z dans le sens négatif (c'est-à-dire loin de nous). Levons-le également de deux mètres sur l'axe Y. Tout cela peut être fait en modifiant l'attribut position:

 <a-scene> <a-box color="red" position="0 2 -5" rotation="0 45 45" scale="2 2 2"></a-box> </a-scene> 

Maintenant on le voit! Yuhu!



La gestion


Pour les écrans plats (ordinateurs portables, ordinateurs), la caméra est contrôlée par défaut en faisant glisser la souris et le WASD ou les flèches sur le clavier. Dans les téléphones, l'accéléromètre en est responsable. Malgré le fait que A-Frame est un cadre pour WebVR, il prend en charge ces schémas de contrôle afin que la scène puisse être visualisée sans casque de réalité virtuelle.



Si vous utilisez un casque de réalité virtuelle, le contrôle sera effectué à l'aide de contrôleurs et d'un casque. Pour entrer dans la réalité virtuelle depuis le navigateur de votre casque, vous devez cliquer sur l'icône avec l'image du casque de réalité virtuelle, qui se trouve dans le coin inférieur droit. Si vous utilisez un casque à 6 degrés de liberté et que vous disposez d'un espace réel, vous pouvez vous promener physiquement autour de la scène que vous avez créée.

Ajouter un environnement


A-Frame permet aux développeurs de créer et de partager des composants qui sont ensuite faciles à utiliser dans leurs projets. Le composant environnement créé par Diego Gobern génère divers environnements et tout cela est réalisé avec une seule ligne de code! Le composant environnement est un moyen simple et efficace de créer une plate-forme visuelle pour nos applications BP. Il vous permet de créer des dizaines d'environnements, personnalisables par un grand nombre de paramètres.

Vous devez d'abord connecter le script à la section après le cadre A:

 <head> <script src="https://aframe.io/releases/0.8.0/aframe.min.js"></script> <script src="https://unpkg.com/aframe-environment-component/dist/aframe-environment-component.min.js"></script> </head> 

Après cela, déjà dans la scène, vous devez ajouter la balise <a-entity> avec l'attribut d'environnement et les paramètres spécifiés, que ce soit une forêt (forêt) avec 200 arbres:

 <a-scene> <a-box color="red" position="0 2 -5" rotation="0 45 45" scale="2 2 2"></a-box> <!-- ,   ! --> <a-entity environment="preset: forest; dressingAmount: 200"></a-entity> </a-scene> 

Remarque : gardez à l'esprit que lorsque vous utilisez du «fer» faible, une telle scène peut ralentir. Par exemple, cela peut se produire sur des appareils mobiles comme Oculus Go. Donc, si vous prenez en charge les appareils mobiles, gardez un œil sur le nombre d'objets générés.

Appliquer des textures


Nous pouvons appliquer une texture à notre cube en utilisant une image, une vidéo ou un canevas en utilisant l'attribut src, tout comme nous le faisons avec une balise régulière. Nous devons également supprimer color = "red" car la couleur ne sera toujours pas affichée lors de l'utilisation de la texture.

 <a-scene> <a-box src="https://i.imgur.com/mYmmbrp.jpg" position="0 2 -5" rotation="0 45 45" scale="2 2 2"></a-box> <a-sky color="#222"></a-sky> </a-scene> 

Maintenant, nous devrions déjà voir notre cube avec la texture chargée en ligne.


Nous utilisons le système de téléchargement de fichiers


Pour améliorer les performances de votre application A-Frame, nous vous recommandons d'utiliser le système de gestion de téléchargement de fichiers . Ce système permet au navigateur de mettre en cache différents fichiers (images, vidéos, modèles 3D). A-Frame est responsable de s'assurer que tous ces fichiers sont téléchargés avant le rendu.

Si nous écrivons une balise dans <a-assets>, A-Frame ne l'affichera pas comme dans le code HTML habituel, il traitera la source et l'enverra à Three.js. Il est important de noter qu'une fois que nous téléchargeons une image, nous pouvons l'utiliser n'importe où, par exemple, comme texture. A-Frame prendra également en charge les problèmes interdomaines et autres problèmes éventuels liés au transfert de fichiers sur le réseau.

Pour utiliser le système de contrôle de téléchargement de fichiers pour ajouter de la texture, vous devez:

  • Ajoutez la balise <a-assets> à l'intérieur de la balise <a-scene> (au premier niveau)
  • Ajoutez la balise <img> , l'attribut src doit contenir le lien du fichier image (ainsi que dans le HTML habituel)
  • Vous devez définir l'attribut id pour la balise img. Idéalement, il devrait décrire la texture elle-même (par exemple, id = ”boxTexture”)
  • Ajoutez l'attribut src pour l'objet qui doit le contenir. Par exemple, pour <a-box src = "# boxTexture">

 <a-scene> <a-assets> <img id="boxTexture" src="https://i.imgur.com/mYmmbrp.jpg"> </a-assets> <a-box src="#boxTexture" position="0 2 -5" rotation="0 45 45" scale="2 2 2"></a-box> <a-sky color="#222"></a-sky> </a-scene> 

Créer un environnement arbitraire


Nous avons déjà parlé du composant environnement ci-dessus. Il est généré automatiquement. Mais que faire si nous devons créer notre propre environnement: ajouter des nuages, de la terre, d'autres objets? Je propose d'en parler davantage.

Ajoutez une image d'arrière-plan pour la scène.


Afin d'ajouter une image d'arrière-plan pour une scène dans A-Frame, il existe un élément spécial <a-sky> . <a-sky> vous permet d'ajouter à la fois des couleurs pures et 360 images ou vidéos. Par exemple, pour ajouter un fond gris foncé, vous devez écrire le code suivant:

 <a-scene> <a-box color="red" position="0 2 -5" rotation="0 45 45" scale="2 2 2"></a-box> <a-sky color="#222"></a-sky> </a-scene> 

Ou nous pouvons utiliser une photo 360:

 <a-scene> <a-assets> <img id="boxTexture" src="https://i.imgur.com/mYmmbrp.jpg"> <img id="skyTexture" src="https://cdn.aframe.io/360-image-gallery-boilerplate/img/sechelt.jpg"> </a-assets> <a-box src="#boxTexture" position="0 2 -5" rotation="0 45 45" scale="2 2 2"></a-box> <a-sky src="#skyTexture"></a-sky> </a-scene> 

Ajouter du sol


Pour ajouter du terrain, nous utiliserons l'élément <a-plane>. Par défaut, les plans du cadre A sont orientés parallèlement à l'axe XY. Pour rendre le plan parallèle à la terre, nous devons le faire pivoter de façon à ce qu'il soit parallèle à l'axe XZ. Cela peut être fait en tournant le plan de -90 ° le long de l'axe X.

 <a-plane src="#groundTexture" rotation="-90 0 0" width="30" height="30" repeat="10 10"></a-plane> 

Travailler sur la lumière


Pour changer l'éclairage de notre scène, nous pouvons ajouter ou reconfigurer l'élément <a-light> . Par défaut, nous n'avions aucune source de lumière, mais le cadre A lui-même ajoute de la lumière ambiante et de la lumière directionnelle. Si A-Frame n'ajoutait pas ces sources de lumière, la scène serait complètement noire. Si nous ajoutons nos propres sources de lumière, les sources que A-Frame ajoute par défaut seront supprimées.

Nous ajouterons une source de lumière diffuse, qui aura une teinte vert bleuâtre (pour s'harmoniser avec le ciel). La lumière diffusée devrait tomber sur tous les éléments de notre scène (bien sûr, s'ils auront des matériaux, mais par défaut c'est le cas).

Nous ajouterons également une source lumineuse ponctuelle. Une source lumineuse ponctuelle est comme une ampoule. L'effet d'éclairage d'une telle source dépendra entièrement de la distance à l'objet.

 <a-scene> <a-assets> <img id="boxTexture" src="https://i.imgur.com/mYmmbrp.jpg"> <img id="skyTexture" src="https://cdn.aframe.io/360-image-gallery-boilerplate/img/sechelt.jpg"> <img id="groundTexture" src="https://cdn.aframe.io/a-painter/images/floor.jpg"> </a-assets> <a-box src="#boxTexture" position="0 2 -5" rotation="0 45 45" scale="2 2 2"></a-box> <a-sky src="#skyTexture"></a-sky> <a-light type="ambient" color="#445451"></a-light> <a-light type="point" intensity="2" position="2 4 4"></a-light> </a-scene> 

Ajouter une animation


Nous avons la possibilité d'ajouter une animation en utilisant le système d' animation intégré A-Frame. L'animation change une certaine valeur (propriété du composant) au fil du temps. Nous avons juste besoin d'ajouter l'élément <a-animation> en tant que descendant d'un objet, par exemple <a-box>. Essayons d'animer le cube pour qu'il se déplace de haut en bas.

 <a-scene> <a-assets> <img id="boxTexture" src="https://i.imgur.com/mYmmbrp.jpg"> </a-assets> <a-box src="#boxTexture" position="0 2 -5" rotation="0 45 45" scale="2 2 2"> <a-animation attribute="position" to="0 2.2 -5" direction="alternate" dur="2000" repeat="indefinite"></a-animation> </a-box> </a-scene> 

Nous disons <a-animation>:

  • Ce dont vous avez besoin pour animer l'attribut position.
  • Animez à 0 2,2 -5, soit 20 centimètres au-dessus de la position d'origine.
  • Modifiez la direction de l'animation à chaque cycle.
  • La boucle d'animation prendra 2 secondes (2000 millisecondes).
  • Répétez l'animation à l'infini.


Détails supplémentaires


<a-animation> utilise le cycle de rendu A-Frame, donc chaque changement dans les propriétés d'un objet se produit une fois par image. Si vous avez besoin de plus de contrôle et souhaitez modifier les valeurs manuellement, vous pouvez écrire un composant A-Frame avec un rappel de tick et une bibliothèque telle que Tween.js (qui est d'ailleurs disponible via le lien AFRAME.TWEEN). Pour de meilleures performances, les opérations image par image doivent être effectuées au niveau A-Frame, vous n'avez pas besoin de créer votre propre fonction requestAnimationFrame lorsque l'A-Frame l'a déjà .

Ajoutez de l'interactivité


Ajoutons la possibilité d'interagir avec notre cube: lorsque nous le regardons, nous augmenterons sa taille, et lorsque vous cliquez dessus, il défilera autour de son axe.

En supposant que la plupart des développeurs ne disposent pas de casques VR avec contrôleurs, nous nous concentrerons sur l'utilisation du composant de base pour l'entrée sur les ordinateurs et les appareils mobiles - le curseur . Le curseur offre la possibilité de «cliquer» sur un objet via des conseils pour les appareils mobiles et des clics de souris pour les ordinateurs. Mais vous devez comprendre que le curseur n'est qu'une des façons d'interagir, tout sera un peu différent si nous avons de vrais contrôleurs VR.

Pour attacher le curseur à la caméra, nous devons l'ajouter en tant que descendant à l'élément caméra (<a-camera>).

Comme nous n'avons pas encore identifié l'appareil photo, A-Frame l'a fait automatiquement. mais comme nous devons ajouter un curseur à la caméra, nous allons définir <a-camera> manuellement et y ajouter <a-cursor>:

 <a-scene> <a-assets> <img id="boxTexture" src="https://i.imgur.com/mYmmbrp.jpg"> </a-assets> <a-box src="#boxTexture" position="0 2 -5" rotation="0 45 45" scale="2 2 2"> <a-animation attribute="position" to="0 2.2 -5" direction="alternate" dur="2000" repeat="indefinite"></a-animation> </a-box> <a-camera> <a-cursor></a-cursor> </a-camera> </a-scene> 

Si nous regardons la documentation du curseur , nous voyons qu'il gère les événements de survol tels que mouseenter, mouseleave et également l'événement click.

Composant écouteur d'événements


Une façon de gérer les événements de curseur consiste à ajouter un écouteur d'événements via JavaScript comme pour un élément normalement DOM. Si vous n'êtes pas sûr de votre connaissance de JavaScript, vous pouvez ignorer cette section jusqu'à la suivante.

En JavaScript, nous obtenons l'élément via querySelector, en utilisant addEventListener et setAttribute pour augmenter la taille du cube en survol. Remarque: A-Frame modifie setAttribute afin qu'il puisse fonctionner avec plusieurs composants à la fois. Nous pouvons ajouter {x, y, z} comme deuxième argument.

 <script> var boxEl = document.querySelector('a-box'); boxEl.addEventListener('mouseenter', function () { boxEl.setAttribute('scale', {x: 2, y: 2, z: 2}); }); </script> 

Mais un moyen plus rapide serait d'encapsuler la logique à l'intérieur du composant A-Frame. Cette méthode ne nécessite pas d'attendre le chargement de la scène, nous n'avons pas besoin d'utiliser des sélecteurs car le composant nous donne le contexte:

 <script> AFRAME.registerComponent('scale-on-mouseenter', { schema: { to: {default: '2.5 2.5 2.5'} }, init: function () { var data = this.data; this.el.addEventListener('mouseenter', function () { this.setAttribute('scale', data.to); }); } }); </script> 

Nous pouvons ajouter ce composant via l'attribut HTML:

 <script> AFRAME.registerComponent('scale-on-mouseenter', { // ... }); </script> <a-scene> <!-- ... --> <a-box src="#boxTexture" position="0 2 -5" rotation="0 45 45" scale="2 2 2" scale-on-mouseenter="to: 2.2 2.2 2.2"> <a-animation attribute="position" to="0 2.2 -5" direction="alternate" dur="2000" repeat="indefinite"></a-animation> </a-box> <!-- ... --> </a-scene> 

Animation d'événement


<a-animation> a la capacité de démarrer et de terminer son animation lorsqu'un objet produit un événement. Cela peut être fait via l'attribut begin en spécifiant le nom de l'événement.

Nous pouvons ajouter deux animations pour le composant curseur - les événements mouseenter et onemouseleave pour redimensionner notre cube, et une pour faire pivoter le cube autour de l'axe Y par l'événement click:

 <a-box color="#FFF" width="4" height="10" depth="2" position="-10 2 -5" rotation="0 0 45" scale="2 0.5 3" src="#texture"> <a-animation attribute="position" to="0 2.2 -5" direction="alternate" dur="2000" repeat="indefinite"></a-animation> <!-- These animations will start when the box is looked at. --> <a-animation attribute="scale" begin="mouseenter" dur="300" to="2.3 2.3 2.3"></a-animation> <a-animation attribute="scale" begin="mouseleave" dur="300" to="2 2 2"></a-animation> <a-animation attribute="rotation" begin="click" dur="2000" to="360 405 45"></a-animation> </a-box> 

Ajouter de l'audio


L'audio est très important pour une immersion complète dans la réalité virtuelle. Même l'ajout d'un bruit blanc à l'arrière-plan peut prendre un certain temps. Nous vous recommandons d'utiliser le son pour chaque scène. Une façon d'ajouter du son: ajoutez l'élément <audio> à <a-assets> et l'attribut autoplay:

 <a-scene> <a-assets> <audio src="https://cdn.aframe.io/basic-guide/audio/backgroundnoise.wav" autoplay preload></audio> </a-assets> <!-- ... --> </a-scene> 

Ou nous pouvons ajouter de l'audio spatial en utilisant l'élément <a-sound>. Ce composant rend le son plus fort lorsque nous nous rapprochons de la source. Nous pouvons positionner <a-sound> en utilisant l'attribut position:

 <a-scene> <!-- ... --> <a-sound src="https://cdn.aframe.io/basic-guide/audio/backgroundnoise.wav" autoplay="true" position="-3 1 -4"></a-sound> <!-- ... --> </a-scene> 

Ajouter du texte


Un cadre a un composant texte. Il existe plusieurs façons de l'afficher et chaque méthode a ses avantages et ses inconvénients. A-Frame a une implémentation SDF à travers trois-bmfont-text qui est assez productive.

Pour cette leçon, nous vous suggérons d'utiliser la forme de texte la plus simple, <a-text>:

 <a-text value="Hello, A-Frame!" color="#BBB" position="-0.9 0.2 -3" scale="1.5 1.5 1.5"></a-text> 

Il existe d'autres façons d'ajouter du texte:

  • Géométrie du texte réalisée par Kevin Ngo. Il s'agit de texte 3D et il nécessite plus de ressources pour le rendu.
  • HTML Shader fait par Mayo Tobit - il rend le texte sous forme de texture. Il est facile à coiffer mais à calculer longtemps.

Conclusion


Vous pouvez jouer avec le code ici . Vous pouvez regarder la scène en temps réel ici .

De l'auteur du premier: Merci à tous pour votre attention! Dans le prochain article, je vais essayer de parler de mon expérience dans la création d'un jeu sur A-Frame: de toutes les subtilités et difficultés qui m'attendaient dans le processus de développement.

Source: https://habr.com/ru/post/fr440694/


All Articles