webxr API
WebXR 设备 API提供对虚拟现实 (VR) 和增强现实 (AR) 设备相关的输入和输出功能的访问。它允许你在web上开发和托管 VR 、 AR 体验。
为什么要使用webxr API
为方便开发提供了如下能力:
- 检测 XR 功能是否可用。
- 查询 XR 设备能力。
- 轮询 XR 设备和关联的输入设备状态。
- 以适当的帧速率在 XR 设备上显示图像。
简易步骤
一、检查是否支持
//检查 navigator 中是否包含 xr
if ('xr' in navigator){
//检查 沉浸式VR 是否支持
navigator.xr.isSessionSupported('immersive-vr').then(function (supported) {
console.log(`沉浸式VR 是否支持 = ${supported}`);
});
}else {
if (window.isSecureContext === false) {
console.log(`WEBXR 需要 HTTPS`);
} else {
console.log(`WEBXR 不可用`);
}
}
二、获取XRSession
let sessionInit = { optionalFeatures: ['local-floor', 'bounded-floor', 'hand-tracking', 'layers'] };
//请求 获取XRSession 对象
const session = await navigator.xr.requestSession('immersive-vr', sessionInit);
三、XRSession相关事件监听
//XRSession
let session: XRSession;
//XRSession 相关事件监听
session.addEventListener('select', onSessionEvent);
session.addEventListener('selectstart', onSessionEvent);
session.addEventListener('selectend', onSessionEvent);
session.addEventListener('squeeze', onSessionEvent);
session.addEventListener('squeezestart', onSessionEvent);
session.addEventListener('squeezeend', onSessionEvent);
session.addEventListener('end', onSessionEndSuc);
session.addEventListener('inputsourceschange', onInputSourcesChange);
四、初始化 XRWebGLLayer 设置 XRSession RenderState
//当前使用的canvas webgl上下文
const gl : WebGL2RenderingContext;
const attributes = gl.getContextAttributes();
//确保要使用canvas上下文与当前xr设备兼容。
if (!attributes.xrCompatible) {
await gl.makeXRCompatible();
}
const layerInit = {
antialias: (session.renderState.layers === undefined) ? attributes.antialias : true,
alpha: attributes.alpha,
depth: attributes.depth,
stencil: attributes.stencil,
framebufferScaleFactor: 1
};
//初始化 XRWebGLLayer
const glBaseLayer = new XRWebGLLayer(session, gl, layerInit);
//设置 RenderState
session.updateRenderState({
baseLayer: glBaseLayer,
depthFar: 1000,
depthNear: 0,
// inlineVerticalFieldOfView: 105
});
五、 请求获取 XRReferenceSpace
//获取referenceSpace
const referenceSpace = await session.requestReferenceSpace("local-floor");
六、 XRSession 启动 requestAnimationFrame 循环,XRFrame 获取view pose,调整相机,渲染。
const loop = (time: number, xrFrame: XRFrame)=>{
const pose = xrFrame.getViewerPose(referenceSpace);
//同步 传感器到场景相机
if (pose) {
const views = pose.views;
const isVR = views.length == 2;
if (isVR) {
//layer.framebuffer 存在时将 画面绘制到 layer.framebuffer
gl.bindFramebuffer(gl.FRAMEBUFFER, glBaseLayer.framebuffer);
for (let i = 0; i < 2; i++) {
//相机信息
const view = views[i];
//获取 设备 相机 viewport
const viewport = glBaseLayer.getViewport(view);
//设置到 webgl 上下文
gl.viewport(viewport.x, viewport.y , viewport.width , viewport.height );
//相机位移
view.transform.position;
//相机旋转
view.transform.orientation;
//相机投影矩阵
view.projectionMatrix;
//渲染一帧场景
renderSence();
}
}
session.requestAnimationFrame(loop);
}
//启动循环
session.requestAnimationFrame(loop);
网友评论