Réalité augmentée: vous le savez peut-être déjà

Si vous avez déjà utilisé l'API WebXR Device, vous y êtes presque.

Joe Medley
Joe Medley

L'API WebXR Device a été publiée l'automne dernier dans Chrome 79. Comme indiqué précédemment, l'implémentation de l'API par Chrome est en cours. Chrome est heureux d'annoncer que certains travaux sont terminés. Chrome 81 propose deux nouvelles fonctionnalités :

Cet article concerne la réalité augmentée. Si vous avez déjà utilisé l'API WebXR Device, vous serez ravi d'apprendre qu'il n'y a que très peu de nouveautés à découvrir. L'accès à une session WebXR est en grande partie identique. L'exécution d'une boucle de frame est en grande partie identique. Les différences résident dans les configurations qui permettent d'afficher le contenu de manière appropriée pour la réalité augmentée. Si vous ne connaissez pas les concepts de base de WebXR, nous vous recommandons de lire mes articles précédents sur l'API WebXR Device, ou au moins de vous familiariser avec les sujets abordés. Vous devez savoir comment demander et entrer dans une session, et vous devez savoir comment exécuter une boucle de frame.

Pour en savoir plus sur les tests de positionnement, consultez l'article associé Positionner des objets virtuels dans des vues du monde réel. Le code de cet article est basé sur l'exemple de session d'AR immersive (source de démonstration) des exemples d'API WebXR Device du groupe de travail sur le Web immersif.

Avant de plonger dans le code, vous devez utiliser l'exemple de session immersive de RA au moins une fois. Vous aurez besoin d'un téléphone Android moderne équipé de Chrome 81 ou d'une version ultérieure.

À quoi servent-elles ?

La réalité augmentée sera un ajout intéressant à de nombreuses pages Web existantes ou nouvelles, car elle leur permettra d'implémenter des cas d'utilisation de la RA sans quitter le navigateur. Par exemple, il peut aider les utilisateurs à apprendre sur des sites éducatifs et permettre aux acheteurs potentiels de visualiser des objets dans leur maison lorsqu'ils font des achats.

Prenons le deuxième cas d'utilisation. Imaginez que vous simulez le placement d'une représentation grandeur nature d'un objet virtuel dans une scène réelle. Une fois placée, l'image reste sur la surface sélectionnée, apparaît à la taille qu'elle aurait si l'élément réel se trouvait sur cette surface et permet à l'utilisateur de l'entourer, de s'en rapprocher ou de s'en éloigner. Cela permet aux spectateurs d'obtenir une compréhension plus approfondie de l'objet qu'avec une image en deux dimensions.

Je vais un peu vite. Pour réaliser ce que j'ai décrit, vous avez besoin de fonctionnalités de RA et de moyens de détecter les surfaces. Cet article concerne la première option. L'article associé sur l'API Test de positionnement WebXR (lien ci-dessus) traite de cette dernière méthode.

Demander une session

La demande d'une session est très semblable à ce que vous avez vu précédemment. Commencez par vérifier si le type de session souhaité est disponible sur l'appareil actuel en appelant xr.isSessionSupported(). Au lieu de demander 'immersive-vr' comme précédemment, demandez 'immersive-ar'.

if (navigator.xr) {
  const supported = await navigator.xr.isSessionSupported('immersive-ar');
  if (supported) {
    xrButton.addEventListener('click', onButtonClicked);
    xrButton.textContent = 'Enter AR';
    xrButton.enabled = supported; // supported is Boolean
  }
}

Comme précédemment, un bouton "Accéder à la RA" s'active. Lorsque l'utilisateur clique dessus, appelez xr.requestSession(), en transmettant également 'immersive-ar'.

let xrSession = null;
function onButtonClicked() {
  if (!xrSession) {
    navigator.xr.requestSession('immersive-ar')
    .then((session) => {
      xrSession = session;
      xrSession.isImmersive = true;
      xrButton.textContent = 'Exit AR';
      onSessionStarted(xrSession);
    });
  } else {
    xrSession.end();
  }
}

Une propriété de commodité

Vous avez probablement remarqué que j'ai mis en surbrillance deux lignes dans le dernier exemple de code. L'objet XRSession semble posséder une propriété appelée isImmersive. Il s'agit d'une propriété pratique que j'ai créée moi-même et qui ne fait pas partie de la spécification. Je l'utiliserai plus tard pour prendre des décisions sur ce que je dois montrer au spectateur. Pourquoi cette propriété ne fait-elle pas partie de l'API ? Étant donné que votre application peut avoir besoin de suivre cette propriété différemment, les auteurs des spécifications ont décidé de ne pas altérer la qualité de l'API.

Lancer une session

Rappelez-vous à quoi ressemblait onSessionStarted() dans mon article précédent :

function onSessionStarted(xrSession) {
  xrSession.addEventListener('end', onSessionEnded);

  let canvas = document.createElement('canvas');
  gl = canvas.getContext('webgl', { xrCompatible: true });

  xrSession.updateRenderState({
    baseLayer: new XRWebGLLayer(session, gl)
  });

  xrSession.requestReferenceSpace('local-floor')
  .then((refSpace) => {
    xrRefSpace = refSpace;
    xrSession.requestAnimationFrame(onXRFrame);
  });
}

Je dois ajouter quelques éléments pour prendre en compte le rendu de la réalité augmentée. Désactiver l'arrière-plan Tout d'abord, je vais déterminer si j'ai besoin de l'arrière-plan. C'est la première fois que j'utilise ma propriété de commodité.

