Realtà aumentata: potresti già conoscerla

Se hai già utilizzato l'API WebXR Device, ci sei quasi.

Joe Medley
Joe Medley

L'API WebXR Device è stata fornita lo scorso autunno in Chrome 79. Come indicato in precedenza, l'implementazione dell'API da parte di Chrome è ancora in fase di sviluppo. Chrome è felice di annunciare che parte del lavoro è terminata. In Chrome 81 sono disponibili due nuove funzionalità:

Questo articolo riguarda la realtà aumentata. Se hai già usato l'API WebXR Device, sarai felice di sapere che c'è molto poco da imparare. Inserire una sessione WebXR è sostanzialmente la stessa. L'esecuzione di un loop di frame è sostanzialmente la stessa. Le differenze riguardano le configurazioni che consentono una visualizzazione appropriata dei contenuti per la realtà aumentata. Se non hai familiarità con i concetti di base di WebXR, dovresti leggere i miei post precedenti sull'API WebXR Device, o almeno avere familiarità con gli argomenti trattati. Dovresti sapere come richiedere ed entrare in una sessione e come eseguire un loop di frame.

Per informazioni sugli hit test, consulta l'articolo complementare Posizionamento di oggetti virtuali nelle visualizzazioni reali. Il codice in questo articolo si basa sull'esempio di sessione AR Immersive (demo source) degli esempi di API WebXR Device di Immersive Web Working Group.

Prima di approfondire il codice, devi utilizzare l'esempio di sessione AR immersiva almeno una volta. Devi avere un telefono Android moderno con Chrome 81 o versioni successive.

Per cosa è utile?

La realtà aumentata sarà un'aggiunta preziosa a molte pagine web nuove o esistenti, consentendo loro di implementare casi d'uso AR senza uscire dal browser. Ad esempio, può aiutare le persone a trovare informazioni sui siti didattici e consentire ai potenziali acquirenti di visualizzare gli oggetti in casa mentre fanno acquisti.

Considera il secondo caso d'uso. Immagina di simulare il posizionamento di una rappresentazione a grandezza naturale di un oggetto virtuale in una scena reale. Una volta posizionata, l'immagine rimane sulla superficie selezionata, appare delle dimensioni che avrebbe se l'elemento effettivo si trovasse su quella superficie e consente all'utente di spostarsi intorno e avvicinarsi o allontanarsi. In questo modo, gli spettatori possono capire meglio l'oggetto rispetto a un'immagine bidimensionale.

Sono un po' avanti rispetto a me. Per fare ciò che ho descritto, servono una funzionalità AR e qualche metodo per rilevare le superfici. Questo articolo riguarda il primo. L'articolo allegato sull'API WebXR Hit Test (link sopra) riguarda quest'ultimo.

Richiesta di una sessione

Richiedere una sessione è molto simile a quanto hai visto prima. Innanzitutto, scopri se il tipo di sessione che vuoi è disponibile sul dispositivo attuale chiamando il numero xr.isSessionSupported(). Invece di richiedere 'immersive-vr' come prima, richiedi '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
  }
}

Come in precedenza, è possibile attivare il pulsante "Entra in AR". Quando l'utente fa clic, chiama xr.requestSession(), trasmettendo anche '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();
  }
}

Un confortevole hotel

Probabilmente avrai notato che ho evidenziato due righe nell'ultimo esempio di codice. L'oggetto XRSession sembrerebbe avere una proprietà chiamata isImmersive. Questa è una proprietà che ho creato personalmente e non fa parte delle specifiche. La userò in seguito per decidere cosa mostrare allo spettatore. Perché questa proprietà non fa parte dell'API? Poiché l'app potrebbe dover monitorare questa proprietà in modo diverso, gli autori delle specifiche hanno deciso di mantenere l'API pulita.

Accesso a una sessione

Ricorda com'era onSessionStarted() nel mio articolo precedente:

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);
  });
}

Devo aggiungere alcuni elementi per tenere conto del rendering della realtà aumentata. Disattiva lo sfondo. Prima di tutto, stabilirò se mi serve lo sfondo. Questo è il primo posto in cui utilizzerò la mia proprietà.

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);
  });

}

