Ti diamo il benvenuto nel Web immersivo

Il web immersivo indica esperienze in mondi virtuali ospitate tramite il browser. Tutte queste esperienze di realtà virtuale sono state visualizzate nel browser o nei visori VR abilitati.

Joe Medley
Joe Medley

Il web immersivo indica le esperienze nel mondo virtuale ospitate tramite il browser. Sono incluse intere esperienze di realtà virtuale (VR) visualizzate nel browser o in visori VR come Daydream di Google, Oculus Rift, Samsung Gear VR, HTC Vive e visori Windows Mixed Reality, nonché esperienze di realtà aumentata sviluppate per dispositivi mobili compatibili con la realtà aumentata.

Anche se usiamo due termini per descrivere le esperienze immersive, devono essere considerati come uno spettro che spazia dalla realtà completa a un ambiente VR completamente immersivo, con vari livelli di AR.

Esempi di esperienze immersive includono:

  • Video immersivi a 360°
  • Video 2D (o 3D) tradizionali presentati in un ambiente immersivo
  • Visualizzazioni di dati
  • Shopping da casa
  • Arte
  • Qualcosa di interessante a cui nessuno ha ancora pensato

Come ci arrivo?

Il web immersivo è disponibile ormai in forma embrionale da quasi un anno. Ciò è stato fatto tramite l'API WebVR 1.1, che è disponibile in una prova dell'origine dalla versione 62 di Chrome. che è supportata anche da Firefox ed Edge e da un polyfill per Safari.

Ma è ora di andare avanti.

La prova dell'origine è terminata il 24 luglio 2018 e le specifiche sono state sostituite dall'API WebXR Device e da una nuova prova dell'origine.

Che cosa è successo a WebVR 1.1?

Abbiamo imparato molto da WebVR 1.1, ma nel tempo è emerso chiaramente che erano necessarie alcune modifiche sostanziali per supportare i tipi di applicazioni che gli sviluppatori vogliono creare. L'elenco completo delle lezioni apprese è troppo lungo per essere riportato qui, ma include problemi come il fatto che l'API sia legata esplicitamente al thread JavaScript principale, troppe opportunità per gli sviluppatori di configurare configurazioni palesemente sbagliate e utilizzi comuni come la finestra magica che è un effetto collaterale anziché una funzionalità intenzionale. La finestra magica è una tecnica per visualizzare contenuti immersivi senza un visore, in cui l'app esegue il rendering di una singola visualizzazione in base al sensore di orientamento del dispositivo.

Il nuovo design semplifica le implementazioni e consente notevoli miglioramenti delle prestazioni. Allo stesso tempo, stavano emergendo l'AR e altri casi d'uso ed è diventato importante che l'API fosse estensibile in modo da supportarli in futuro.

L'API WebXR Device è stata progettata e denominata tenendo conto di questi casi d'uso espansi e offre un percorso migliore. Gli implementatori di WebVR si sono impegnati a eseguire la migrazione all'API WebXR Device.

Che cos'è l'API WebXR Device?

Come la specifica WebVR precedente, l'API WebXR Device è un prodotto dell'Immersive Web Community Group che collabora con Google, Microsoft, Mozilla e altri. L'X in XR è inteso come una sorta di variabile algebrica che rappresenta qualsiasi elemento nello spettro delle esperienze immersive. È disponibile nella prova dell'origine menzionata in precedenza, nonché tramite un polyfill.

Quando questo articolo è stato pubblicato inizialmente durante il periodo beta di Chrome 67, erano attivate solo le funzionalità VR. La realtà aumentata è arrivata con Chrome 69. Scopri di più nella pagina Realtà aumentata per il web.

Questa nuova API è molto più di quanto posso consultare in un articolo come questo. Voglio darti abbastanza informazioni per iniziare a comprendere i sample WebXR. Puoi trovare maggiori informazioni sia nell'articolo esplicativo originale sia nella nostra Guida per gli early adopter del web immersivo. Amplierò la seconda man mano che la prova dell'origine avanza. Non esitare ad aprire i problemi o a inviare richieste di pull.

In questo articolo parlerò di come avviare, interrompere ed eseguire una sessione XR, oltre a alcune nozioni di base sull'elaborazione dell'input.

