Three.js 创建 VR 内容:四步把一个普通 3D 场景送进头显

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 应用,核心就这四件事:

  1. 引入 VRButton,在页面上放一个「进入 VR」按钮;
  2. 告诉 WebGLRenderer 开启 XR 渲染;
  3. 把动画循环从 requestAnimationFrame 换成 renderer.setAnimationLoop
  4. 把按钮挂到页面上。

下面逐一拆开讲,最后给一份能直接跑的最小代码。

二、第一步:引入 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)

延伸阅读

相关推荐
三十而立洋1 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁1 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄1 天前
JavaScript 隐式全局变量解析
javascript
沙蒿同学1 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端
paopaokaka_luck1 天前
智慧社区综合服务小程序(人脸识别、AI问答、Echarts图形化分析)
前端·javascript·spring boot·spring·数据分析·echarts
Hilaku1 天前
为什么死磕 1px 的团队,用户体验反而更差?
前端·javascript·程序员
陈拉斯1 天前
给公司年会写了个大屏抽奖系统:动画在前端跑,凭什么说结果没被改?
javascript
yzy851 天前
Vue中下载或打开文件的JavaScript方法
前端·javascript·vue
用户298698530141 天前
在 React 中用 JavaScript 将 Word 转换为文本
前端·javascript·react.js
Zldaisy3d1 天前
中南大学 | 热稳定纳米析出相助力增材制造Al-Fe-Cr-Sc-Zr合金400℃长期热暴露后室温强度保持
3d·制造