Realtà aumentata: potresti già conoscerla

Se hai già utilizzato l'API WebXR Device, hai quasi completato la procedura.

Joe Medley
Joe Medley

L'API WebXR Device è stata rilasciata lo scorso autunno in Chrome 79. Come affermato in precedenza, l'implementazione dell'API in Chrome è in fase di sviluppo. Chrome è felice di annunciare che parte del lavoro è stata completata. In Chrome 81 sono state introdotte due nuove funzionalità:

Questo articolo riguarda la realtà aumentata. Se hai già utilizzato l'API WebXR Device, ti farà piacere sapere che non c'è molto altro da imparare. La procedura per accedere a una sessione WebXR è in gran parte la stessa. L'esecuzione di un ciclo di frame è in gran parte la stessa. Le differenze riguardano le configurazioni che consentono di mostrare i contenuti in modo appropriato per la realtà aumentata. Se non conosci i concetti di base di WebXR, ti consiglio di leggere i miei post precedenti sull'API WebXR Device o almeno di essere familiare con gli argomenti trattati al loro interno. Devi sapere come richiedere e accedere a una sessione e come eseguire un loop di frame.

Per informazioni sui test degli hit, consulta l'articolo complementare Posizionare oggetti virtuali nelle visualizzazioni del mondo reale. Il codice in questo articolo si basa sull'esempio di sessione AR immersiva (demo source) proveniente dagli esempi dell'API WebXR Device del gruppo di lavoro Immersive Web.

Prima di iniziare a lavorare al codice, devi utilizzare il sample di sessione AR immersiva almeno una volta. Devi avere uno smartphone Android moderno con Chrome 81 o versioni successive.

A cosa serve?

La realtà aumentata sarà un'aggiunta preziosa per molte pagine web esistenti o nuove, in quanto consentirà di implementare casi d'uso AR senza uscire dal browser. Ad esempio, può aiutare le persone a imparare sui siti didattici e consentire ai potenziali acquirenti di visualizzare gli oggetti in casa durante lo shopping.

Prendi in considerazione il secondo caso d'uso. Immagina di simulare il posizionamento di una rappresentazione in scala reale di un oggetto virtuale in una scena reale. Una volta posizionata, l'immagine rimane sulla superficie selezionata, viene visualizzata nelle dimensioni che avrebbe se l'elemento effettivo fosse su quella superficie e consente all'utente di spostarsi intorno, avvicinarsi o allontanarsi. In questo modo, gli spettatori possono comprendere meglio l'oggetto rispetto a quanto sia possibile con un'immagine bidimensionale.

Mi sto un po' anticipando. Per fare ciò che ho descritto, hai bisogno della funzionalità AR e di alcuni mezzi per rilevare le superfici. Questo articolo riguarda la prima opzione. L'articolo associato sull'API Hit Test WebXR (link sopra) tratta quest'ultimo.

Richiesta di una sessione

La richiesta di una sessione è molto simile a quanto hai visto in precedenza. Innanzitutto, scopri se il tipo di sessione che vuoi è disponibile sul dispositivo corrente chiamando xr.isSessionSupported(). Anziché 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, viene attivato un pulsante "Accedi all'AR". Quando l'utente fa clic, chiama xr.requestSession(), passando 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();
  }
}

Una proprietà comoda

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

Accedere a una sessione

Ricorda come appariva 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 alcune cose per tenere conto del rendering della realtà aumentata. Disattiva lo sfondo. Per prima cosa, devo stabilire se ho bisogno dello sfondo. Qui è la prima volta che userò la mia proprietà comodità.

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 hanno esaminato superficialmente gli spazi di riferimento. Il sample che sto descrivendo ne utilizza due, quindi è il momento di correggere questa omissione.

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

  • Specifica l'origine del sistema di coordinate utilizzato per esprimere le posizioni nel mondo virtuale.
  • Specifica se ci si aspetta che l'utente si muova all'interno di questo sistema di coordinate.
  • Indica se il sistema di coordinate ha confini predefiniti. Gli esempi riportati qui non utilizzano sistemi di coordinate con confini predefiniti.

Per tutti gli spazi di riferimento, la coordinata X esprime sinistra e destra, la Y rappresenta su e giù e Z avanti e indietro. I valori positivi sono rispettivamente per destra, su e indietro.

Le coordinate restituite da XRFrame.getViewerPose() dipendono dal tipo di spazio di riferimento richiesto. Scopriremo di più quando arriveremo al loop dei frame. Al momento dobbiamo selezionare un tipo di riferimento appropriato per la realtà aumentata. Anche in questo caso viene utilizzata la proprietà per comodità.

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 il Sample di sessione AR immersiva, noterai che inizialmente la scena è statica e non è affatto realtà virtuale. Puoi trascinare e scorrere con il dito per spostarti nella scena. Se fai clic su "AVVIA AR", lo sfondo scompare e puoi spostarti nella scena muovendo il dispositivo. Le modalità utilizzano diversi tipi di spazi di riferimento. Il testo evidenziato sopra mostra come viene selezionato. Utilizza i seguenti tipi di riferimento:

local: l'origine è la posizione dello spettatore al momento della creazione della sessione. Ciò significa che l'esperienza non ha necessariamente un valore minimo ben definito e la posizione esatta dell'origine può variare in base alla piattaforma. Anche se non esistono confini predefiniti per lo spazio, si prevede che i contenuti possano essere visualizzati senza movimenti diversi dalla rotazione. Come puoi vedere dal nostro esempio di AR, potrebbe essere possibile un po' di movimento all'interno dello spazio.

viewer: utilizzato più di frequente per i contenuti presentati in linea nella pagina, questo spazio segue il dispositivo di visualizzazione. Se viene passato a getViewerPose, non fornisce alcun monitoraggio e, di conseguenza, registra sempre una posa all'origine, a meno che l'applicazione non la modifichi con XRReferenceSpace.getOffsetReferenceSpace(). Il sample lo utilizza per attivare la panoramica della fotocamera tramite tocco.

Eseguire un ciclo di frame

A livello concettuale, non cambia nulla rispetto a quanto 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'utilizzo di viewer come valore predefinito consente a una pagina di mostrare le anteprime dei contenuti prima che venga richiesto il consenso dell'utente per l'AR o la VR. Questo illustra un punto importante: i contenuti in linea utilizzano lo stesso loop di frame dei contenuti immersivi, riducendo la quantità di codice da gestire.

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 illustra solo le nozioni di base sull'implementazione di contenuti immersivi sul web. Moltissime altre funzionalità e casi d'uso sono presentati dagli esempi dell'API WebXR Device del gruppo di lavoro Immersive Web. Inoltre, abbiamo appena pubblicato un articolo sui test di corrispondenza che spiega un'API per il rilevamento delle superfici e il posizionamento di elementi virtuali in una visuale della fotocamera del mondo reale. Dai un'occhiata e visita il blog web.dev per altri articoli nel corso dell'anno.

Foto di David Grandmougin su Unsplash