Three.js 创建 VR 内容:四步把一个普通 3D 场景送进头显
原文出处:Three.js Manual -- How to create VR content
本文基于官方手册「How to create VR content」章节整理,用通俗方式带你看懂:怎么用 Three.js 把已有的 WebGL 场景,接入 WebXR、戴进 VR 头显里看。
写在前面
你手里已经有一个跑得不错的 Three.js 场景了------有 Scene、有 Camera、有 WebGLRenderer,平时在浏览器里转得挺好。现在想让它进 VR 头显里看,是不是要大改?
答案是:几乎不用大改。Three.js 把 WebXR 的复杂细节封装得相当干净,你只需要动四处地方。这一篇就是一份极简上手指南,照着四步走,你的场景就能在头显里渲染了。
小提示:和 VR 对称的还有 AR(增强现实),Three.js 提供了
ARButton,用法和下面要讲的VRButton几乎一模一样,想做 AR 内容把VRButton换成ARButton即可。
一、整体工作流:四步上手
把 VR 接入一个 Three.js 应用,核心就这四件事:
- 引入
VRButton,在页面上放一个「进入 VR」按钮; - 告诉
WebGLRenderer开启 XR 渲染; - 把动画循环从
requestAnimationFrame换成renderer.setAnimationLoop; - 把按钮挂到页面上。
下面逐一拆开讲,最后给一份能直接跑的最小代码。
二、第一步:引入 VRButton
VRButton 是 Three.js 官方提供的辅助类,放在 addons 里。先把它 import 进来:
js
import { VRButton } from 'three/addons/webxr/VRButton.js';
注意路径:它在
three/addons/webxr/下,不是three/核心包。如果你用的是 npm 的three包,对应路径是three/examples/jsm/webxr/VRButton.js。
三、第二步:创建按钮并挂到页面
VRButton.createButton(renderer) 干了两件关键的事:
- 探测兼容性:它会生成一个按钮,只有在当前浏览器/设备支持 VR 时才是可点的「ENTER VR」;不支持时会显示提示文字(比如「VR NOT SUPPORTED」)。
- 自动管理会话 :用户一点按钮,它会帮你发起(以及退出)一个 VR
XRSession,你完全不用手写 WebXR 的requestSession那套复杂逻辑。
你只要把它 append 到页面里:
js
document.body.appendChild( VRButton.createButton( renderer ) );
划重点:这一步要在
renderer创建之后做,因为按钮内部需要读取 renderer 来发起会话。把 renderer「交给」按钮就行,别试图自己再造一个按钮去触发会话------那是重复造轮子,还容易踩坑。
四、第三步:开启渲染器的 XR 模式
接下来得明确告诉 WebGLRenderer:「我要做 XR 渲染了」。一行搞定:
js
renderer.xr.enabled = true;
这个开关默认是
false。不打开它,即使按钮能点、会话能起,渲染出来的也不会是双目立体、跟随头显姿态的 VR 画面。记得在第一次render之前设置好。
五、第四步:换掉动画循环(最容易漏的一步)
普通 Three.js 应用我们习惯这么写动画循环:
js
// ❌ VR 下不能用这套
window.requestAnimationFrame( animate );
在 VR 里,渲染节奏由头显的显示刷新率驱动,而不是浏览器的 requestAnimationFrame。所以必须改用 Three.js 提供的 renderer.setAnimationLoop():
js
renderer.setAnimationLoop( function () {
renderer.render( scene, camera );
} );
⚠️ 这是新人最容易踩的坑:沿用老的
requestAnimationFrame循环,结果画面要么不更新、要么姿态不动。记住------只要上了 WebXR,动画循环一律用setAnimationLoop,它会自动按头显节奏回调,并且内部正确驱动相机姿态。
六、完整最小代码
把上面四步拼起来,一个能进 VR 的最小骨架长这样:
js
import * as THREE from 'three';
import { VRButton } from 'three/addons/webxr/VRButton.js';
// 1. 你的常规场景(这里省略几何体细节)
const renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.setSize( window.innerWidth, window.innerHeight );
// 2. 开启 XR 渲染
renderer.xr.enabled = true;
// 3. 放「进入 VR」按钮
document.body.appendChild( VRButton.createButton( renderer ) );
// 场景、相机、物体的常规搭建
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.01, 20 );
// 4. VR 专用动画循环
renderer.setAnimationLoop( function () {
renderer.render( scene, camera );
} );
现实约束提醒:WebXR 必须在安全上下文(HTTPS,或 localhost)下运行,而且得有支持的设备(如 Meta Quest 通过浏览器访问、或连接了头显的 PC)。纯桌面浏览器没接头显时,按钮会显示不支持------这是正常的,不是代码写错了。
总结
创建 VR 内容的四步清单:
| 步骤 | 关键代码 | 作用 |
|---|---|---|
| 1. 引按钮 | import { VRButton } from 'three/addons/webxr/VRButton.js' |
引入 VR 入口控件 |
| 2. 挂按钮 | document.body.appendChild( VRButton.createButton( renderer ) ) |
生成可点按钮 + 自动管理会话 |
| 3. 开 XR | renderer.xr.enabled = true |
让渲染器进入 XR 模式 |
| 4. 换循环 | renderer.setAnimationLoop( ... ) |
用头显节奏驱动渲染(别用 rAF) |