Non parlerò di come disegnare contenuti AR/VR sullo schermo. L'API WebXR Device non fornisce funzionalità di rendering delle immagini. Dipende da te. Il disegno viene eseguito utilizzando le API WebGL. Puoi farlo se hai grandi ambizioni. Tuttavia, ti consigliamo di utilizzare un framework. Gli esempi web immersivi ne utilizzano uno creato appositamente per le dimostrazioni, chiamato Cottontail. Three.js supporta WebXR da maggio. Non ho sentito nulla su A-Frame.

Avvio ed esecuzione di un'app

La procedura di base è la seguente:

  1. Richiedi un dispositivo XR.
  2. Se è disponibile, richiedi una sessione XR. Se vuoi che l'utente infili lo smartphone in un auricolare, si tratta di una sessione immersiva che richiede un gesto dell'utente per accedere.
  3. Utilizza la sessione per eseguire un ciclo di rendering che fornisce 60 fotogrammi di immagini al secondo. Disegna contenuti appropriati sullo schermo in ogni frame.
  4. Esegui il loop di rendering finché l'utente non decide di uscire.
  5. Termina la sessione XR.

Esaminiamo questo aspetto in modo più dettagliato e includiamo del codice. Non sarai in grado di eseguire un'app da ciò che sto per mostrarti. Ma, di nuovo, è solo per farti capire.

Richiedi un dispositivo XR

Qui riconoscerai il codice di rilevamento delle funzionalità standard. Potresti inserire questo codice in una funzione chiamata ad esempio checkForXR().

Se non utilizzi una sessione immersiva, puoi saltare la pubblicità della funzionalità e l'ottenimento di un gesto dell'utente e passare direttamente alla richiesta di una sessione. Una sessione immersiva è una sessione che richiede un auricolare. Una sessione non immersiva mostra semplicemente i contenuti sullo schermo del dispositivo. La maggior parte delle persone pensa alla prima quando si fa riferimento alla realtà virtuale o alla realtà aumentata. Quest'ultima viene a volte chiamata "finestra magica".

if (navigator.xr) {
    navigator.xr.requestDevice()
    .then(xrDevice => {
    // Advertise the AR/VR functionality to get a user gesture.
    })
    .catch(err => {
    if (err.name === 'NotFoundError') {
        // No XRDevices available.
        console.error('No XR devices available:', err);
    } else {
        // An error occurred while requesting an XRDevice.
        console.error('Requesting XR device failed:', err);
    }
    })
} else{
    console.log("This browser does not support the WebXR API.");
}

Richiedere una sessione XR

Ora che abbiamo il dispositivo e il gesto dell'utente, è il momento di avviare una sessione. Per creare una sessione, il browser ha bisogno di un canvas su cui disegnare.

xrPresentationContext = htmlCanvasElement.getContext('xrpresent');
let sessionOptions = {
    // The immersive option is optional for non-immersive sessions; the value
    //   defaults to false.
    immersive: false,
    outputContext: xrPresentationContext
}
xrDevice.requestSession(sessionOptions)
.then(xrSession => {
    // Use a WebGL context as a base layer.
    xrSession.baseLayer = new XRWebGLLayer(session, gl);
    // Start the render loop
})

Eseguire il loop di rendering

Il codice di questo passaggio è più semplice. Per aiutarti a capire, sto per dirti un sacco di parole. Se vuoi dare un'occhiata al codice finale, vai avanti per dare un'occhiata veloce e poi torna per la spiegazione completa. Potresti non essere in grado di dedurre molto.

La procedura di base per un ciclo di rendering è la seguente:

  1. Richiedi un frame dell'animazione.
  2. Query per la posizione del dispositivo.
  3. Disegna i contenuti in base alla posizione del dispositivo.
  4. Svolgere le operazioni necessarie per i dispositivi di input.
  5. Ripeti l'operazione 60 volte al secondo finché l'utente non decide di uscire.

Richiedi un frame della presentazione

