Image de couverture de l'article Débuter en réalité virtuelle mobile sur le web avec THREE.js
Retour aux articles

L'agence

WanadevStudio

Débuter en réalité virtuelle mobile sur le web avec THREE.js

Créer une application en réalité virtuelle pour le web mobile est une chose tout a fait accessible mais pourtant assez méconnue. Je vous propose de démystifier tout ça en créant votre propre appli web VR mobile !

Lors de précédents articles nous avons abordé le sujet de la réalité virtuelle sur le web d'un point de vue théorique, aujourd'hui je vous propose de passer à la pratique en créant une petite application mobile à utiliser avec un casque de réalité virtuelle, type Homido, Samsung Gear VR ou encore Google Cardboard !

J'attire votre attention sur le fait qu'une application en réalité virtuelle est plus consommatrice qu'une application classique, que ce soit en terme de puissance nécessaire que d’énergie, ainsi, il faudra vous munir d'un mobile récent et suffisamment puissant. La configuration moyenne devra être architecturée autour d'un processeur à quatre cœurs, un bon GPU, 2 go de ram et enfin un écran allant de 4.5 à 6 pouces.

La VR comment ça marche ?

La réalité virtuelle permet d'obtenir une immersion impressionnante en donnant à l'utilisateur une sensation de profondeur. La première chose que l'on se dit en rentrant dans un monde virtuel est qu'on pourrait presque toucher les éléments du décors. Pour avoir cette sensation il faut avoir recourt à une projection stéréo de la scène sur un écran. Une projection par oeil, donc. Le casque que vous utilisez ensuite contient des lentilles spécifiques qui permettront de voir la scène en 3D correctement. Donc techniquement, on utilise deux caméras avec des réglages différents mais qui vont rendre la même scène.

Une scène en réalité virtuelle Une scène en réalité virtuelle

Ensuite il y a ce deuxième aspect magique qu'est le Head Tracking (le suivi des mouvements de la tête). Il y a plusieurs méthodes pour suivre les mouvements de la têtes. La plus efficace est d'utiliser le gyroscope et l’accéléromètre conjointement afin de déterminer la bonne rotation à appliquer aux caméras. Ce point est important car si votre mobile n'a pas de gyroscope alors le HeadTracking sera absent. Il est cependant possible de n'utiliser que l’accéléromètre mais dans ce cas le suivis sera nettement moins précis.

Maintenant que nous avons vue la théorie, passons à la pratique avec un peu de code !

Mise en place du projet

Ce tutoriel est basé sur le Framework THREE.js qui propose d'excellentes bibliothèques pour mettre en place une application VR. Pour suivre ce premier tutoriel vous allez avoir besoin de la dernière version de THREE.js ainsi que d'autres scripts disponibles sur le dépôt github du projet. Commençons avec three.min.js qui contient les sources du moteur ; StereoEffect.js est un helper permettant d'avoir ce fameux rendu stéréoscopique ; DeviceOrientationControls.js est un script de contrôle de la caméra utilisé pour le HeadTracking ; Enfin, OrbitControls.js ne servira que sur PC afin de pouvoir déplacer la caméra avec la souris.

Une fois que vous avez récupéré tout ces scripts, il faut créer une page web avec le code suivant dedans :

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, user-scalable=no/>
    <title>VR Sandbox 3D</title>
    <style>
        body {
        margin: 0; padding: 0; overflow: hidden;
    }

    #container {
            width: 100%; height: 100%;
    }
    </style>
</head>
<body>
    <div id="container"></div>
    <script src="js/vendors/three.js"></script>
    <script src="js/vendors/StereoEffect.js"></script>
    <script src="js/vendors/DeviceOrientationControls.js"></script>
    <script src="js/vendors/OrbitControls.js"></script>
    <script>
        var renderer, camera, scene,
            viewController, stereoEffect,
            clock, container;

        function initialize() { }

        function createScene() { }

        function resize() { }

        function loop() { }

        // Entry point
        window.onload = function () {
            initialize();
            createScene();
            loop();
        };
    </script>
</body>
</html>

Si vous avez déjà travaillé avec THREE.js alors vous connaissez déjà un tas de choses. Je vais cependant expliquer rapidement à quoi vont nous servir toutes ces variables, si vous savez déjà tout ça alors vous pouvez passer à la suite.

