为什么提供给`XRSession.requestAnimationFrame()`的回调没有被调用?

问题描述 投票:0回答:1

这是一个最小的示例,它重现了我在更复杂的情况下遇到的问题:

let session;

const dummyRenderLoop = (time, frame) => {
    if (!session) 
      return;

    console.log("Render callback");
    
    // Continue loop
    session.requestAnimationFrame(dummyRenderLoop);
}

window.addEventListener("load", async () => {
    if (!await navigator.xr.isSessionSupported("immersive-vr")) 
      return;
    
    // Obtain a WebXR session
    session = await navigator.xr.requestSession("immersive-vr");
    if (!session) 
      return;
    
    // Session creation succeeded
    console.log("Have an XR session");
    
    session.onend = () => {
      console.log("End session");
      session = undefined;
    };
    
    // Initiate animation loop
    session.requestAnimationFrame(dummyRenderLoop);
});

我已经在 Chrome 129 中使用 WebXR 模拟器和真正的 VR 耳机尝试过此操作。在控制台中,我得到输出

Have an XR session
,但从未得到
Render callback
。根据 MDN,这种使用模式应该没问题。那么为什么动画帧回调永远不会被调用呢?

javascript asynchronous callback webxr
1个回答
0
投票

如果尚未正确配置渲染,

XRSession
不会调用动画帧回调。要正确配置会话,您需要:

  • 创建 WebGL 上下文。这提供了我们渲染图形所需的接口。
const canvas = document.createElement("canvas");
const gl     = canvas.getContext("webgl2", { xrCompatible: true });
  • 使用新上下文创建
    XRWebGLLayer
    。这允许 WebXR 与我们的 WebGL 上下文交互。
const glLayer = new XRWebGLLayer(session, gl);
  • 最后(这是重要的部分)配置当前会话以使用我们新的 WebGL 层。
session.updateRenderState({ baseLayer: glLayer });

现在将运行动画帧回调。您甚至不必实际渲染任何内容!

MDN 有更多关于

XRSession.updateRenderState
的信息。

© www.soinside.com 2019 - 2024. All rights reserved.