Writing 3D applications for the browser is possible since some years due to the WebGL API. But since Virtual Reality and Augmented Reality are getting more popular, web developers and designers now have a serious reason to get to know the 3D web, its APIs and design patterns.
26. Lifetime of a WebXR App
Request XR Device
Reveal XR Functionality
27. Lifetime of a WebXR App
Request XR Device
Reveal XR Functionality
Request XR Session
28. Lifetime of a WebXR App
Request XR Device
Reveal XR Functionality
Request XR Session
Run Render Loop
29. Request a XR Devices
navigator.xr.requestDevice().then(device => {
if (device) {
handleXRAvailable(device);
}
}).catch(error =>
console.error('Unable to request an XR device: ', error);
});
30. Request a XR Devices
navigator.xr.requestDevice().then(device => {
if (device) {
handleXRAvailable(device);
}
}).catch(error =>
console.error('Unable to request an XR device: ', error);
});
31. Check XR Session Support
let xrDevice = null;
function handleXRAvailable(device) {
xrDevice = device;
xrDevice.supportsSession({exclusive: true}).then(() => {
addWebXRButtonToPage();
}).catch((error) => {
console.log('Session not supported: ' + error);
});
}
32. Check XR Session Support
let xrDevice = null;
function handleXRAvailable(device) {
xrDevice = device;
xrDevice.supportsSession({exclusive: true}).then(() => {
addWebXRButtonToPage();
}).catch((error) => {
console.log('Session not supported: ' + error);
});
}
33. Request a XR Session
function beginXRSession() {
let canvas = document.createElement('canvas');
let context = canvas.getContext('xrpresent');
document.body.appendChild(canvas);
xrDevice.requestSession({exclusive: true, outputContext: context})
.then(onSessionStarted)
.catch((error) => {console.log('requestSession failed: ' + error);});
}
34. Start a XR Session
let xrSession = null;
let xrFrameOfReference = null;
function onSessionStarted(session) {
xrSession = session;
xrSession.requestFrameOfReference('eyeLevel')
.then((frameOfReference) => {xrFrameOfReference = frameOfReference;})
.then(setupWebGLLayer)
.then(() => {xrSession.requestAnimationFrame(onRenderFrame);});
}
35. Start a XR Session
let xrSession = null;
let xrFrameOfReference = null;
function onSessionStarted(session) {
xrSession = session;
xrSession.requestFrameOfReference('eyeLevel')
.then((frameOfReference) => {xrFrameOfReference = frameOfReference;})
.then(setupWebGLLayer)
.then(() => {xrSession.requestAnimationFrame(onRenderFrame);});
}
36. Start a XR Session
let xrSession = null;
let xrFrameOfReference = null;
function onSessionStarted(session) {
xrSession = session;
xrSession.requestFrameOfReference('eyeLevel')
.then((frameOfReference) => {xrFrameOfReference = frameOfReference;})
.then(setupWebGLLayer)
.then(() => {xrSession.requestAnimationFrame(onRenderFrame);});
}
37. Setup an XRLayer
let glCanvas = document.createElement('canvas');
let glContext = glCanvas.getContext('webgl');
function setupWebGLLayer() {
return glContext.setCompatibleXRDevice(xrDevice).then(() => {
xrSession.baseLayer = new XRWebGLLayer(xrSession, glContext);
});
}
38. Setup an XRLayer
let glCanvas = document.createElement('canvas');
let glContext = glCanvas.getContext('webgl');
function setupWebGLLayer() {
return glContext.setCompatibleXRDevice(xrDevice).then(() => {
xrSession.baseLayer = new XRWebGLLayer(xrSession, glContext);
});
}
39. Start a XR Session
let xrSession = null;
let xrFrameOfReference = null;
function onSessionStarted(session) {
xrSession = session;
xrSession.requestFrameOfReference('eyeLevel')
.then((frameOfReference) => {xrFrameOfReference = frameOfReference;})
.then(setupWebGLLayer)
.then(() => {xrSession.requestAnimationFrame(onRenderFrame);});
}
40. Start the Render Loop
function onRenderFrame(timestamp, xrFrame) {
let pose = xrFrame.getDevicePose(xrFrameOfReference);
if (pose) {
for (let view of xrFrame.views) {
// Draw something
}
}
// Input device code
xrSession.requestAnimationFrame(onRenderFrame);
}
41. Start the Render Loop
function onRenderFrame(timestamp, xrFrame) {
let pose = xrFrame.getDevicePose(xrFrameOfReference);
if (pose) {
for (let view of xrFrame.views) {
// Draw something
}
}
// Input device code
xrSession.requestAnimationFrame(onRenderFrame);
}
42. Start the Render Loop
function onRenderFrame(timestamp, xrFrame) {
let pose = xrFrame.getDevicePose(xrFrameOfReference);
if (pose) {
for (let view of xrFrame.views) {
// Draw something
}
}
// Input device code
xrSession.requestAnimationFrame(onRenderFrame);
}
43. Start the Render Loop
function onRenderFrame(timestamp, xrFrame) {
let pose = xrFrame.getDevicePose(xrFrameOfReference);
if (pose) {
for (let view of xrFrame.views) {
// Draw something
}
}
// Input device code
xrSession.requestAnimationFrame(onRenderFrame);
}
44. Exit the WebXR Session
function endXRSession() {
if (xrSession) {xrSession.end().then(onSessionEnd);}
}
function onSessionEnd() {
xrSession = null;
window.requestAnimationFrame(onDrawFrame);
}
45. Exit the WebXR Session
function endXRSession() {
if (xrSession) {xrSession.end().then(onSessionEnd);}
}
function onSessionEnd() {
xrSession = null;
window.requestAnimationFrame(onDrawFrame);
}
46.
47.
48.
49.
50. Fallback: Magic Window
let mwCanvas = document.createElement('canvas');
let mwContext = mwCanvas.getContext('xrpresent');
document.body.appendChild(mwCanvas);
function beginMagicWindowXRSession() {
xrDevice.requestSession({exclusive: false, outputContext: mwContext})
.then(OnSessionStarted)
.catch((error) => {console.log('requestSession failed: ' + error);});
}
51. Fallback: Magic Window
let mwCanvas = document.createElement('canvas');
let mwContext = mwCanvas.getContext('xrpresent');
document.body.appendChild(mwCanvas);
function beginMagicWindowXRSession() {
xrDevice.requestSession({exclusive: false, outputContext: mwContext})
.then(OnSessionStarted)
.catch((error) => {console.log('requestSession failed: ' + error);});
}
54. On Page Load:
Magic Window
exclusive sessions are supported
Render a
"Start VR" Button
55. 6DOF VR Headset
Created by Hans Gerhard Meier, Bence Bezeredy, Laura HernĂĄndez, Anil, Sachin Modgekar, Ben Davis from the Noun Project
56. 6DOF VR Headset
AR-ready Smartphone
Created by Hans Gerhard Meier, Bence Bezeredy, Laura HernĂĄndez, Anil, Sachin Modgekar, Ben Davis from the Noun Project
57. 6DOF VR Headset
AR-ready Smartphone
3DOF VR Headset
Created by Hans Gerhard Meier, Bence Bezeredy, Laura HernĂĄndez, Anil, Sachin Modgekar, Ben Davis from the Noun Project
58. Progressive Enhancement
6DOF VR Headset
AR-ready Smartphone
3DOF VR Headset
Created by Hans Gerhard Meier, Bence Bezeredy, Laura HernĂĄndez, Anil, Sachin Modgekar, Ben Davis from the Noun Project
59. Progressive Enhancement
6DOF VR Headset
AR-ready Smartphone
3DOF VR Headset
WebXR Polyfill
Created by Hans Gerhard Meier, Bence Bezeredy, Laura HernĂĄndez, Anil, Sachin Modgekar, Ben Davis from the Noun Project
60. Progressive Enhancement
6DOF VR Headset
AR-ready Smartphone
3DOF VR Headset
Magic Window
WebXR Polyfill
Created by Hans Gerhard Meier, Bence Bezeredy, Laura HernĂĄndez, Anil, Sachin Modgekar, Ben Davis from the Noun Project
61. Progressive Enhancement
6DOF VR Headset
AR-ready Smartphone
3DOF VR Headset
Magic Window
Gyroscope
WebXR Polyfill
Created by Hans Gerhard Meier, Bence Bezeredy, Laura HernĂĄndez, Anil, Sachin Modgekar, Ben Davis from the Noun Project
62. Progressive Enhancement
6DOF VR Headset
AR-ready Smartphone
3DOF VR Headset
Magic Window
Gyroscope
WebXR Polyfill
Static Image
Created by Hans Gerhard Meier, Bence Bezeredy, Laura HernĂĄndez, Anil, Sachin Modgekar, Ben Davis from the Noun Project
108. It was the pioneer days; people had to make their own interrogation rooms. Out of
cornmeal. These endless days are finally ending in a blaze. When I say, 'I love you,'
it's not because I want you or because I can't have you. It's my estimation that every
man ever got a statue made of him was one kind of sommbitch or another. Oh my god you
will never believe what happened at school today. From beneath you, it devours. I am
never gonna see a merman, ever.
It was supposed to confuse him, but it just made him peppy. It was like the Heimlich,
with stripes! How did your brain even learn human speech? I'm just so curious.
Apocalypse, we've all been there; the same old trips, why should we care? Frankly, it's
ludicrous to have these interlocking bodies and not...interlock. I just don't see why
everyone's always picking on Marie-Antoinette. You're the one freaky thing in my freaky
world that still makes sense to me. You are talking crazy-person talk.
109. It was the pioneer days; people had to make their own interrogation rooms. Out of
cornmeal. These endless days are finally ending in a blaze. When I say, 'I love you,'
it's not because I want you or because I can't have you. It's my estimation that every
man ever got a statue made of him was one kind of sommbitch or another. Oh my god you
will never believe what happened at school today. From beneath you, it devours. I am
never gonna see a merman, ever.
It was supposed to confuse him, but it just made him peppy. It was like the Heimlich,
with stripes! How did your brain even learn human speech? I'm just so curious.
Apocalypse, we've all been there; the same old trips, why should we care? Frankly, it's
ludicrous to have these interlocking bodies and not...interlock. I just don't see why
everyone's always picking on Marie-Antoinette. You're the one freaky thing in my freaky
world that still makes sense to me. You are talking crazy-person talk.
110.
111. It was the pioneer days; people had to make their own interrogation rooms. Out of
cornmeal. These endless days are finally ending in a blaze. When I say, 'I love you,'
it's not because I want you or because I can't have you. It's my estimation that every
man ever got a statue made of him was one kind of sommbitch or another. Oh my god you
will never believe what happened at school today. From beneath you, it devours. I am
never gonna see a merman, ever.
It was supposed to confuse him, but it just made him peppy. It was like the Heimlich,
with stripes! How did your brain even learn human speech? I'm just so curious.
Apocalypse, we've all been there; the same old trips, why should we care? Frankly, it's
ludicrous to have these interlocking bodies and not...interlock. I just don't see why
everyone's always picking on Marie-Antoinette. You're the one freaky thing in my freaky
world that still makes sense to me. You are talking crazy-person talk.