Le but primaire d'une application 3D est d'afficher une scène à l'écran avec un point de vue particulier. Ainsi nous avons besoin d'une Scene contenant toutes les instances 3D,  d'une Caméra qui définie le point de vue et enfin d'un Renderer qui dessine le tout sur votre écran (c'est une sorte de boite magique dans laquelle vous trouverez des références étranges comme BackBuffer, Shader ou encore Death Depth Buffer ;) ).

Transformer une scène 3D classique en scène VR est relativement simple mais pas automatique avec THREE.js, il suffit grossièrement de rendre la scène deux fois via deux caméras en prenant en compte certains paramètres comme l'écartement entre les deux yeux, le FOV (champs de vision), etc... Il n'y a absolument rien d'autre à faire. Le HeadTracking est quant-à lui assuré par l’événement JavaScript deviceorientation qui renvoie 3 coordonnées alpha, beta et gamma représentant l'accélération du mobile dans l'espace. À partir de ces données il est possible de détecter les mouvements de la tête sur les 3 axes de rotation et les appliquer à la caméra principale.

Nous allons commencer par peupler la fonction initialize en créant les instances utiles au bon fonctionnement d'une application avec THREE.js

renderer = new THREE.WebGLRenderer();
renderer.autoClear = false;
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xffffff, 1);

// Add the canvas into the DOM
container = document.getElementById("container");
container.appendChild(renderer.domElement);

// The camera
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 5000);
camera.position.set(0, 50, 0);

// The scene
scene = new THREE.Scene();

Vous noterez qu'on passe le flag autoClear à false de l'objet WebGLRenderer, c'est très important de garder ça en tête pour la suite. Ensuite il faut mettre en place les doubles caméras en utilisant StereoEffect

stereoEffect = new THREE.StereoEffect(renderer);

Une ligne suffit à mettre en place la gestion de deux caméras. Il faut aussi savoir que tous les changements réalisés sur la caméra principale, celle que vous avez déclaré au début, seront appliqués aux deux caméras créées par l'effet. Donc de notre côté c'est totalement transparent, on joue sur la caméra principale et c'est tout ;) . Maintenant il faut ajouter le contrôleur de Head Tracking qui permettra de faire les rotations de la caméra en fonction des mouvement de la tête. Par défaut nous développons et testons sur PC donc dans un soucis de facilité, nous mettrons aussi en place un contrôleur de type Orbit. Si un évènement de rotation d'écran est détecté alors on basculera automatiquement sur le contrôleur de Head Tracking.

viewController = new THREE.OrbitControls(camera, renderer.domElement);
viewController.rotateUp(Math.PI / 4);
viewController.target.set(camera.position.x + 0.1, camera.position.y, camera.position.z);

clock = new THREE.Clock();

resize();

var onOrientationChanged = function (event) {
    if (!event.alpha) {
        return;
    }

    viewController = new THREE.DeviceOrientationControls(camera, true);
    viewController.connect();
    viewController.update();
    resize();

    window.removeEventListener("deviceorientation", onOrientationChanged);
};

window.addEventListener("deviceorientation", onOrientationChanged, false);
window.addEventListener("resize", resize, false);

Et pour terminer il faut rendre la scène dans une boucle infinie à 60 FPS, ici on ne va pas utiliser la fonction render de l'objet WebGLRenderer, mais celle de l'effet stéréo. C'est assez simple à comprendre en réalité car c'est lui qui gère les deux caméras chargées de rendre la scène.

function loop() {
    requestAnimationFrame(loop);
    viewController.update(clock.getDelta());
    stereoEffect.render(scene, camera);
}

Il ne reste plus qu'à implémenter la fonction createScene avec ce que vous voulez, pour ma part j'ai crée une SkySphere, un sol et quelques cubes...

Une SkySphere, un sol et des cubesUne SkySphere, un sol et des cubes

Utilisation de l'API Fullscreen Utilisation de l'API Fullscreen pour renforcer l'immersion et surtout supprimer la barre d'adresse !

Vous pouvez télécharger l'intégralité du code ici. Une fois votre scène en place vous pouvez l'afficher dans votre navigateur PC et mobile !

En route pour de nouvelles aventures !

Nous avons vu que créer une application VR avec THREE.js était à la portée de tous, il faut simplement utiliser l'effet stéréoscopique proposé sur le dépôt et enfin ajouter un contrôleur de Head Tracking, lui aussi disponible dans les sources du Framework. De là vous pouvez commencer à créer des expérience web multimédia intéressantes mais faites bien attention car une application VR va plus consommer étant donné que la scène est rendue deux fois !

Il faudra aussi faire attention à la partie UI qui doit elle aussi être présente en double... Ce n'est pas évident à gérer mais avec de la pratique vous verrez que l'on s'en sort quand même :)

Il y a maintenant des petites choses à faire en plus pour rendre l'expérience plus agréable. Déjà il est possible de proposer à l'utilisateur de passer en mode plein écran, ce qui aura pour effet de masquer la barre de navigation sur mobile, permettant une meilleure immersion. Par défaut l'utilisateur n'a aucun moyen de se déplacer mais il est tout à fait possible d'utiliser un clavier ou une souris en bluetooth ou en USB et de mettre au point un contrôleur de déplacement adapté à vos besoins (FPS, TPS, etc...).

