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 |
瀏覽器相容性
載入中…