Want to build a compelling 3D interactive experience that anyone can instantly access through their browser? You’ve come to the right place! We just released a new VR demo that makes it really easy to start building right away. Built with Mozilla’s WebVR API, VR Quickstart features position and orientation tracking, Leap Motion interaction, and code that’s been broken down to bite-sized pieces.

vr-quickstart-webvr-javascript-virtual-reality

Building with Mozilla’s WebVR API

As we saw recently, Mozilla is providing the Oculus integration out of the box with a special VR Firefox build, and Chrome builds are available here: Chrome WebVR. VR Quickstart is the second demo we’ve built using the WebVR API – VRCollage being the first.

To work, the demo requires the latest build of Firefox’s VR beta. It uses Three.js, LeapJS 0.6.3+, and LeapJS Plugins 0.1.9+ (which we updated for this very purpose). The code is in a single file, broken down into sections for ease of use:

  • create the scene
  • add cubes
  • add Leap Motion
  • add virtual reality
  • make it go! (the render loop)

When you setup the demo, we recommend that you lock your Oculus display to 60Hz, as this is what Firefox currently supports. (On Mac, you can accomplish this through the Display System Preferences, seen in the image below.)

oculus-display-60hz

You might notice that units are all converted to meters – this is very important for correct eye positions. Here’s the Leap Motion part of the demo, which brings in the bone hand (constructed from cylinders and spheres) with just a few lines of code:

//
// ADD LEAP MOTION
//
//

// Connect to localhost and start getting frames
Leap.loop();

// Docs: http://leapmotion.github.io/leapjs-plugins/main/transform/
Leap.loopController.use('transform', {

  // This matrix flips the x, y, and z axis, scales to meters, and offsets the hands by -8cm.
  vr: true,

  // This causes the camera's matrix transforms (position, rotation, scale) to be applied to the hands themselves
  // The parent of the bones remain the scene, allowing the data to remain in easy-to-work-with world space.
  // (As the hands will usually interact with multiple objects in the scene.)
  effectiveParent: camera

});

// Docs: http://leapmotion.github.io/leapjs-plugins/main/bone-hand/
Leap.loopController.use('boneHand', {

  // If you already have a scene or want to create it yourself, you can pass it in here
  // Alternatively, you can pass it in whenever you want by doing
  // Leap.loopController.plugins.boneHand.scene = myScene.
  scene: scene,

  // Display the arm
  arm: true

});

Looking for an alternative approach?

You can also build an experience that works on all modern browsers, but there is a trade-off – as the currently existing libraries don’t provide positional tracking. If this is the approach you want to take, here are the components you would need:

OculusRiftEffect. This renders the lense effect with Three.js:

// setting up
effect = new THREE.OculusRiftEffect(renderer, {
  worldScale: 2
});

effect.setSize(window.innerWidth, window.innerHeight);

// when resizing:
effect.setSize(window.innerWidth, window.innerHeight)

// when rendering:
effect.render(scene, camera);
Optimize HMD

OculusControls. This takes position and orientation data from your Oculus to your web app, over a user-installed REST server.

Components

Optimize HMD. This tells tracking to optimize for head-mounted tracking mode, and should be used any time the Leap is used on a VR headset like the Oculus Rift.  Conveniently, most of the time you won’t have to set this yourself, as this is handled by setting the `vr` option on the `transform` plugin above.

// optimizeHMD optimizes the Leap Motion tracking for seeing the backs of hands from above.  It doesn’t require background mode, but the flag is seen here as a nice convenience.
new Leap.Controller({
  optimizeHMD: true
});

Transform.  This allows arbitrary transformation of Leap Motion frame data. The `vr` option makes sure that your hand won’t appear upside-up in the scene when head-mounted. The `effectiveParent` option makes the hand movement be relative to the parent object, such as the camera.

Bone Hand. As I mentioned before, this adds a hand to your Three.js scene, constructed from cylinders and spheres. You can either give it a DOM element, and it will add a scene and do all the Three.js work, or you can pass in a scene of your own. Here’s some config:

// set up the hand
controller.use('boneHand', {
  scene: myScene,
  opacity: 0.7,
  jointColor: new THREE.Color(0x222222),
  arm: true
})

However, if you don’t pass in your own scene, you can access the default one (as well as the renderer, camera, etc.).

var scene = controller.plugins.boneHand.scene

Remember to check out our full list of official LeapJS plugins (and fun developer examples) to help you get started on the wild road to JavaScript-based VR. Any questions? Post on the community forum.

Want to learn how to build a throw in WebVR? In a January Twitch talk, Peter walks through building a simple demo to throw a rock into 3D space, plus a sneak peek at some of our latest web projects:

For cutting-edge projects and demos, tune in every Tuesday at 5pm PT to twitch.tv/leapmotiondeveloper. To make sure you never miss an episode, enter your email address to subscribe to up-to-the-minute Twitch updates:



Alex is the head writer and blog editor at Leap Motion, where he stands as the final bulwark against bad grammar. Want to share your Leap Motion project? Email acolgan@leapmotion.com or PM leapmotion_alex on Reddit.

Twitter Skype  

Peter is a software engineer at Leap Motion who loves to practice web development and bring the power of LeapJS to everyone.

Twitter