how to make your users sick in 60 seconds – about ux design, webvr and react vr
TRANSCRIPT
geildanke.com @ RuhrJS17 @fischaelameer
How to Make Your User Sick in 60 Seconds
About UX Design, WebVR, and ReactVR
geildanke.com @ RuhrJS17 @fischaelameer
You Should Care About WebVR Because You Care About Your Users.
geildanke.com @ RuhrJS17 @fischaelameer
Virtual Reality Is Tricking Our Eyes And Brain to Think of a 2D Image to Be in 3D.
geildanke.com @ RuhrJS17 @fischaelameer
Virtual Reality Changes The Way We Relate to Technology.
geildanke.com @ RuhrJS17 @fischaelameer
VR Is Good For Understanding Spatial Relationships
geildanke.com @ RuhrJS17 @fischaelameer
https://www.reddit.com/r/VRFail/comments/4p9zgj/pool_shot/
geildanke.com @ RuhrJS17 @fischaelameer
https://www.reddit.com/r/VRFail/comments/4p9zgj/pool_shot/
geildanke.com @ RuhrJS17 @fischaelameer
geildanke.com @ RuhrJS17 @fischaelameer
geildanke.com @ RuhrJS17 @fischaelameer
geildanke.com @ RuhrJS17 @fischaelameer
geildanke.com @ RuhrJS17 @fischaelameer
Browser
https://github.com/mrdoob/three.js
geildanke.com @ RuhrJS17 @fischaelameer
Browser
WebGL
https://github.com/mrdoob/three.js
geildanke.com @ RuhrJS17 @fischaelameer
Browser
WebGL WebVR
https://github.com/mrdoob/three.js
geildanke.com @ RuhrJS17 @fischaelameer
Browser
WebGL WebVR
three.js
Ricardo Cabello
https://github.com/mrdoob/three.js
geildanke.com @ RuhrJS17 @fischaelameer
geildanke.com @ RuhrJS17 @fischaelameer
geildanke.com @ RuhrJS17 @fischaelameer
geildanke.com @ RuhrJS17 @fischaelameer
geildanke.com @ RuhrJS17 @fischaelameer
geildanke.com @ RuhrJS17 @fischaelameer
Browser
WebGL WebVR
three.js WebVR Polyfill
https://github.com/googlevr/webvr-polyfill
geildanke.com @ RuhrJS17 @fischaelameer
Static Image With Fallback
WebGL With Touch And Gyroscope
geildanke.com @ RuhrJS17 @fischaelameer
Static Image With Fallback
WebGL With Touch And Gyroscope
Mobile & Desktop VR Devices
geildanke.com @ RuhrJS17 @fischaelameer
geildanke.com @ RuhrJS17 @fischaelameer
geildanke.com @ RuhrJS17 @fischaelameer
geildanke.com @ RuhrJS17 @fischaelameer
let scene = new THREE.Scene();let camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 10000 );let renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );document.body.appendChild( renderer.domElement );
let geometry = new THREE.SphereGeometry( 500, 60, 40 );geometry.scale( -1, 1, 1 );
let video = document.createElement( 'video' );let videoTexture = new THREE.VideoTexture( video );let videoMaterial = new THREE.MeshBasicMaterial( { map: videoTexture } );let mesh = new THREE.Mesh( geometry, videoMaterial );
function render() {requestAnimationFrame( render );renderer.render( scene, camera );
}
render();
geildanke.com @ RuhrJS17 @fischaelameer
let scene = new THREE.Scene();let camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 10000 );let renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );document.body.appendChild( renderer.domElement );
let geometry = new THREE.SphereGeometry( 500, 60, 40 );geometry.scale( -1, 1, 1 );
let video = document.createElement( 'video' );let videoTexture = new THREE.VideoTexture( video );let videoMaterial = new THREE.MeshBasicMaterial( { map: videoTexture } );let mesh = new THREE.Mesh( geometry, videoMaterial );
function render() {requestAnimationFrame( render );renderer.render( scene, camera );
}
render();
geildanke.com @ RuhrJS17 @fischaelameer
let scene = new THREE.Scene();let camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 10000 );let renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );document.body.appendChild( renderer.domElement );
let geometry = new THREE.SphereGeometry( 500, 60, 40 );geometry.scale( -1, 1, 1 );
let video = document.createElement( 'video' );let videoTexture = new THREE.VideoTexture( video );let videoMaterial = new THREE.MeshBasicMaterial( { map: videoTexture } );let mesh = new THREE.Mesh( geometry, videoMaterial );
function render() {requestAnimationFrame( render );renderer.render( scene, camera );
}
render();
geildanke.com @ RuhrJS17 @fischaelameer
let scene = new THREE.Scene();let camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 10000 );let renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );document.body.appendChild( renderer.domElement );
let geometry = new THREE.SphereGeometry( 500, 60, 40 );geometry.scale( -1, 1, 1 );
let video = document.createElement( 'video' );let videoTexture = new THREE.VideoTexture( video );let videoMaterial = new THREE.MeshBasicMaterial( { map: videoTexture } );let mesh = new THREE.Mesh( geometry, videoMaterial );
function render() {requestAnimationFrame( render );renderer.render( scene, camera );
}
render();
geildanke.com @ RuhrJS17 @fischaelameer
let vrDisplay;
navigator.getVRDisplays().then( function( displays ) { if ( displays.length > 0 ) { vrDisplay = displays[ 0 ]; } else { console.log( 'No VR Displays found.' ); }});
geildanke.com @ RuhrJS17 @fischaelameer
VRDisplay.isConnectedVRDisplay.isPresenting
VRDisplay.getEyeParameters()VRDisplay.requestAnimationFrame()
geildanke.com @ RuhrJS17 @fischaelameer
vrDisplay.requestPresent( [ { source: myCanvas } ] );
geildanke.com @ RuhrJS17 @fischaelameer
myButton.addEventListener( 'click', function() { vrDisplay.requestPresent( [ { source: myCanvas } ] );});
geildanke.com @ RuhrJS17 @fischaelameer
myButton.addEventListener( 'click', function() { vrDisplay.requestPresent( [ { source: myCanvas } ] ) .then( function() { vrDisplay.requestAnimationFrame( render ); });});
geildanke.com @ RuhrJS17 @fischaelameer
function render() { vrDisplay.requestAnimationFrame( render );
}
geildanke.com @ RuhrJS17 @fischaelameer
function render() { vrDisplay.requestAnimationFrame( render );
// update display pose // update scene and meshes
}
geildanke.com @ RuhrJS17 @fischaelameer
let pose = vrDisplay.getPose();
console.log( pose.orientation );// [ 0, 0, 0, 1 ]// [ -0.0000724312, -0.06752134, 0.0028374712, 0.9977243 ]console.log( pose.position );// null// [ 0.05234, -0.043485, 0.0003243 ]
geildanke.com @ RuhrJS17 @fischaelameer
let leftEyeParameters = vrDisplay.getEyeParameters( 'left' );
console.log( leftEyeParameters.offset );// [ -0.03, 0, 0 ]console.log( leftEyeParameters.renderWidth );// 640.5console.log( leftEyeParameters.renderHeight );// 721
geildanke.com @ RuhrJS17 @fischaelameer
function render() { vrDisplay.requestAnimationFrame( render );
// update display pose // update scene and meshes
vrDisplay.submitFrame( pose );}
geildanke.com @ RuhrJS17 @fischaelameer
geildanke.com @ RuhrJS17 @fischaelameer
geildanke.com @ RuhrJS17 @fischaelameer
Browser
WebGL WebVR
three.js WebVR Polyfill
geildanke.com @ RuhrJS17 @fischaelameer
Browser
WebGL WebVR
three.js WebVR Polyfill
A-Frame
geildanke.com @ RuhrJS17 @fischaelameer
Browser
WebGL WebVR
three.js WebVR Polyfill
A-FrameReact VR
geildanke.com @ RuhrJS17 @fischaelameer
<head> <script src="aframe.js"></script></head><body> <a-scene> <a-assets> <video id="video" src="video.mp4" autoplay loop></video> </a-assets> <a-videosphere src="#video"></a-videosphere> </a-scene></body>
geildanke.com @ RuhrJS17 @fischaelameer
<head> <script src="aframe.js"></script></head><body> <a-scene> <a-assets> <video id="video" src="video.mp4" autoplay loop></video> </a-assets> <a-videosphere src="#video"></a-videosphere> </a-scene></body>
geildanke.com @ RuhrJS17 @fischaelameer
<head> <script src="aframe.js"></script></head><body> <a-scene> <a-assets> <video id="video" src="video.mp4" autoplay loop></video> </a-assets> <a-videosphere src="#video"></a-videosphere> </a-scene></body>
geildanke.com @ RuhrJS17 @fischaelameer
<head> <script src="aframe.js"></script></head><body> <a-scene> <a-assets> <video id="video" src="video.mp4" autoplay loop></video> </a-assets> <a-videosphere src="#video"></a-videosphere> </a-scene></body>
<a-box> <a-cone> <a-cylinder> <a-dodecahedron><a-icosahedron> <a-octahedron> <a-ring> <a-sphere><a-tetrahedron> <a-torus-knot> <a-torus>
geildanke.com @ RuhrJS17 @fischaelameer
<a-video> <a-videosphere> <a-image> <a-sound><a-gltf-model> <a-obj-model> <a-text><a-light> <a-sky> <a-cursor>
<a-box> <a-cone> <a-cylinder> <a-dodecahedron><a-icosahedron> <a-octahedron> <a-ring> <a-sphere><a-tetrahedron> <a-torus-knot> <a-torus>
geildanke.com @ RuhrJS17 @fischaelameer
import React from 'react';import { AppRegistry, VideoPano, View } from 'react-vr';
class GEILDANKE_REACTVR_PANO extends React.Component { render() { return ( <View> <VideoPano source={{uri: 'video.mp4'}} /> </View> ); }};
AppRegistry.registerComponent('GEILDANKE_REACTVR_PANO', () => GEILDANKE_REACTVR_PANO);
geildanke.com @ RuhrJS17 @fischaelameer
import React from 'react';import { AppRegistry, VideoPano, View } from 'react-vr';
class GEILDANKE_REACTVR_PANO extends React.Component { render() { return ( <View> <VideoPano source={{uri: 'video.mp4'}} /> </View> ); }};
AppRegistry.registerComponent('GEILDANKE_REACTVR_PANO', () => GEILDANKE_REACTVR_PANO);
geildanke.com @ RuhrJS17 @fischaelameer
import React from 'react';import { AppRegistry, VideoPano, View } from 'react-vr';
class GEILDANKE_REACTVR_PANO extends React.Component { render() { return ( <View> <VideoPano source={{uri: 'video.mp4'}} /> </View> ); }};
AppRegistry.registerComponent('GEILDANKE_REACTVR_PANO', () => GEILDANKE_REACTVR_PANO);
geildanke.com @ RuhrJS17 @fischaelameer
Box Cylinder CylindricalPanel Plane Sphere
AmbientLight DirectionalLight PointLight SpotLight
Model Sound VrButton
Pano Video VideoPano
geildanke.com @ RuhrJS17 @fischaelameer
geildanke.com @ RuhrJS17 @fischaelameer
Browser
WebGL WebVR
three.js WebVR Polyfill
React VR A-Frame
geildanke.com @ RuhrJS17 @fischaelameer
Browser
WebGLGamepad WebVR
three.js WebVR Polyfill
React VR A-Frame
geildanke.com @ RuhrJS17 @fischaelameer
Browser
WebGLGamepad Audio WebVR
three.js WebVR Polyfill
React VR A-Frame
geildanke.com @ RuhrJS17 @fischaelameer
Browser
WebGLGamepad Audio WebVR Speech
three.js WebVR Polyfill
React VR A-Frame
geildanke.com @ RuhrJS17 @fischaelameer
Libraries Like React VRWill Not Fix Your UX Design
geildanke.com @ RuhrJS17 @fischaelameer
Comfort
Interpretability
Usefulness
Delight
Beau Cronin
https://medium.com/@beaucronin/the-hierarchy-of-needs-in-virtual-reality-development-4333a4833acc
geildanke.com @ RuhrJS17 @fischaelameer
PresenceComfort
Interpretability
Usefulness
Delight
Beau Cronin
https://medium.com/@beaucronin/the-hierarchy-of-needs-in-virtual-reality-development-4333a4833acc
geildanke.com @ RuhrJS17 @fischaelameer
Presence Comfort
Interpretability
Usefulness
Delight
Safety
geildanke.com @ RuhrJS17 @fischaelameer
UX Design For WebVRComfort & Ergonomics
geildanke.com @ RuhrJS17 @fischaelameer
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.
http://www.commercekitchen.com/whedon-ipsum/
geildanke.com @ RuhrJS17 @fischaelameer
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.
http://www.commercekitchen.com/whedon-ipsum/
geildanke.com @ RuhrJS17 @fischaelameer
geildanke.com @ RuhrJS17 @fischaelameer
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.
http://www.commercekitchen.com/whedon-ipsum/
geildanke.com @ RuhrJS17 @fischaelameer
geildanke.com @ RuhrJS17 @fischaelameer
geildanke.com @ RuhrJS17 @fischaelameer
geildanke.com @ RuhrJS17 @fischaelameer
geildanke.com @ RuhrJS17 @fischaelameer
130°
Comfortably bending 30° to each side
geildanke.com @ RuhrJS17 @fischaelameer
Stretching 80° to each side
https://www.youtube.com/watch?v=00vzW2-PvvE
geildanke.com @ RuhrJS17 @fischaelameer
~10ppd
60ppd
Today’s Pixel Density
Optimal Pixel Density
geildanke.com @ RuhrJS17 @fischaelameer
geildanke.com @ RuhrJS17 @fischaelameer
geildanke.com @ RuhrJS17 @fischaelameerhttps://www.youtube.com/watch?v=ES9jArHRFHQ
geildanke.com @ RuhrJS17 @fischaelameer
https://sizecalc.com
https://sizecalc.com
geildanke.com @ RuhrJS17 @fischaelameer
Do Not Move Things FastTowards the Camera.
Do Not Trigger Phobias.
geildanke.com @ RuhrJS17 @fischaelameer
Do Not Attach ThingsNear the Camera.
Respect the Personal Space.
geildanke.com @ RuhrJS17 @fischaelameerIcon made by Freepik from www.flaticon.com
geildanke.com @ RuhrJS17 @fischaelameerIcon made by Freepik from www.flaticon.com
geildanke.com @ RuhrJS17 @fischaelameer
Do Not Use Acceleration.
https://web.colby.edu/cogblog/2016/05/09/2451/
geildanke.com @ RuhrJS17 @fischaelameer
Do Not Use Acceleration.
https://web.colby.edu/cogblog/2016/05/09/2451/
geildanke.com @ RuhrJS17 @fischaelameer
Do Not Move the Horizon Or the Camera.
Do Not Use Acceleration.
https://web.colby.edu/cogblog/2016/05/09/2451/
geildanke.com @ RuhrJS17 @fischaelameer
Do Not Move the Horizon Or the Camera.
Do Not Use Acceleration.
Keep a Low Latency And a High Framerate.
https://web.colby.edu/cogblog/2016/05/09/2451/
geildanke.com @ RuhrJS17 @fischaelameer
Add a Stable Focus Point.
http://vtrav.com/2015/04/nose-reduces-simulator-sickness/
geildanke.com @ RuhrJS17 @fischaelameer
Add a Stable Focus Point.
http://vtrav.com/2015/04/nose-reduces-simulator-sickness/
geildanke.com @ RuhrJS17 @fischaelameer
Avoid Flicker Or Blur.
Add a Stable Focus Point.
http://vtrav.com/2015/04/nose-reduces-simulator-sickness/
geildanke.com @ RuhrJS17 @fischaelameer
Avoid Flicker Or Blur.
Add a Stable Focus Point.
Support Short Usage.http://vtrav.com/2015/04/nose-reduces-simulator-sickness/
geildanke.com @ RuhrJS17 @fischaelameer
Abstract Patterns Are Better Than Realistic Ones.
https://blog.mozvr.com/a-painter/ http://www.kotaku.co.uk/2016/12/16/the-state-of-virtual-reality-in-2016
geildanke.com @ RuhrJS17 @fischaelameer
Abstract Patterns Are Better Than Realistic Ones.
https://blog.mozvr.com/a-painter/ http://www.kotaku.co.uk/2016/12/16/the-state-of-virtual-reality-in-2016
geildanke.com @ RuhrJS17 @fischaelameer
You Are Responsible For The Well-Being Of Your Users.
geildanke.com @ RuhrJS17 @fischaelameer
https://www.reddit.com/r/Vive/comments/4i49d3/when_instinct_takes_over/
https://www.reddit.com/r/VRFail/comments/4s7nc1/friend_loses_his_vrginity_and_then_some_crappy/
geildanke.com @ RuhrJS17 @fischaelameer
https://www.reddit.com/r/Vive/comments/4i49d3/when_instinct_takes_over/
https://www.reddit.com/r/VRFail/comments/4s7nc1/friend_loses_his_vrginity_and_then_some_crappy/
geildanke.com @ RuhrJS17 @fischaelameer
You Are Responsible For The Well-Being Of Your Users.
geildanke.com @ RuhrJS17 @fischaelameer
http://www.uxofvr.com/
https://webvr.rocks/
General Information
https://webvr-slack.herokuapp.com/
Community
https://www.reddit.com/r/WebVR/
https://w3c.github.io/webvr/
https://github.com/googlevr/webvr-polyfill
https://threejs.org/
API, Frameworks, Libraries
https://facebook.github.io/react-vr/
https://aframe.io/
https://geildanke.com/en/vr/
Geil,Danke!
https://bit.ly/webvrcomet