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