Home >Web Front-end >JS Tutorial >How to Build VR on the Web Today
Virtual reality is set to be worth up to $7 billion by 2020. The web is definitely not going to remain an exclusively 2D environment during this time. In fact, there are already a few simple ways to bring VR into the browser. It is also incredibly fun to work with!
To begin your development adventure into the Virtual Web, there are three potential ways to do this:
I’ll go over each one and show a short summary of how each works.
One of the ways that most browser based virtual reality projects work at the moment is via the deviceorientation browser event. This tells the browser how the device is oriented and allows the browser to pick up if it has been rotated or tilted. This functionality within a VR perspective allows you to detect when someone looks around and adjust the camera to follow their gaze.
To achieve a wonderful 3D scene within the browser, we use three.js, a JavaScript framework that makes it easy to create 3D shapes and scenes. It takes most of the complexity out of putting together a 3D experience and allows you to focus on what you are trying to put together within your scene.
I’ve written two demos here at SitePoint that use the Device Orientation method:
If you are new to three.js and how to put together a scene, I’d recommend taking a look at the above two articles for a more in depth introduction into this method. I will cover key concepts here, however it’ll be at a higher level.
The key components of each of these involve the following JavaScript files (you can get these files from the example demos above and also will find them in the three.js examples download):
The code to enable Device Orientation controls looks like so:
<span>function setOrientationControls(e) { </span> <span>if (!e.alpha) { </span> <span>return; </span> <span>} </span> controls <span>= new THREE<span>.DeviceOrientationControls</span>(camera, true); </span> controls<span>.connect(); </span> controls<span>.update(); </span> element<span>.addEventListener('click', fullscreen, false); </span> <span>window.removeEventListener('deviceorientation', setOrientationControls, true); </span><span>} </span><span>window.addEventListener('deviceorientation', setOrientationControls, true); </span> <span>function fullscreen() { </span> <span>if (container.requestFullscreen) { </span> container<span>.requestFullscreen(); </span> <span>} else if (container.msRequestFullscreen) { </span> container<span>.msRequestFullscreen(); </span> <span>} else if (container.mozRequestFullScreen) { </span> container<span>.mozRequestFullScreen(); </span> <span>} else if (container.webkitRequestFullscreen) { </span> container<span>.webkitRequestFullscreen(); </span> <span>} </span><span>}</span>
The DeviceOrientation event listener provides an alpha, beta and gamma value when it has a compatible device. If we don’t have any alpha value, it doesn’t change our controls to use Device Orientation so that we can use Orbit Controls instead.
If it does have this alpha value, then we create a Device Orientation control and provide it our camera variable to control. We also set it to set our scene to fullscreen if the user taps the screen (we don’t want to be staring at the browser’s address bar when in VR).
If that alpha value isn’t present and we don’t have access the device’s Device Orientation event, this technique instead provides a control to move the camera via dragging it around with the mouse. This looks like so:
controls <span>= new THREE<span>.OrbitControls</span>(camera, element); </span>controls<span>.target.set( </span> camera<span>.position.x, </span> camera<span>.position.y, </span> camera<span>.position.z </span><span>); </span>controls<span>.noPan = true; </span>controls<span>.noZoom = true;</span>
The main things that might be confusing from the code above is the noPan and noZoom. Basically, we don’t want to move physically around the scene via the mouse and we don’t want to be able to zoom in or out – we only want to look around.
In order to use the stereo effect, we define it like so:
effect <span>= new THREE<span>.StereoEffect</span>(renderer);</span>
Then on resize of the window, we update its size:
effect<span>.setSize(width, height);</span>
Within each requestAnimationFrame we set the scene to render through our effect:
effect<span>.render(scene, camera);</span>
That is the basics of how the Device Orientation style of achieving VR works. It can be effective for a nice and simple implementation with Google Cardboard, however it isn’t quite as effective on the Oculus Rift. The next approach is much better for the Rift.
Looking to access VR headset orientation like the Oculus Rift? WebVR is the way to do it at the moment. WebVR is an early and experimental Javascript API that provides access to the features of Virtual Reality devices like Oculus Rift and Google Cardboard. At the moment, it is available on Firefox Nightly and a few experimental builds of Mobile Chrome and Chromium. One thing to keep in mind is that it the spec is still in draft and is subject to change, so experiment with it but know that you may need to adjust things over time.
Overall, the WebVR API provides access to the VR device information via:
<span>function setOrientationControls(e) { </span> <span>if (!e.alpha) { </span> <span>return; </span> <span>} </span> controls <span>= new THREE<span>.DeviceOrientationControls</span>(camera, true); </span> controls<span>.connect(); </span> controls<span>.update(); </span> element<span>.addEventListener('click', fullscreen, false); </span> <span>window.removeEventListener('deviceorientation', setOrientationControls, true); </span><span>} </span><span>window.addEventListener('deviceorientation', setOrientationControls, true); </span> <span>function fullscreen() { </span> <span>if (container.requestFullscreen) { </span> container<span>.requestFullscreen(); </span> <span>} else if (container.msRequestFullscreen) { </span> container<span>.msRequestFullscreen(); </span> <span>} else if (container.mozRequestFullScreen) { </span> container<span>.mozRequestFullScreen(); </span> <span>} else if (container.webkitRequestFullscreen) { </span> container<span>.webkitRequestFullscreen(); </span> <span>} </span><span>}</span>
I won’t go into lots of technical details here (I’ll cover this in more detail in its own future SitePoint article!), if you’re interested in finding out more check out the WebVR editor’s draft. The reason I won’t go into detail with it is that there is a much easier method to implement the API.
This aforementioned easier method to implement the WebVR API is to use the WebVR Boilerplate from Boris Smus. It provides a good level of baseline functionality that implements WebVR and gracefully degrades the experience for different devices. It is currently the nicest web VR implementation I’ve seen. If you are looking to build a VR experience for the web, this is currently the best place to start!
To start using this method, download the WebVR Boilerplate on Github.
You can focus on editing the index.html and using all of the files in that set up, or you can implement the specific plugins into your own project from scratch. If you’d like to compare the differences in each implementation, I’ve migrated my Visualizing a Twitter Stream in VR with Three.js and Node example from above into a WebVR powered Twitter Stream in VR.
To include this project into your own from scratch, the files you’ll want to have are:
Implementing it requires only a few adjustments from the Device Orientation method. Here’s an overview for those looking to try this method:
The VR controls are quite simple to set up. We can just assign a new VRControls object to the controls variable we used earlier. The orbit controls and device orientation controls should not be necessary as the Boilerplate should now take care of browsers without VR capabilities. This means your scene should still work quite well on Google Cardboard too!
<span>function setOrientationControls(e) { </span> <span>if (!e.alpha) { </span> <span>return; </span> <span>} </span> controls <span>= new THREE<span>.DeviceOrientationControls</span>(camera, true); </span> controls<span>.connect(); </span> controls<span>.update(); </span> element<span>.addEventListener('click', fullscreen, false); </span> <span>window.removeEventListener('deviceorientation', setOrientationControls, true); </span><span>} </span><span>window.addEventListener('deviceorientation', setOrientationControls, true); </span> <span>function fullscreen() { </span> <span>if (container.requestFullscreen) { </span> container<span>.requestFullscreen(); </span> <span>} else if (container.msRequestFullscreen) { </span> container<span>.msRequestFullscreen(); </span> <span>} else if (container.mozRequestFullScreen) { </span> container<span>.mozRequestFullScreen(); </span> <span>} else if (container.webkitRequestFullscreen) { </span> container<span>.webkitRequestFullscreen(); </span> <span>} </span><span>}</span>
The effect is very similar to implement as the StereoEffect was. Just replace that effect with our new VREffect one:
controls <span>= new THREE<span>.OrbitControls</span>(camera, element); </span>controls<span>.target.set( </span> camera<span>.position.x, </span> camera<span>.position.y, </span> camera<span>.position.z </span><span>); </span>controls<span>.noPan = true; </span>controls<span>.noZoom = true;</span>
However, we do not render through that effect in this method. Instead, we render through our VR manager.
The VR manager takes care of all our VR entering/exiting and so forth, so this is where our scene is finally rendered. We initially set it up via the following:
effect <span>= new THREE<span>.StereoEffect</span>(renderer);</span>
The VR manager provides a button which lets the user enter VR mode if they are on a compatible browser, or full screen if their browser isn’t capable of VR (full screen is what we want for mobile). The hideButton parameter says whether we want to hide that button or not. We definitely do not want to hide it!
Our render call then looks like so, it uses a timestamp variable that comes from our three.js’ update() function:
effect<span>.setSize(width, height);</span>
With all of that in place, you should have a working VR implementation that translates itself into various formats depending on the device.
Is renderer.getSize() returning an error? This drove me mad for a few hours but all you’ll need to do to fix this is – update three.js!
Here is what the view of my Twitter example looks like on a browser which supports VR:
Here is it within the Oculus Rift view that appears when you click the VR icon:
This is what the view looks like on a smartphone, device orientation still allows us to look around the scene and we don’t have a split screen. A great responsive view of the content:
If we click the VR icon on mobile, we get a fullscreen view for Google Cardboard style devices:
Mozilla is aiming to bring VR viewing capabilities to its browser in the Firefox Nightly versions too, however it is quite early days! I haven’t had much luck getting it to work on my Mac and Oculus set up. The sorts of conventions that Vladimir Vukićević from Firefox has mentioned includes integrating CSS 3D transforms with VR fullscreen mode.
As an example from Vladimir’s blog post, he says that elements with transform-style: preserve-3d should render twice from the two viewpoints to bring it into VR:
<span>function setOrientationControls(e) { </span> <span>if (!e.alpha) { </span> <span>return; </span> <span>} </span> controls <span>= new THREE<span>.DeviceOrientationControls</span>(camera, true); </span> controls<span>.connect(); </span> controls<span>.update(); </span> element<span>.addEventListener('click', fullscreen, false); </span> <span>window.removeEventListener('deviceorientation', setOrientationControls, true); </span><span>} </span><span>window.addEventListener('deviceorientation', setOrientationControls, true); </span> <span>function fullscreen() { </span> <span>if (container.requestFullscreen) { </span> container<span>.requestFullscreen(); </span> <span>} else if (container.msRequestFullscreen) { </span> container<span>.msRequestFullscreen(); </span> <span>} else if (container.mozRequestFullScreen) { </span> container<span>.mozRequestFullScreen(); </span> <span>} else if (container.webkitRequestFullscreen) { </span> container<span>.webkitRequestFullscreen(); </span> <span>} </span><span>}</span>
If you know of any demos using VR and CSS, please do let me know! I haven’t been able to track any down. The idea of bringing the HTML and CSS part of the web into VR is without a doubt a really intriguing concept. It’s inevitable that the web will enter the VR realm like this at some point as we all slowly shift to VR devices!
The world of technology is slowly but surely going to embrace Virtual Reality in the coming years as our technological capabilities match up with our wild aspirations! The one thing that will drive the VR adoption and its value is content. We need to get VR content out there for VR users to enjoy! What better and easier way is there than via the web?
If you take the plunge and build a VR demo using this code, please share it in the comments or get in touch with me on Twitter (@thatpatrickguy). I’d love to put on my Oculus Rift or Google Cardboard and take it for a spin!
I’ve got a set of curated links on VR and AR via JavaScript for those looking for a quick reference. Head over to Dev Diner and check out my Dev Diner VR and AR with JavaScript Developer Guide, full of both links mentioned in this article, other great SitePoint articles and more. If you’ve got other great resources I don’t have listed – please let me know too!
To start building VR on the web, you need to have a basic understanding of HTML, CSS, and JavaScript. You should also be familiar with WebGL, a JavaScript API for rendering 2D and 3D graphics. Knowledge of Three.js, a popular JavaScript library for creating 3D graphics, is also beneficial. Additionally, you should have a VR headset for testing your VR experiences.
JavaScript, along with libraries like Three.js and A-Frame, can be used to create VR experiences. Three.js simplifies the process of working with WebGL, while A-Frame allows you to build VR scenes using HTML-like syntax. You can create 3D objects, add textures and lighting, and control camera movement using these tools.
WebVR is a JavaScript API that provides support for various virtual reality devices, such as the Oculus Rift, HTC Vive, and Google Cardboard, in a web browser. It allows developers to create immersive VR experiences on the web that are accessible to anyone with a VR device and a compatible browser.
JavaScript is the primary language for web development, including VR. However, you can use languages that compile to JavaScript, such as TypeScript or CoffeeScript. Additionally, WebAssembly allows you to run code written in languages like C at near-native speed in the browser.
Optimizing VR experiences for the web involves reducing latency, managing memory efficiently, and optimizing rendering. You can use techniques such as asynchronous loading, texture compression, and level of detail (LOD) to improve performance. Also, consider the limitations of the user’s hardware and network conditions.
You can create fallbacks for users without VR devices. For example, you can use the DeviceOrientation API to allow users to explore the VR scene by moving their mobile device. You can also provide a 360-degree view that users can navigate with their mouse or touch.
You can test your VR experiences using a VR headset. If you don’t have a headset, you can use the WebVR emulator extension for Chrome and Firefox. This tool simulates the WebVR API and provides a 3D view of the VR scene.
You can use the glTF exporter in Three.js to export your 3D models in a format that A-Frame can read. glTF (GL Transmission Format) is a standard file format for 3D scenes and models.
Some challenges include handling user input in a 3D environment, optimizing performance, and ensuring compatibility across different VR devices and browsers. Additionally, creating realistic 3D graphics and animations can be complex.
There are many resources available online. Mozilla’s WebVR documentation is a great starting point. You can also check out tutorials and examples on the Three.js and A-Frame websites. Additionally, there are numerous online communities where you can ask questions and share your work.
The above is the detailed content of How to Build VR on the Web Today. For more information, please follow other related articles on the PHP Chinese website!