HTML5怎样用VRDisplay.getFrameData取VR数据_HTML5VR取数法【归总】

15次阅读

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

HTML5怎样用VRDisplay.getFrameData取VR数据_HTML5VR取数法【归总】

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(leftright),每个元素含 projectionMatrixtransform(即该眼的视图矩阵)。

立即学习前端免费学习笔记(深入)”;

注意点:

  • 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 nullgetViewerPose() 返回 null(比如用户把头显摘了、权限被拒、session 被中断),必须判空
  • 桌面 Chrome 测试时无 VR 设备 → 用 chrome://flags/#enable-webxr 开启 WebXR,并启用 WebXR Incubations;或用 webxr-tester 模拟
  • 移动端 safari 不支持 immersive-vr → 目前只支持 'inline' 模式,无法进入全屏 VR,这是 apple 的策略限制,无法绕过

真实项目里,别只写 immersive-vr 分支。至少加上 inline 回退路径,并用 XRSession.end 做清理,否则内存泄漏和重复绑定很常见。

text=ZqhQzanResources