XRSession:requestAnimationFrame() 方法
XRSession
方法 requestAnimationFrame()
与同名的 Window
方法类似,它计划在浏览器下次准备好将会话的虚拟环境绘制到 XR 显示器时执行回调。指定的回调将在下次重绘之前执行一次;如果您希望它在下一次重绘时执行,则必须再次调用 requestAnimationFrame()
。这可以在回调本身中完成。
回调以两个参数作为输入:一个 XRFrame
,描述会话中所有跟踪对象的当前状态,以及一个时间戳,您可以使用它来计算任何所需的动画更新。
您可以通过调用 cancelAnimationFrame()
取消先前计划的动画。
注意:尽管这些方法与 Window
接口提供的全局 requestAnimationFrame()
函数之间存在明显的相似之处,但您绝不能将它们视为可互换的。无法保证后者在沉浸式 XR 会话正在进行时能否正常工作。
语法
requestAnimationFrame(animationFrameCallback)
参数
animationFrameCallback
-
一个在下次重绘之前被调用的函数,以便您可以根据经过的时间、动画、用户输入的变化等更新和渲染 XR 场景。回调接收两个参数作为输入。
时间
-
一个
DOMHighResTimeStamp
,指示从 WebXR 设备接收更新的查看器状态的时间偏移量。 xrFrame
-
一个
XRFrame
对象,描述会话跟踪的对象的状态。这可以用于获取查看器和场景本身的姿势,以及渲染 AR 或 VR 场景帧所需的其它信息。
返回值
一个整数值,用作唯一的非零 ID 或句柄,如果您需要移除挂起的动画帧请求,则可以将其传递给 cancelAnimationFrame()
。
示例
以下示例使用“内联”模式请求 XRSession
,以便它可以显示在 HTML 元素中(无需单独的 AR 或 VR 设备)。
注意: 实际应用应该检查设备和用户代理是否都支持 WebXR API,然后检查它们是否都支持通过 XRSystem.isSessionSupported()
所需的会话类型。
// Obtain XR object
const XR = navigator.xr;
// Request a new XRSession
XR.requestSession("inline").then((xrSession) => {
xrSession.requestAnimationFrame((time, xrFrame) => {
const viewer = xrFrame.getViewerPose(xrReferenceSpace);
gl.bindFramebuffer(xrWebGLLayer.framebuffer);
for (const xrView of viewer.views) {
const xrViewport = xrWebGLLayer.getViewport(xrView);
gl.viewport(
xrViewport.x,
xrViewport.y,
xrViewport.width,
xrViewport.height,
);
// WebGL draw calls will now be rendered into the appropriate viewport.
}
});
});
以下示例直接取自规范草案。此示例演示了一种设计模式,该模式可确保通过 Window.requestAnimationFrame
创建的非沉浸式动画与沉浸式 XR 动画之间无缝转换。
let xrSession = null;
function onWindowAnimationFrame(time) {
window.requestAnimationFrame(onWindowAnimationFrame);
// This may be called while an immersive session is running on some devices,
// such as a desktop with a tethered headset. To prevent two loops from
// rendering in parallel, skip drawing in this one until the session ends.
if (!xrSession) {
renderFrame(time, null);
}
}
// The window animation loop can be started immediately upon the page loading.
window.requestAnimationFrame(onWindowAnimationFrame);
function onXRAnimationFrame(time, xrFrame) {
xrSession.requestAnimationFrame(onXRAnimationFrame);
renderFrame(time, xrFrame);
}
function renderFrame(time, xrFrame) {
// Shared rendering logic.
}
// Assumed to be called by a user gesture event elsewhere in code.
function startXRSession() {
navigator.xr.requestSession("immersive-vr").then((session) => {
xrSession = session;
xrSession.addEventListener("end", onXRSessionEnded);
// Do necessary session setup here.
// Begin the session's animation loop.
xrSession.requestAnimationFrame(onXRAnimationFrame);
});
}
function onXRSessionEnded() {
xrSession = null;
}
规范
规范 |
---|
WebXR 设备 API # dom-xrsession-requestanimationframe |
浏览器兼容性
BCD 表格仅在浏览器中加载