XRSession: requestAnimationFrame() 方法
与同名的 Window 方法类似,XRSession 方法 requestAnimationFrame() 会安排一个回调函数,在下次浏览器准备好将会话的虚拟环境绘制到 XR 显示器时执行。指定的 [回调函数](#animationframecallback) 会在下一次重绘之前执行一次;如果您希望它在后续的重绘时执行,您必须再次调用 requestAnimationFrame()。这可以在回调函数内部完成。
回调函数接受两个参数:一个 XRFrame,描述了会话中所有跟踪对象的 [状态](#xrframe);以及一个您可以用于计算任何所需动画更新的时间戳。
您可以通过调用 cancelAnimationFrame() 来取消先前调度的动画。
注意: 尽管这些方法与 Window 接口提供的全局 requestAnimationFrame() 函数有明显的相似之处,但您不得将它们视为可互换的。在沉浸式 XR 会话进行期间,不保证后者能够正常工作。
语法
requestAnimationFrame(animationFrameCallback)
参数
animationFrameCallback-
在下一次重绘之前调用的函数,以便您根据经过的时间、动画、用户输入更改等来更新和渲染 XR 场景。回调函数接收两个参数作为输入。
时间-
一个
DOMHighResTimeStamp,表示从 WebXR 设备接收到更新后的查看器状态的时间偏移量。 xrFrame-
一个
XRFrame对象,描述了会话正在跟踪的对象的 [状态](#xrframe)。这可用于获取查看器和场景本身的姿态,以及渲染 AR 或 VR 场景帧所需的其他信息。
返回值
一个整数值,作为唯一的非零 ID 或句柄,如果您需要删除挂起的动画帧请求,可以将其传递给 cancelAnimationFrame()。
示例
以下示例请求使用“inline”模式的 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 Device API # dom-xrsession-requestanimationframe |
浏览器兼容性
加载中…