Three.js is a cross-browser JavaScript library used to create and display animated 3D computer graphics in a web browser. It has a large community, good docs, and many examples.
Using VR is largely the same as regular Three.js applications. Setup the scene, camera, and renderer. The major difference is setting the vr.enabled flag to true on the renderer. There is an optional VRButton class to make a button that will enter and exit VR for you.
For more info, see this guide to VR in Three.js and the WebXR examples.
Here is a full example that sets up a scene with a rotating red cube.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
body {
margin: 0;
background-color: #000;
}
canvas {
display: block;
}
</style>
</head>
<body>
<script type="module">
// Import three
import * as THREE from 'https://unpkg.com/three/build/three.module.js';
// Import the default VRButton
import { VRButton } from 'https://unpkg.com/three/examples/jsm/webxr/VRButton.js';
// Make a new scene
let scene = new THREE.Scene();
// Set background color of the scene to gray
scene.background = new THREE.Color(0x505050);
// Make a camera. note that far is set to 100, which is better for realworld sized environments
let camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 100);
camera.position.set(0, 1.6, 3);
scene.add(camera);
// Add some lights
var light = new THREE.DirectionalLight(0xffffff,0.5);
light.position.set(1, 1, 1).normalize();
scene.add(light);
scene.add(new THREE.AmbientLight(0xffffff,0.5))
// Make a red cube
let cube = new THREE.Mesh(
new THREE.BoxBufferGeometry(1,1,1),
new THREE.MeshLambertMaterial({color:'red'})
);
cube.position.set(0, 1.5, -10);
scene.add(cube);
// Make a renderer that fills the screen
let renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
// Turn on VR support
renderer.vr.enabled = true;
// Set animation loop
renderer.setAnimationLoop(render);
// Add canvas to the page
document.body.appendChild(renderer.domElement);
// Add a button to enter/exit vr to the page
document.body.appendChild(VRButton.createButton(renderer));
// For AR instead, import ARButton at the top
// import { ARButton } from 'https://unpkg.com/three/examples/jsm/webxr/ARButton.js';
// then create the button
// document.body.appendChild(ARButton.createButton(renderer));
// Handle browser resize
window.addEventListener('resize', onWindowResize, false);
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function render(time) {
// Rotate the cube
cube.rotation.y = time / 1000;
// Draw everything
renderer.render(scene, camera);
}
</script>
</body>
</html>