web VR 功能 webxr API 接入指南

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);

参考

  • 沉浸式web webxr 讲解

你可能感兴趣的:(web VR 功能 webxr API 接入指南)