Build Your First WebVR Experience with Three.js: A Step‑by‑Step Guide
This tutorial explains how to create a WebVR page using the WebVR API and three.js, covering VR and naked‑eye modes, required plugins, HTML setup, scene construction, camera, renderer, a rotating cube, and integration of VR controls, effects, and manager for a complete immersive experience.
Last year Google and Firefox standardized the WebVR API, enabling immersive web experiences that combine the web with virtual reality headsets. WebVR can operate in two modes: a full VR mode using head‑mounted displays (HMDs) and a naked‑eye mode that works with mouse or touch interactions.
Preparation
We will use three.js for WebGL rendering and the following JavaScript plugins:
three.min.js
webvr-polyfill.js
VRControls.js
VREffect.js
webvr-manager.js
HTML Skeleton
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0, shrink-to-fit=no">
<title>webVR-helloworld</title>
<style type="text/css">
* { margin:0; padding:0; }
html,body { height:100%; overflow:hidden; }
</style>
</head>
<body>
<script src="./vendor/three.min.js"></script>
<script src="./vendor/webvr-polyfill.js"></script>
<script src="./vendor/VRControls.js"></script>
<script src="./vendor/VREffect.js"></script>
<script src="./vendor/webvr-manager.js"></script>
<script src="./main.js"></script>
</body>
</html>Creating the 3D Scene
In main.js we build the scene step by step.
var scene = new THREE.Scene();Camera
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
scene.add(camera);Renderer
var renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xeeeeee);
document.body.appendChild(renderer.domElement);Cube Mesh
var geometry = new THREE.CubeGeometry(10, 10, 10);
var cubematerial = new THREE.MeshLambertMaterial({ color: 0xef6500, needsUpdate:true, opacity:1, transparent:true });
var cube = new THREE.Mesh(geometry, cubematerial);
cube.position.set(0, 100, -50);
cube.rotation.set(Math.PI/6, Math.PI/4, 0);
scene.add(cube);Animation Loop
function animate() {
cube.rotation.y += 0.01; // rotate cube
renderer.render(scene, camera);
requestAnimationFrame(animate);
}
animate();Adding WebVR Support
We initialize the VR controller, effect, and manager provided by the plugins.
var vrControls = new THREE.VRControls(camera);
var vrEffect = new THREE.VREffect(renderer);
var vrManager = new WebVRManager(renderer, vrEffect);Then we modify the animation loop to update the controller and let the manager render the scene.
function animate() {
cube.rotation.y += 0.01;
vrControls.update();
vrManager.render(scene, camera);
requestAnimationFrame(animate);
}
animate();Result
The page now displays a rotating cube that can be viewed in VR mode with a headset (e.g., Cardboard) or in naked‑eye mode using mouse drag or touch gestures. The implementation demonstrates the core workflow of building a WebVR application with three.js.
For the full source code and a live demo, see the links provided in the original article.
With the upcoming support from major browsers and the rollout of 5G networks, WebVR is poised to become a revolutionary way to browse, shop, and teach online.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Huawei Cloud Developer Alliance
The Huawei Cloud Developer Alliance creates a tech sharing platform for developers and partners, gathering Huawei Cloud product knowledge, event updates, expert talks, and more. Together we continuously innovate to build the cloud foundation of an intelligent world.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
