VRDisplay.getFrameData 已被废弃,WebVR API 被 W3C 正式弃用,Chrome 91+、Firefox 95+、Edge 93+ 均已移除支持;现唯一标准是 WebXR,需用 XRFrame.getViewerPose() 获取位姿,并通过 pose.views 获取左右眼的 projectionMatrix 和视图矩阵。

VRDisplay.getFrameData 已被废弃,别再用了
直接说结论:VRDisplay.getFrameData 是 WebVR API 的方法,而 WebVR 已被 W3C 正式废弃,所有主流浏览器(Chrome 91+、Firefox 95+、Edge 93+)均已移除支持。调用它会抛出 TypeError: Failed to execute 'getFrameData' on 'VRDisplay': Cannot access VRDisplay from this context 或直接返回 undefined。现在唯一标准路径是 WebXR API。
替代方案:用 XRFrame.getViewerPose 取头显位姿数据
WebXR 中不再有 VRDisplay,而是通过 XRSession 和每帧的 XRFrame 获取数据。关键入口是 XRFrame.getViewerPose(),它返回包含位置、朝向、视图矩阵等信息的 XRViewerPose。
常见使用条件:
- 必须在用户手势触发的上下文中启动 session(如
button.addEventListener('click', () => xrSession = await xrRef.requestSession('immersive-vr'))) - 需提前调用
navigator.xr.isSessionSupported('immersive-vr')检查支持性 -
getViewerPose()的参数必须是已绑定到该 session 的XRReferenceSpace(通常用session.requestReferenceSpace('local-floor')创建)
let refSpace;
let xrSession;
button.addEventListener('click', async () => {
xrSession = await navigator.xr.requestSession('immersive-vr');
refSpace = await xrSession.requestReferenceSpace('local-floor');
xrSession.requestAnimationFrame(onXRFrame);
});
function onXRFrame(time, frame) {
const pose = frame.getViewerPose(refSpace);
if (pose) {
const transform = pose.transform; // 包含 position 和 orientation
console.log('position:', transform.position);
console.log('orientation:', transform.orientation);
}
xrSession.requestAnimationFrame(onXRFrame);
}
如何拿到左右眼渲染所需的投影和视图矩阵
单靠 getViewerPose() 只能得到“人眼中心”的姿态。真要渲染双目画面,得遍历 pose.views —— 它是一个数组,长度通常为 2(left 和 right),每个元素含 projectionMatrix 和 transform(即该眼的视图矩阵)。
立即学习“前端免费学习笔记(深入)”;
注意点:
-
pose.views仅在getViewerPose()成功且pose !== null时存在 - 不同设备返回的 view 顺序不固定,应检查
view.eye字段(值为'left'或'right'),不要硬写索引[0]/[1] -
projectionMatrix是 Float32Array(16 个元素),不是DOMMatrix,需传给 WebGL uniform 时用gl.uniformMatrix4fv
const pose = frame.getViewerPose(refSpace);
if (pose && pose.views.length > 0) {
for (const view of pose.views) {
const eye = view.eye; // 'left' | 'right'
const proj = view.projectionMatrix; // Float32Array[16]
const viewMat = view.transform.inverse.matrix; // 视图矩阵(逆变换后)
// ……传给着色器
}
}
常见报错和兼容性兜底建议
开发中容易卡在这几个地方:
-
InvalidStateError: Cannot call getViewerPose before reference space is set→ 忘了先requestReferenceSpace,或 space 还没 resolve 就进 loop -
TypeError: Cannot read property 'views' of null→getViewerPose()返回 null(比如用户把头显摘了、权限被拒、session 被中断),必须判空 - 桌面 Chrome 测试时无 VR 设备 → 用
chrome://flags/#enable-webxr开启 WebXR,并启用WebXR Incubations;或用 webxr-tester 模拟 - 移动端 Safari 不支持 immersive-vr → 目前只支持
'inline'模式,无法进入全屏 VR,这是 Apple 的策略限制,无法绕过
真实项目里,别只写 immersive-vr 分支。至少加上 inline 回退路径,并用 XRSession.end 做清理,否则内存泄漏和重复绑定很常见。











