TD2 - Visiocasque "en carton"

Dans ce TD vous allez intégrer votre moteur de rendu stéréo dans un visiocasque (head-mounted display). Pour cela, nous nous baserons sur un smartphone et une visionneuse de type Google Cardboard qui possède les caractéristiques suivantes :

  • distance focale des lentilles : 45 mm
  • diamètre des lentilles : 25 mm
  • distance entre les pupilles : 60 mm
  • distance entre l'écran et les lentilles : 42 mm
  • dégagement oculaire : 10 mm

1. Rendu stéréo pour le visiocasque

En vous basant sur les informations précédentes, implémentez les fonctions distanceScreenViewer et lensMagnification dans le fichier js/displayParameters.js. La première devra calculer la distance entre l'image virtuelle et l'observateur, tandis que la seconde retournera le facteur d'agrandissement. Référez-vous aux diapos de Gordon Wetzstein (Stanford University).

Ajoutez les fichiers suivants au projet : stereoRenderer.zip. En utilisant les valeurs précédentes et les dimensions physiques de l'écran de votre smartphone (n'oubliez pas de les mettre à jour dans js/displayParameters.js), implémentez la méthode update() de la classe StereoRenderer calculant les matrices de vue et de projection pour chaque œil. Comme vous avez pu le voir sur les diapos, elles sont différentes de celles utilisées pour la stéréo anaglyphe du TD1 en raison des lentilles.

Enfin, faites en sorte que le rendu pour l'œil gauche (resp. droit) s'effectue dans la moitié gauche (resp. droite) de la fenêtre à l'aide de la méthode setViewport du WebGLRenderer. Hébergez la dossier sur votre espace web du CREMI, ouvrez index.html en plein écran sur votre smartphone et chaussez le casque !

stereo

2. Correction des distorsions

Toutes les lentilles introduisent des distorsions géométriques et des aberrations chromatiques dans le champ de rayons lumineux qui les traverse. Celles produites par les lentilles de piètre qualité du Cardboard sont particulièrement prononcées. Pour améliorer la qualité de l'image, il est possible de compenser certaines distorsions géométriques en pré-déformant l'image synthétisée ; nous nous concentrerons sur les distorsion radiales en barillet représentables par le modèle de Brown-Conrady avec deux coefficients $K_1$ et $K_2$.

Pour calculer l'image pré-déformée à afficher sur l'écran, vous compléterez le fragment shader shaderUnwarp.frag. Il prend en entrée un offscreen buffer correspondant au rendu de la scène 3D, la position du centre de la lentille en coordonnées normalisées (dans $[0,1]$) et les coefficients de distorsion (vec2 K). Appliquez le modèle de Brown-Conrady pour calculer les coordonnées de texture déformées et utilisez-les pour chercher la couleur correspondante dans la texture. Contrairement à OpenGL, WebGL 1.0 ne permet pas de gérer les accès texture en dehors de $[0,1]$ ; si les coordonnées déformées sortent de cet intervalle, retournez simplement la couleur noire.

Ajustez les coefficients $K_1$ et $K_2$ jusqu'à ce que les lignes vous semblent droites sur l'ensemble de votre champ de vision.

unwarp

3. Suivi de l'orientation de l'observateur

Pour contrôler l'orientation de la caméra virtuelle, nous allons utiliser les informations fournies par l'accéléromètre et le gyroscope du smartphone. Elles sont accessibles dans le navigateur selon ces spécifications W3C ; observez en particulier les schémas pour comprendre les angles retournés. Pour vous simplifiez le travail, vous utiliserez l'encapsulation offerte par le contrôleur THREE.DeviceOrientationControls. Lisez sa méthode update() pour faire le lien avec les schémas précédents et appelez-la dans votre code.

Félicitations, vous venez de réaliser un système de réalité virtuelle bon marché !

Notez que three.js supporte le standard WebVR implémenté par certains navigateurs. En passant par cette API le rendu stéréo avec correction des distorsions et la localisation de l'observateur (en fonction du visiocasque utilisé) sont automatiquement gérés par l'API.