Go最新google glb 模型的 webXR 演示_dom overlay,2024年最新Golang程序员架构之路该如何继续学习

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

  // create and configure three.js renderer with XR support
    renderer = new THREE.WebGLRenderer({
      antialias: true,
      alpha: true,
      autoClear: true,
      context: gl,
    });
    renderer.setPixelRatio(window.devicePixelRatio);
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.xr.enabled = true;
    renderer.xr.setReferenceSpaceType('local');
    renderer.xr.setSession(session);

    // simple sprite to indicate detected surfaces
    reticle = new THREE.Mesh(
      new THREE.RingBufferGeometry(0.12, 0.15, 20).rotateX(-Math.PI / 2),
      new THREE.MeshPhongMaterial({ color: 0x0fff00 }),
    );
    // we will update it's matrix later using WebXR hit test pose matrix
    reticle.matrixAutoUpdate = false;
    reticle.visible = false;
    scene.add(reticle);
}
// closing intiScene

在上面的代码中,我们添加了矩形对象,这将有助于识别我们指向相机的表面区域。


reticle image

在 initScene 中设置完所有 threejs 之后,我们现在将开始做与 webxrSession 相关的事情,我们称之为 initScene。

如果没有用户交互,我们将无法启动 webxrSession 我们将首先在我们的 jsx 返回中添加一个按钮

const xrButton = useRef(null);

return (
// id xrOverlay will be used later
<div id="xrOverlay">
  <button id="xrbutton"  ref={xrButton} onClick={onXRButtonClick}> 
    Start experience
  </button>
</div> )

  function checkXR() {
    if (!window.isSecureContext) {
      // show message to use secure connection, 
      // webXR need https for giving device permission
    }
    if (navigator.xr) {
     xrButton?.current?.disabled = false;
    } else {
     xrButton?.current?.disabled = true
      // show message that this device or browser does not support webXR
    }
}

  React.useEffect(() => {
    checkXR();
  }, []);

我们添加了检查是否支持 XR 的功能。现在我们将处理启动 webXR 会话的主要部分,其中包含我们需要的命中和放置功能所需的功能。

我们将要求immersive session提供dom-overlay, local, and hit-test功能。

  • dom-overlay:它允许我们在会话时在屏幕上添加 html DOM 内容。
  • local:在会话开始时启用您的设备作为视图位置。
  • hit-test:它提供了我们击中并想要放置我们的 3D 模型的表面信息。

我们可以根据我们的需要请求更多功能,例如hand-tracking, depth sensing等。

 let xrSession = null;
  let xrRefSpace = null;
  let xrHitTestSource = null;

  function onXRButtonClick() {
    if (!xrSession) {
      navigator.xr
        .requestSession('immersive-ar', {
          optionalFeatures: ['dom-overlay'],
          requiredFeatures: ['local', 'hit-test'],
          domOverlay: { root: document.getElementById('xrOverlay') },
        })
        .then(onSessionStarted, onRequestSessionError);
    } else {
      xrSession.end();
    }
  }

我们已经通过document.getElementById(‘xrOverlay’)了,任何对此 DOM 的输入和交互都只能用于 xrSession 操作。

 function onSessionStarted(session) {
    setIsWebXRStarted(true);
    xrSession = session;

    // create a canvas element and WebGL context for rendering
    session.addEventListener('end', onSessionEnded);
    let canvas = document.createElement('canvas');
    gl = canvas.getContext('webgl', { xrCompatible: true });
    session.updateRenderState({ baseLayer: new XRWebGLLayer(session, gl) });

   // here we have register source from where we want to get hit test result in surronding         
    space
    session.requestReferenceSpace('viewer').then(refSpace => {
      session.requestHitTestSource({ space: refSpace }).then(hitTestSource => {
        xrHitTestSource = hitTestSource;
      });
    });

    session.requestReferenceSpace('local').then(refSpace => {
      xrRefSpace = refSpace;
      session.requestAnimationFrame(onXRFrame);
    });

// we have added click listner once session is started to place object once we have 
// surface information after hit-test result.
    document.getElementById('arOverlay').addEventListener('click', placeObject);

    // initialize three.js scene
    initScene(gl, session);
  }

现在,我们必须添加最后一个主函数来处理会话中每个更新的帧。正如我们在上面的代码中的 session.requestAnimationFrame() 中注册 onXRFrame 一样。

  function onXRFrame(t, frame) {
    let session = frame.session;
    // calling it recursively to get current updated frame information
    session.requestAnimationFrame(onXRFrame);
    if (xrHitTestSource) {
      // obtain hit test results by casting a ray from the centre of device screen
      // into AR view. Results indicate that ray intersected with one or more detected surfaces
      const hitTestResults = frame.getHitTestResults(xrHitTestSource);
      if (hitTestResults.length) {
        // obtain a local pose at the intersection point
        const pose = hitTestResults[0].getPose(xrRefSpace);
        // we are changing reticle position and view at the intersection 
            point to get visible  feedback on which surface the hit result is in this frame.              
        reticle.matrix.fromArray(pose.transform.matrix);
        reticle.visible = true;
      }
    } else {
      // do not show a reticle if no surfaces are intersected
      reticle.visible = false;
    }

    // update object animation if your model contains animation
    updateAnimation();
    // bind our gl context that was created with WebXR to threejs renderer
    gl.bindFramebuffer(
      gl.FRAMEBUFFER,
      session.renderState.baseLayer.framebuffer,
    );
    // render the scene
    renderer.render(scene, camera);
  }

在每个帧更新中为模型动画添加这个

  function updateAnimation() {


![img](https://img-blog.csdnimg.cn/img_convert/6a1a6a511945259d44cd7a3aa941d95c.png)
![img](https://img-blog.csdnimg.cn/img_convert/74e1d8a4667447e2314420dd67b8fdbb.png)
![img](https://img-blog.csdnimg.cn/img_convert/e49ce7aa4626073026ae0ce2b3933e40.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618658159)**

9729)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618658159)**

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值