Nous sommes impatients de voir et d'essayer vos applications en réalité virtuelle sur mobile ! Vous bossez sur quelque chose ? Vous avez besoin de conseils ? N'hésitez pas à laisser un petit commentaire ou si le cœur vous en dit, à venir boire un café avec nous.

Photo de Yannick Comte auteur de l'article

Yannick Comte

Commentaires

Bonjour;
très intéressant ce tuto. Je suis débutant et cette technologie me fascine énormément je veux faire de grande chose avec le VR mais je sais pas vraiment par quoi beggin…
Photo de Yannick Comte auteur du commentaire

Yannick Comte

Il y a 9 ans

Salut @Bamba

Je suis content que ce tutoriel t’ai donné envie d’aller plus loin. La première question à te poser est de savoir ce que tu veux faire ?
– Applicatif ?
– Jeu vidéo ?

Ensuite il faut déterminer sur quelle plateforme tu veux travailler : Web, Mobile, PC ?

De là tu as plusieurs outils à ta disposition. Sur le web tu as Three.js et Babylon.js qui te permettront d’utiliser l’Oculus Rift et la VR mobile. Sur mobile tu as un tas de choses possibles, mais passer par Unity est probablement la chose la plus simple. Enfin sur PC c’est comme sur mobile (Unity est recommandé ou l’Unreal Engine) mais avec un peu moins de restrictions hardware.

J’ai écris sur un autre blog un petit guide pour démarrer en VR mobile, je te recommande vivement sa lecture http://www.demonixis.net/blog/la-realite-virtuelle-sur-mobile/
De même, voici un tutoriel expliquant comment créer un grille d’hexagones avec BABYLON.js tout en ajoutant le support de la VR mobile et PC http://www.demonixis.net/blog/creer-une-grille-hexagonale-en-3d-avec-babylon-js/ .

N’hésite pas à me contacter si tu as d’autres questions.

Yannick.

Photo de Palatan Michael auteur du commentaire

Palatan Michael

Il y a 8 ans

Salut,


Merci pour le tuto ;-)

J'essaie de réaliser une app pour mon village. Reconstitution de l'entrée médiévale  par exemple. J'arrive à mes fins avec Unity. Mais je voudrais mettre un peu d'interactivité en permettant aux gamins de déclencher une audio pédagogique  d'un simple regard. Je trouve pas le script pour faire ça ;-(

Si on pouvait trouver un moyen de faire aboutir ce projet... Merci d'avance...

Mika

Photo de Yannick Comte auteur du commentaire

Yannick Comte

Il y a 8 ans

Salut,

Faire des interactions avec le regard est quelque chose de très simple sur Unity. La première chose est de placer un script sur la caméra principale et de tirer un rayon. Ensuite il faut créer un script qui va déclencher le son. Voici un morceau de code (non testé) qui devrait vous aiguiller pour mettre en place ce système.

GazeTrigger.cs

private AudioTrigger _selected = null;
public float waitForTrigger = 2.5f

void Update()
{
    RaycastHit hit;
    if (Physics.Raycast(transform.position, transform.forward, out hit)
    {
        // AudioTrigger est la classe que nous allons créer plus bas
        var audioTrigger = hit.collider.GetComponent<AudioTrigger>();
        
        if (_selected != null)
            StartCoroutine(TriggerAudio(audioTrigger);

        _selected = audioTrigger
    }
    else
        _selected = null;
}

IEnumerator TriggerAudio(AudioTrigger trigger)
{
     yield return new WaitForSeconds(waitForTrigger);

     if (trigger == _selected)
          trigger.StartAudio();

     _selected = null;
}

AudioTrigger.cs

public AudioClip clip;

public void StartAudio()
{
    AudioSource.PlayClipAtPoint(clip, transform.position);
}

Il suffit désormais de mettre AudioTrigger sur un Sprite par exemple, avec un SphereCollider ayant la case isTrigger de cochée (pour ne pas rentrer en collision avec le joueur en cas de déplacement) ;)

Si vous avez d'autres soucis, n'hésitez pas à nous contacter.

Salut @Yannick,
Super tutorial, grâce à vous je me familiarise un peu plus avec la technologie VR et three.js, et ça me donne envie de pousser mon projet un peu plus loin.

Aujourd'hui j'aimerai appliquer cette technologie à une maison 3D que j'ai dessiné, voici le lien : http://www.saidbelmir.com/output/salon_1.html comme vous pourrez le constater, vous pouvez vous déplacer dans la maison grâce aux petits yeux jaunes que vous croiserez, comme dans un jeu d'exploration en point & click.
J'aimerais reproduire la même chose en réalité virtuel. D'abord en retranscrivant tous mes panoramas sur three.js, et deuxièmement en créant des hotspots déclenchable avec le regard via une cible qui se charge.

Avez-vous des pistes à me suggérer ? D'avance je vous remercie.