Virtual Reality in the Web

Sebastian Siemssen
Nik Graf

Virtual reality is inevitably going to become mainstream - it's only a question of how good it needs to be before the mainstream is willing to use it.

Palmer Luckey

Head tracking

Lenses

Screen

The critical pieces

Head mount

How do you make your users look like this?

Immersiveness through lens distortion

Lens*

Physical screen

Virtual Screen

With Lens

Without Lens

*Convex Fresnel Lens

Pincussion Distortion

Projected image

Perceived image

Barrel Distortion

Projected image

Perceived image

Pixel based

Mesh based

Geometry based

Computing a Barrel Distortion

The Oculus Thrift*

*Sparauge

https://w3c.github.io/webvr/

WebVR is an experimental JavaScript API that provides access to Virtual Reality devices, such as the Oculus Rift, HTC Vive, Samsung Gear VR, or Google Cardboard, in your browser.

Browser enthusiasm

Browser support

Browser installation and configuration instructions

Supported Web Browser

Polyfill

Mobile

Desktop

Virtual Reality Headset

Smartphone and Lenses

Requirements

WebVR

WebGL

Introduction to ReactVR

(Pre Release)

Let's create a VR scene?

yarn global add react-vr-cli

or

npm install -g react-vr-cli

Files

  • index.vr.js
  • node_modules
  • package.json
  • postinstall.js
  • rn-cli.config.js
  • static_assets/chess-world.jpg
  • vr/client.js
  • vr/index.html
  • yarn.lock
<!-- vr/index.html -->
<html>
  <head>
    <title>firstproject</title>
    <style>body { margin: 0; }</style>
  <head>
  <body>
    <script src="./client.bundle?platform=vr"></script>
    <script>
      ReactVR.init(
        '../index.vr.bundle?platform=vr&dev=true',
        document.body
      );
    </script>
  </body>
</html>
// vr/client.js
import {VRInstance} from 'react-vr-web';

function init(bundle, parent, options) {
  const vr = new VRInstance(
    bundle,
    'firstproject',
    parent,
    { ...options }
  );
  vr.render = function() {
    // Any custom behavior you want to perform
    // on each frame goes here
  };
  // Begin the animation loop
  vr.start();
  return vr;
}

window.ReactVR = {init};
// index.vr.js (part 1)
import React from 'react';
import {
  AppRegistry,
  asset,
  StyleSheet,
  Pano,
  Text,
  View
} from 'react-vr';
// index.vr.js (part 2)
class firstproject extends React.Component {
  render() { return (
    <View>
      <Pano source={asset('chess-world.jpg')}/>
      <Text style={{
        backgroundColor:'blue',
        textAlign:'center',
        textAlignVertical:'center',
        layoutOrigin: [0.5, 0.5],
        transform: [{translate: [0, 0, -3]}],
      }}>
        hello
      </Text>
    </View>
  )}
};

AppRegistry.registerComponent(
 'firstproject', () => firstproject
);
class firstproject extends React.Component {
  render() { return (
    <View>
      <Pano source={asset('agentconf.jpg')}/>
      <Text style={{
        fontSize: 0.4,
        layoutOrigin: [0.5, 0.5],
        transform: [{translate: [0, 0, -3]}],
      }}>
        Welcome to Agent.sh
      </Text>
    </View>
  )}
};

AppRegistry.registerComponent(
  'firstproject', () => firstproject
);

Let's create a
Virtual World

cube.obj

cube.mtl

<View>
  <PointLight style={{
    color:'white',
    transform:[{translate : [0, 400, 700]}]}}
  />
  <Pano source={asset('chess-world.jpg')}/>
  <Mesh
    style={{ transform: [
      {translate: [0, -5, -20]},
      {rotateY: -30},
      {rotateX: -40}
    ] }}
    source={{
      mesh: asset('cube2.obj'),
      mtl: asset('cube2.mtl'),
      lit: true
    }}
  />
</View>
// Tree.js
export default ({ style }) => (
  <View style={style}>
    <Mesh
      source={{
        mesh: asset('tree-trunk.obj'),
        mtl: asset('tree-trunk.mtl'),
        lit: true
      }}
      style={{ transform: [{scale: [0.6, 1, 0.6]}] }}
    />
    <Mesh
      source={{
        mesh: asset('tree-crown.obj'),
        mtl: asset('tree-crown.mtl'),
        lit: true
      }}
      style={{ transform: [{translate: [0, 2.5, 0]}] }}
    />
  </View>
);
// Forest.js Part 1
import { range, map, xprod, flatten } from 'ramda';
import Tree from './Tree';

const randomPosition = () => (Math.floor(Math.random() * 10) - 5);
const randomHeight = () => (Math.random() - 1);
const randomScale = () => (Math.random() * 0.25 + 1);

const grid = xprod(range(0, 10), range(0, 10));
const trees = grid.map((entry, index) => {
  return {
    x: entry[0] * 8 + randomPosition(),
    y: entry[1] * 8 + randomPosition(),
    id: index
  };
});
// Forest.js
export default ({ style }) => (
  <View style={style}>
    {trees.map((tree) => {
      const scale = randomScale();
      return (
        <Tree
          key={tree.id}
          style={{
            transform: [
              {scale: [scale, scale, scale]},
              {translate: [
                tree.x, randomHeight(),
                tree.y
              ]},
            ]
          }}
        />
      );
    })}
  </View>
);

Examples

https://github.com/nikgraf/webvr-expriments

What's next?

  • Stablising the APIs
  • Content creation
  • More users

Thank you!

WebVR

By Sebastian Siemssen

WebVR

  • 2,032