You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测WebXR命中测试结果中的平面是否垂直并仅在垂直平面显示准星

仅在垂直平面显示WebXR准星的实现方案

嘿,很高兴你在探索WebXR的命中测试功能!你的观察特别到位——那个示例里准星在垂直墙面变色,确实是因为它背后有判断平面朝向的逻辑,只是没有直接暴露成参数,我来帮你把这个逻辑拆解出来,实现只在垂直平面显示准星的需求。

核心思路:通过平面法线判断是否垂直

WebXR的命中测试结果里,每个XRHitTestResult对象可以关联一个XRPlane(平面),我们可以通过这个平面的法线方向来判断它是不是垂直平面(比如墙面):

  • 垂直平面的法线是平行于地面的,所以法线的Y轴分量(上下方向)会非常接近0;
  • 相反,水平面(比如地面)的法线Y分量接近1或-1。

具体实现步骤

  1. 确保会话支持平面检测
    首先要在初始化XR会话时,请求plane-detection特性,这样才能获取到平面的详细信息:

    const session = await navigator.xr.requestSession('immersive-ar', {
      requiredFeatures: ['hit-test', 'plane-detection']
    });
    
  2. 在命中测试中判断平面朝向
    拿到命中测试结果后,先提取关联的平面,再通过平面的变换矩阵提取法线,最后判断是否为垂直平面,再控制准星的显示:

    // 假设你已经在XR帧回调里获取了hitTestResults
    if (hitTestResults.length > 0) {
      const hitResult = hitTestResults[0];
      const plane = hitResult.getPlane(); // 获取命中的平面对象
    
      let isVerticalPlane = false;
      if (plane) {
        // 从平面的变换矩阵中提取法线(Z轴方向,对应矩阵的第9-11位索引)
        const planeMatrix = plane.transform.matrix;
        const normalY = planeMatrix[9]; // 法线的Y分量
    
        // 用阈值判断是否为垂直平面(可根据需求调整0.1这个值)
        isVerticalPlane = Math.abs(normalY) < 0.1;
      }
    
      const pose = hitResult.getPose(xrRefSpace);
      if (isVerticalPlane) {
        // 仅在垂直平面时显示准星
        reticle.visible = true;
        reticle.matrix = pose.transform.matrix;
      } else {
        reticle.visible = false;
      }
    } else {
      // 没有命中结果时隐藏准星
      reticle.visible = false;
    }
    

关于准星朝向的补充

你提到的pose.transform.matrix确实包含了准星的朝向信息——这个4x4矩阵的前3列分别对应准星的X、Y、Z轴方向。不过对于判断平面是否垂直来说,直接用hitResult.getPlane()获取平面的信息会更准确,因为准星的朝向是完全贴合平面的,平面的法线就是准星的Z轴方向。

为什么示例里准星会变色?

那个示例的逻辑和上面类似:当检测到垂直平面时,会修改准星的材质颜色,只是没有把判断逻辑单独拎出来。你可以去示例的源码里找找getPlane()相关的代码,就能看到它的判断逻辑啦。

内容的提问来源于stack exchange,提问作者sparkanzo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 21:18:11