Spazi di riferimento

I miei articoli precedenti passavano in rassegna gli spazi di riferimento. Nell'esempio che sto descrivendo, ne vengono usate due, quindi è il momento di correggere l'omissione.

Uno spazio di riferimento descrive la relazione tra il mondo virtuale e l'ambiente fisico dell'utente. Per farlo:

  • Specificando l'origine del sistema di coordinate utilizzato per esprimere le posizioni nel mondo virtuale.
  • Specifica se è previsto che l'utente si sposti all'interno del sistema di coordinate.
  • Indica se il sistema di coordinate ha confini prestabiliti. (Gli esempi mostrati qui non utilizzano sistemi di coordinate con confini prestabiliti.)

Per tutti gli spazi di riferimento, la coordinata X esprime verso sinistra e destra, la Y esprime verso l'alto e il basso e la Z esprime avanti e indietro. I valori positivi sono rispettivamente destra, in alto e indietro.

Le coordinate restituite da XRFrame.getViewerPose() dipendono dal tipo di spazio di riferimento richiesto. Vediamo di più quando parliamo di loop di frame. Ora dobbiamo selezionare un tipo di riferimento appropriato per la realtà aumentata. Anche in questo caso, viene utilizzata la mia proprietà di convenienza.

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);
  });
}

Se hai visitato l'esempio di sessione AR immersiva, noterai che inizialmente la scena è statica e non è affatto in realtà aumentata. Puoi trascinare e scorrere con il dito per spostarti nella scena. Se fai clic su "AVVIA AR", lo sfondo cade e puoi spostarti nella scena spostando il dispositivo. Le modalità utilizzano tipi di spazi di riferimento diversi. Il testo evidenziato sopra mostra come viene selezionata questa opzione. Utilizza i seguenti tipi di riferimento:

local. L'origine è la posizione del visualizzatore al momento della creazione della sessione. Ciò significa che l'esperienza non ha necessariamente un livello minimo ben definito e la posizione esatta dell'origine può variare a seconda della piattaforma. Sebbene non esistano limiti prestabiliti per lo spazio, si prevede che i contenuti possano essere visualizzati senza alcun movimento diverso dalla rotazione. Come puoi vedere dal nostro esempio AR, alcuni movimenti all'interno dello spazio potrebbero essere possibili.

viewer: usato più di frequente per i contenuti presentati in linea nella pagina, questo spazio segue il dispositivo di visualizzazione. Quando viene passato a getViewerPose, non fornisce alcun monitoraggio e quindi segnala sempre una posa all'origine, a meno che l'applicazione non la modifichi con XRReferenceSpace.getOffsetReferenceSpace(). Nell'esempio viene usata questa funzionalità per consentire la panoramica della fotocamera basata sul tocco.

Esecuzione di un loop di frame

A livello concettuale, non cambia nulla rispetto a quello che ho fatto nella sessione VR descritta nei miei articoli precedenti. Passa il tipo di spazio di riferimento a XRFrame.getViewerPose(). Il valore XRViewerPose restituito sarà per il tipo di spazio di riferimento corrente. L'uso di viewer come impostazione predefinita consente a una pagina di mostrare le anteprime dei contenuti prima che l'utente venga richiesto il consenso per AR o VR. Questo evidenzia un aspetto importante: i contenuti in linea utilizzano lo stesso loop di frame dei contenuti immersivi, riducendo la quantità di codice che deve essere gestita.

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

Conclusione

Questa serie di articoli tratta solo le nozioni di base sull'implementazione di contenuti immersivi sul web. Gli esempi di API del dispositivo WebXR di Immersive Web Working Group presentano molte altre funzionalità e casi d'uso. Abbiamo appena pubblicato anche un articolo di hit test che spiega un'API per il rilevamento delle superfici e il posizionamento degli elementi virtuali in una visualizzazione reale della videocamera. Dai un'occhiata e guarda il blog web.dev per trovare altri articoli nell'anno a venire.

Foto di David Grandmougin su Unsplash