Quelques notions de base pour vous préparer à un large éventail d'expériences immersives: réalité virtuelle, réalité augmentée et tout ce qui se trouve entre les deux.
Les expériences immersives sont arrivées sur le Web dans Chrome 79. L'API WebXR Device offre la réalité virtuelle, tandis que la compatibilité avec la réalité augmentée arrive dans Chrome 81. Une mise à jour de l'API GamePad étend l'utilisation avancée des commandes à la VR. D'autres navigateurs seront bientôt compatibles avec ces spécifications, y compris Firefox Reality, le navigateur Oculus, Edge et le navigateur Helio de Magic Leap, entre autres.
Cet article commence une série sur le Web immersif. Cet article explique comment configurer une application WebXR de base, ainsi que comment entrer et sortir d'une session XR. Des articles ultérieurs traiteront de la boucle de frame (l'outil principal de l'expérience WebXR), des spécificités de la réalité augmentée et de l'API WebXR Hit Test, qui permet de détecter des surfaces dans une session de RA. Sauf indication contraire, tout ce que je décris dans cet article et les suivants s'applique à la fois à la RA et à la RV.
Qu'est-ce que le Web immersif ?
Bien que nous utilisions deux termes pour décrire les expériences immersives (réalité augmentée et réalité virtuelle), beaucoup les considèrent comme un spectre allant de la réalité complète à la réalité complètement virtuelle, avec des degrés d'immersion intermédiaires. La lettre X dans XR vise à refléter cette pensée en étant une sorte de variable algébrique qui représente tout dans le spectre des expériences immersives.
Voici quelques exemples d'expériences immersives:
- Jeux
- Vidéo à 360°
- Vidéos 2D (ou 3D) traditionnelles présentées dans un environnement immersif
- Achat d'un logement
- Visualiser des produits chez vous avant de les acheter
- Art immersif
- Une idée géniale que personne n'a encore eue
Concepts et utilisation
Je vais vous expliquer quelques principes de base de l'utilisation de l'API WebXR Device. Si vous avez besoin d'informations plus détaillées que celles que je vous ai fournies, consultez les exemples WebXR du groupe de travail sur le Web immersif ou les matériaux de référence croissants du MDN. Si vous connaissez les premières versions de l'API WebXR Device, vous devriez consulter l'ensemble de ces documents. Des modifications ont été apportées.
Le code de cet article est basé sur l'exemple de base du groupe de travail sur le Web immersif (démo, source), mais a été modifié pour plus de clarté et de simplicité.
La création de la spécification WebXR a consisté en partie à mettre en place des mesures de sécurité et de confidentialité pour protéger les utilisateurs. Par conséquent, les implémentations doivent respecter certaines exigences. Une page Web ou une application doit être active et en mode plein écran avant de pouvoir demander des informations sensibles à l'utilisateur. Les pages Web ou les applications doivent être diffusées via HTTPS. L'API elle-même est conçue pour protéger les informations obtenues à partir des capteurs et des caméras, dont elle a besoin pour fonctionner.
Demander une session
Pour accéder à une session XR, l'utilisateur doit effectuer un geste. Pour ce faire, utilisez la détection de fonctionnalités pour tester XRSystem
(via navigator.xr
) et appelez XRSystem.isSessionSupported()
. Notez que dans les versions 79 et 80 de Chrome, l'objet XRSystem
était appelé XR
.
Dans l'exemple ci-dessous, j'ai indiqué que je souhaite une session de réalité virtuelle avec le type de session 'immersive-vr'
. Les autres types de sessions sont 'immersive-ar'
et 'inline'
. Une session intégrée permet de présenter du contenu dans le code HTML. Elle est principalement utilisée pour les contenus teaser. L'exemple de session d'AR immersive illustre ce point. Je vous expliquerai cela dans un prochain article.
Une fois que je sais que les sessions de réalité virtuelle sont compatibles, j'active un bouton qui me permet d'acquérir un geste utilisateur.
if (navigator.xr) {
const supported = await navigator.xr.isSessionSupported('immersive-vr');
if (supported) {
xrButton.addEventListener('click', onButtonClicked);
xrButton.textContent = 'Enter VR';
xrButton.enabled = supported; // supported is Boolean
}
}
Après avoir activé le bouton, j'attends un événement de clic, puis je demande une session.
let xrSession = null;
function onButtonClicked() {
if (!xrSession) {
navigator.xr.requestSession('immersive-vr')
.then((session) => {
xrSession = session;
xrButton.textContent = 'Exit XR';
onSessionStarted(xrSession);
});
} else {
xrSession.end();
}
}
Notez la hiérarchie des objets dans ce code. Il passe de navigator
à xr
vers une instance XRSession
. Dans les premières versions de l'API, un script devait demander un appareil avant de demander une session. L'appareil est désormais acquis implicitement.
Lancer une session
Une fois que j'ai obtenu une session, je dois la démarrer et y entrer. Mais d'abord, je dois configurer quelques éléments. Une session a besoin d'un gestionnaire d'événements onend
pour que l'application ou la page Web puisse être réinitialisée lorsque l'utilisateur quitte l'application.
J'ai également besoin d'un élément <canvas>
sur lequel dessiner ma scène. Il doit s'agir d'un WebGLRenderingContext ou d'un WebGL2RenderingContext compatible avec la réalité XR.
Tous les dessins sont effectués à l'aide de ces éléments ou d'un framework basé sur WebGL tel que Three.js.
Maintenant que j'ai un espace pour dessiner, j'ai besoin d'une source de contenu à dessiner. Pour ce faire, je crée une instance de XRWebGLLayer
. Je l'associe au canevas en appelant XRSession.updateRenderState()
.
Une fois que je suis dans une session, j'ai besoin d'un moyen de déterminer où se trouvent les éléments dans la réalité virtuelle. J'ai besoin d'un espace de référence. Un espace de référence 'local-floor'
est un espace où l'origine se trouve à proximité du spectateur, où l'axe Y est à 0 au niveau du sol et où il ne doit pas bouger. Il existe d'autres types d'espaces de référence, mais c'est un sujet plus complexe que je ne peux pas aborder ici. J'enregistre l'espace de référence dans une variable, car j'en aurai besoin lorsque je dessinerai à l'écran.
function onSessionStarted(xrSession) {
xrSession.addEventListener('end', onSessionEnded);
let canvas = document.createElement('canvas');
webGLRenContext = canvas.getContext('webgl', { xrCompatible: true });
xrSession.updateRenderState({
baseLayer: new XRWebGLLayer(xrSession, webGLRenContext)
});
xrSession.requestReferenceSpace('local-floor')
.then((refSpace) => {
xrRefSpace = refSpace;
xrSession.requestAnimationFrame(onXRFrame);
});
}
Après avoir obtenu un espace de référence, j'appelle XRSession.requestAnimationFrame()
.
C'est le début de la présentation du contenu virtuel, qui se fait dans la boucle de frame.
Exécuter une boucle de frame
La boucle de frame est une boucle infinie contrôlée par l'agent utilisateur dans laquelle le contenu est dessiné à plusieurs reprises à l'écran. Le contenu est dessiné dans des blocs distincts appelés "frames". La succession d'images crée l'illusion de mouvement. Pour les applications de réalité virtuelle, le nombre d'images par seconde peut varier de 60 à 144. La RA pour Android s'exécute à 30 images par seconde. Votre code ne doit pas supposer de fréquence d'images particulière.
Le processus de base de la boucle de frame est le suivant:
- Appelez
XRSession.requestAnimationFrame()
. En réponse, l'agent utilisateur appelle leXRFrameRequestCallback
, que vous avez défini. - Dans votre fonction de rappel :
- Appelez à nouveau
XRSession.requestAnimationFrame()
. - Obtenez la position du spectateur.
- Transmettez ('liez') le
WebGLFramebuffer
duXRWebGLLayer
auWebGLRenderingContext
. - Itérez sur chaque objet
XRView
, récupérez sonXRViewport
à partir deXRWebGLLayer
et transmettez-le àWebGLRenderingContext
. - Dessinez quelque chose dans le framebuffer.
- Appelez à nouveau
Le reste de cet article décrit l'étape 1 et une partie de l'étape 2, à savoir la configuration et l'appel de XRFrameRequestCallback
. Les éléments restants de l'étape 2 sont abordés dans la partie II.
XRFrameRequestCallback
Vous définissez le XRFrameRequestCallback
. Elle utilise deux paramètres: un DOMHighResTimeStamp
et une instance XRFrame
. L'objet XRFrame
fournit les informations nécessaires pour afficher un seul frame à l'écran. L'argument DOMHighResTimeStamp
est à utiliser ultérieurement.
Avant de faire quoi que ce soit d'autre, je vais demander le frame d'animation suivant. Comme indiqué précédemment, la synchronisation des frames est déterminée par l'agent utilisateur en fonction du matériel sous-jacent. Demander d'abord le frame suivant garantit que la boucle de frame continue si un élément génère une erreur pendant le rappel.
function onXRFrame(hrTime, xrFrame) {
let xrSession = xrFrame.session;
xrSession.requestAnimationFrame(onXRFrame);
// Render a frame.
}
À ce stade, il est temps de dessiner quelque chose pour le spectateur. C'est une discussion pour la partie II. Avant d'y arriver, je vais vous montrer comment mettre fin à une session.
Mettre fin à la session
Une session immersive peut se terminer pour plusieurs raisons, y compris par votre propre code via un appel à XRSession.end()
. Le casque peut également être déconnecté ou une autre application peut le contrôler. C'est pourquoi une application bien gérée doit surveiller l'événement end
. Dans ce cas, supprimez la session et ses objets de rendu associés. Une session immersive terminée ne peut pas être reprise. Pour revenir à l'expérience immersive, mon application doit démarrer une nouvelle session.
Dans Accéder à une session, vous avez vu que j'ai ajouté un gestionnaire d'événements onend
lors de la configuration.
function onSessionStarted(xrSession) {
xrSession.addEventListener('end', onSessionEnded);
// More setup…
}
Dans le gestionnaire d'événements, restaurez l'état de l'application avant que l'utilisateur ne soit entré dans une session.
function onSessionEnded(event) {
xrSession = null;
xrButton.textContent = 'Enter VR';
}
Conclusion
Je n'ai pas tout expliqué pour écrire une application Web XR ou AR. J'espère vous avoir donné suffisamment d'informations pour commencer à comprendre le code par vous-même et à effectuer des tests. Dans l'article suivant, je vais expliquer la boucle de frame, qui est l'endroit où le contenu est dessiné à l'écran.
Photo de JESHOOTS.COM sur Unsplash