La parola "frame" ha diversi significati in un contesto XR web. Il primo è il frame di riferimento, che definisce da dove viene calcolata l'origine del sistema di coordinate e cosa succede a quell'origine quando il dispositivo si sposta. La visualizzazione rimane invariata quando l'utente si sposta o cambia come nella vita reale?

Il secondo tipo di frame è il frame di presentazione, rappresentato da un oggetto XRFrame. Questo oggetto contiene le informazioni necessarie per eseguire il rendering di un singolo frame di una scena AR/VR sul dispositivo. Questo è un po' confuso perché un frame di presentazione viene recuperato chiamando requestAnimationFrame(). In questo modo è compatibile con window.requestAnimationFrame().

Prima di darti altro da assimilare, ti fornirò del codice. L'esempio seguente mostra come viene avviato e mantenuto il loop di rendering. Nota il doppio utilizzo del frame di testo. e nota la chiamata ricorsiva a requestAnimationFrame(). Questa funzione verrà chiamata 60 volte al secondo.

xrSession.requestFrameOfReference('eye-level')
.then(xrFrameOfRef => {
    xrSession.requestAnimationFrame(onFrame(time, xrFrame) {
    // The time argument is for future use and not implemented at this time.
    // Process the frame.
    xrFrame.session.requestAnimationFrame(onFrame);
    }
});

Pose

Prima di disegnare qualsiasi elemento sullo schermo, devi sapere dove è rivolto il dispositivo di visualizzazione e devi avere accesso allo schermo. In generale, la posizione e l'orientamento di un oggetto in AR/VR sono chiamati posa. Sia i visualizzatori sia i dispositivi di input hanno una posa. (Parlerò dei dispositivi di input più avanti). Le pose dello spettatore e del dispositivo di input sono definite come una matrice 4 x 4 memorizzata in un Float32Array nell'ordine principale della colonna. Puoi ottenere la posa dello spettatore chiamando XRFrame.getDevicePose() sull'oggetto frame dell'animazione corrente. Controlla sempre se hai ricevuto una risposta. Se si è verificato un problema, non vuoi disegnare sullo schermo.

let pose = xrFrame.getDevicePose(xrFrameOfRef);
if (pose) {
    // Draw something to the screen.
}

Visualizzazioni

Dopo aver controllato la posa, è il momento di disegnare qualcosa. L'oggetto su cui disegni è chiamato vista (XRView). È qui che il tipo di sessione diventa importante. Le visualizzazioni vengono recuperate dall'oggetto XRFrame come array. In una sessione non immersiva, l'array ha una vista, Se sei in una sessione immersiva, l'array ne ha due, uno per ciascun occhio.

for (let view of xrFrame.views) {
    // Draw something to the screen.
}

Questa è una differenza importante tra WebXR e altri sistemi immersivi. Anche se potrebbe sembrare inutile eseguire l'iterazione in una visualizzazione, questa operazione ti consente di avere un unico percorso di rendering per una serie di dispositivi.

L'intero loop di rendering

Se metto tutto insieme, ottengo il codice riportato di seguito. Ho lasciato un segnaposto per i dispositivi di input, che tratteremo in una sezione successiva.

xrSession.requestFrameOfReference('eye-level')
.then(xrFrameOfRef => {
    xrSession.requestAnimationFrame(onFrame(time, xrFrame) {
    // The time argument is for future use and not implemented at this time.
    let pose = xrFrame.getDevicePose(xrFrameOfRef);
    if (pose) {
        for (let view of xrFrame.views) {
        // Draw something to the screen.
        }
    }
    // Input device code will go here.
    frame.session.requestAnimationFrame(onFrame);
    }
}

Terminare la sessione XR

Una sessione XR può terminare per diversi motivi, tra cui la fine con codice personale tramite una chiamata al numero XRSession.end(). Altre cause sono la disconnessione delle cuffie o il controllo da parte di un'altra applicazione. Ecco perché un'applicazione di buon comportamento deve monitorare l'evento di fine e, quando si verifica, eliminare gli oggetti sessione e renderer. Una volta terminata, una sessione XR non può essere ripresa.

xrDevice.requestSession(sessionOptions)
.then(xrSession => {
    // Create a WebGL layer and initialize the render loop.
    xrSession.addEventListener('end', onSessionEnd);
});

// Restore the page to normal after immersive access has been released.
function onSessionEnd() {
    xrSession = null;

    // Ending the session stops executing callbacks passed to the XRSession's
    // requestAnimationFrame(). To continue rendering, use the window's
    // requestAnimationFrame() function.
    window.requestAnimationFrame(onDrawFrame);
}

Come funziona l'interazione?

Come per la durata dell'applicazione, vi darò un assaggio di come interagire con gli oggetti in AR o VR.

L'API WebXR Device adotta un approccio "point and click" per l'input dell'utente. Con questo approccio ogni origine di input ha un raggio puntatore definito per indicare dove punta un dispositivo di input e eventi per indicare quando è stato selezionato qualcosa. L'app disegna il raggio del cursore e mostra dove è rivolto. Quando l'utente fa clic sul dispositivo di input, vengono attivati gli eventi select, selectStart e selectEnd. L'app determina su cosa è stato fatto clic e risponde in modo appropriato.

Il dispositivo di input e il raggio di puntatore

Per gli utenti, il raggio del cursore è solo una linea sbiadita tra il controller e qualunque cosa stiano indicando. Ma è l'app a doverli disegnare. Ciò significa ottenere la posa del dispositivo di input e tracciare una linea dalla sua posizione a un oggetto nello spazio AR/VR. La procedura è approssimativamente la seguente:

let inputSources = xrSession.getInputSources();
for (let xrInputSource of inputSources) {
    let inputPose = frame.getInputPose(inputSource, xrFrameOfRef);
    if (!inputPose) {
    continue;
    }
    if (inputPose.gripMatrix) {
    // Render a virtual version of the input device
    //   at the correct position and orientation.
    }
    if (inputPose.pointerMatrix) {
    // Draw a ray from the gripMatrix to the pointerMatrix.
    }
}

Questa è una versione semplificata dell'esempio di monitoraggio degli input del gruppo della community web immersiva. Come per il rendering della scena, spetta a te disegnare il raggio del cursore e il dispositivo. Come accennato in precedenza, questo codice deve essere eseguito nell'ambito del ciclo di rendering.

Selezione di elementi nello spazio virtuale

Semplicemente puntare gli oggetti in AR/VR è piuttosto inutile. Per fare qualcosa di utile, gli utenti devono avere la possibilità di selezionare elementi. L'API WebXR Device fornisce tre eventi per rispondere alle interazioni utente: select, selectStart e selectEnd. Hanno un'anomalia che non mi aspettavo: ti dicono solo che è stato fatto clic su un dispositivo di input. Non indicano su quale elemento dell'ambiente è stato fatto clic. I gestori degli eventi vengono aggiunti all'oggetto XRSession e devono essere aggiunti non appena sono disponibili.

xrDevice.requestSession(sessionOptions)
.then(xrSession => {
    // Create a WebGL layer and initialize the render loop.
    xrSession.addEventListener('selectstart', onSelectStart);
    xrSession.addEventListener('selectend', onSelectEnd);
    xrSession.addEventListener('select', onSelect);
});

Questo codice si basa su un esempio di selezione input, nel caso in cui tu voglia maggiori informazioni.

Per capire su cosa è stato fatto clic, utilizzi una posa. (Siete sorpresi? Non lo pensavo.) I dettagli sono specifici della tua app o del framework che utilizzi e, pertanto, non rientrano nell'ambito di questo articolo. L'approccio di Cottontail è nell'esempio di selezione di input.

function onSelect(ev) {
    let inputPose = ev.frame.getInputPose(ev.inputSource, xrFrameOfRef);
    if (!inputPose) {
    return;
    }
    if (inputPose.pointerMatrix) {
    // Figure out what was clicked and respond.
    }
}

Conclusione: uno sguardo al futuro

Come detto in precedenza, la realtà aumentata è prevista in Chrome 69 (Canary a giugno 2018). Tuttavia, ti incoraggio a provare ciò che abbiamo finora. Abbiamo bisogno del tuo feedback per migliorare. Segui i progressi guardando ChromeStatus.com per WebXR Hit Test. Puoi anche seguire gli ancoraggi WebXR per migliorare il monitoraggio della posa.