这是一个最小的示例,它重现了我在更复杂的情况下遇到的问题:
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,这种使用模式应该没问题。那么为什么动画帧回调永远不会被调用呢?
如果尚未正确配置渲染,
XRSession
将不会调用动画帧回调。要正确配置会话,您需要:
const canvas = document.createElement("canvas");
const gl = canvas.getContext("webgl2", { xrCompatible: true });
XRWebGLLayer
。这允许 WebXR 与我们的 WebGL 上下文交互。const glLayer = new XRWebGLLayer(session, gl);
session.updateRenderState({ baseLayer: glLayer });
现在将运行动画帧回调。您甚至不必实际渲染任何内容!
XRSession.updateRenderState
的信息。