function onSessionStarted(xrSession) {
  xrSession.addEventListener('end', onSessionEnded);

  if (session.isImmersive) {
    removeBackground();
  }

  let canvas = document.createElement('canvas');
  gl = canvas.getContext('webgl', { xrCompatible: true });

  xrSession.updateRenderState({
    baseLayer: new XRWebGLLayer(session, gl)
  });

  refSpaceType = xrSession.isImmersive ? 'local' : 'viewer';
  xrSession.requestReferenceSpace(refSpaceType).then((refSpace) => {
    xrSession.requestAnimationFrame(onXRFrame);
  });

}

Espaces de référence

Dans mes articles précédents, j'ai à peine abordé les espaces de référence. L'exemple que je décris en utilise deux. Il est donc temps de corriger cette omission.

Un espace de référence décrit la relation entre le monde virtuel et l'environnement physique de l'utilisateur. Pour ce faire:

  • Spécification de l'origine du système de coordonnées utilisé pour exprimer les positions dans le monde virtuel.
  • Indique si l'utilisateur doit se déplacer dans ce système de coordonnées.
  • Indique si ce système de coordonnées a des limites prédéfinies. (Les exemples présentés ici n'utilisent pas de systèmes de coordonnées avec des limites prédéfinies.)

Pour tous les espaces de référence, la coordonnée X indique la gauche et la droite, la coordonnée Y indique le haut et le bas, et la coordonnée Z indique l'avant et l'arrière. Les valeurs positives correspondent respectivement à la droite, à la hausse et à l'arrière.

Les coordonnées renvoyées par XRFrame.getViewerPose() dépendent du type d'espace de référence demandé. Nous y reviendrons plus tard lorsque nous aborderons la boucle de frame. Pour le moment, nous devons sélectionner un type de référence adapté à la réalité augmentée. Là encore, cette méthode utilise ma propriété de commodité.

let refSpaceType
function onSessionStarted(xrSession) {
  xrSession.addEventListener('end', onSessionEnded);

  if (session.isImmersive) {
    removeBackground();
  }

  let canvas = document.createElement('canvas');
  gl = canvas.getContext('webgl', { xrCompatible: true });

  xrSession.updateRenderState({
    baseLayer: new XRWebGLLayer(session, gl)
  });

  refSpaceType = xrSession.isImmersive ? 'local' : 'viewer';
  xrSession.requestReferenceSpace(refSpaceType).then((refSpace) => {
    xrSession.requestAnimationFrame(onXRFrame);
  });
}

Si vous avez consulté l'exemple de session d'AR immersive, vous remarquerez que la scène est initialement statique et pas du tout en réalité augmentée. Vous pouvez faire glisser votre doigt et balayer l'écran pour vous déplacer dans la scène. Si vous cliquez sur "START AR" (DÉMARRER EN RA), l'arrière-plan disparaît et vous pouvez vous déplacer dans la scène en déplaçant l'appareil. Les modes utilisent différents types d'espaces de référence. Le texte en surbrillance ci-dessus montre comment cette option est sélectionnée. Il utilise les types de références suivants :

local : l'origine se trouve dans la position de l'utilisateur au moment de la création de la session. Cela signifie que l'expérience n'a pas nécessairement un prix plancher bien défini et que la position exacte de l'origine peut varier selon la plate-forme. Bien qu'il n'y ait pas de limites préétablies pour l'espace, il est normal que le contenu soit visible sans autre mouvement que la rotation. Comme vous pouvez le voir dans notre exemple en RA, un mouvement dans l'espace peut être possible.

viewer : utilisé le plus souvent pour le contenu présenté en ligne sur la page, cet espace suit l'appareil de visionnage. Lorsqu'il est transmis à getViewerPose, il ne fournit aucun suivi et signale donc toujours une pose à l'origine, sauf si l'application le modifie avec XRReferenceSpace.getOffsetReferenceSpace(). L'exemple utilise cela pour activer le panoramique de l'appareil photo par commande tactile.

Exécuter une boucle de frame

Conceptuellement, rien ne change par rapport à ce que j'ai fait lors de la session de RV décrite dans mes articles précédents. Transmettez le type d'espace de référence à XRFrame.getViewerPose(). Le XRViewerPose renvoyé correspond au type d'espace de référence actuel. L'utilisation de viewer par défaut permet à une page d'afficher des aperçus de contenu avant que l'autorisation de l'utilisateur ne soit demandée pour la RA ou la RV. Cela illustre un point important : le contenu intégré utilise la même boucle de frame que le contenu immersif, ce qui réduit la quantité de code à gérer.

function onXRFrame(hrTime, xrFrame) {
  let xrSession = xrFrame.session;
  xrSession.requestAnimationFrame(onXRFrame);
  let xrViewerPose = xrFrame.getViewerPose(refSpaceType);
  if (xrViewerPose) {
    // Render based on the pose.
  }
}

Conclusion

Cette série d'articles porte uniquement sur les principes de base de la mise en œuvre de contenu immersif sur le Web. De nombreuses autres fonctionnalités et cas d'utilisation sont présentées dans les exemples d'API WebXR Device du groupe de travail sur le Web immersif. Nous venons également de publier un article sur les tests de positionnement qui explique une API permettant de détecter des surfaces et de placer des éléments virtuels dans une vue d'appareil photo réelle. Consultez-les et suivez le blog web.dev pour en savoir plus au cours de l'année à venir.

Photo de David Grandmougin sur Unsplash