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

Three.js:如何判断空间点是否可见或被遮挡?

解决Three.js中标注被遮挡时的隐藏问题

你现在用的视锥体检测只能判断点是否在相机的可视范围内,完全没法处理被其他网格遮挡的情况——这就是为什么只有大幅旋转时标注才会消失的原因。要解决遮挡检测,咱们得用**射线投射(Raycaster)**来实现精准的遮挡判断。

首先先修正你现有代码里的一个小错误:你写的逻辑搞反了,frustum.containsPoint(vector)返回true说明点在视野里,这时候应该显示标注(opacity:1),反之才隐藏。

接下来是完整的解决方案:

核心思路

从相机位置向目标空间点发射一条射线,检查这条射线在到达目标点之前是否和场景中的其他物体相交。如果有相交,说明目标点被遮挡,隐藏标注;否则显示标注。

完整代码实现

const vector = new THREE.Vector3(x, y, z);
this.aCamera.updateMatrixWorld(true);

// 1. 先做视锥体检测,快速过滤掉视野外的点
const frustum = new THREE.Frustum();
frustum.setFromMatrix(new THREE.Matrix4().multiplyMatrices(
    this.aCamera.projectionMatrix,
    this.aCamera.matrixWorldInverse
));

if (!frustum.containsPoint(vector)) {
    // 点不在视野里,直接隐藏标注
    anAnnotation.css({opacity: 0});
    return;
}

// 2. 视野内的点,再做遮挡检测
const raycaster = new THREE.Raycaster();
// 设置射线起点为相机位置,方向指向目标点
raycaster.set(this.aCamera.position, vector.clone().sub(this.aCamera.position).normalize());
// 计算相机到目标点的距离,作为射线检测的最大距离(避免检测到更远的物体)
const distanceToPoint = this.aCamera.position.distanceTo(vector);
raycaster.far = distanceToPoint;

// 检测场景中的物体(替换成你实际的场景物体数组,第二个true表示递归检测子物体)
const intersects = raycaster.intersectObjects(scene.children, true);

// 判断是否被遮挡:如果有相交结果,且第一个相交的物体距离小于目标点距离,说明被遮挡
let isOccluded = false;
if (intersects.length > 0) {
    // 注意:如果目标点本身在某个网格上,需要排除该网格(根据你的需求调整)
    // 比如可以给目标点所在网格加个标记,然后在这里判断
    isOccluded = intersects[0].distance < distanceToPoint - 0.01; // 加个小偏移避免精度问题
}

// 根据遮挡状态设置标注显示
anAnnotation.css({opacity: isOccluded ? 0 : 1});

关键细节说明

  • 视锥体检测前置:先做视锥体检测可以快速过滤掉视野外的点,减少不必要的射线检测,提升性能。
  • 射线距离限制:把射线的far设置为相机到目标点的距离,这样只会检测目标点之前的物体,不会误判更远的物体。
  • 精度偏移:判断距离时减去一个很小的值(比如0.01),避免因为浮点精度问题,把目标点所在的网格当成遮挡物。
  • 排除自身网格:如果你的目标点是附着在某个网格上的,记得在检测时排除这个网格,否则会误判为被自身遮挡。你可以给该网格添加一个自定义属性(比如isAnnotationHost: true),然后在遍历相交结果时跳过它。

性能优化建议

如果你的场景里有大量标注,频繁的射线检测可能会影响性能,可以试试这些优化:

  • 只在相机移动、旋转或者物体动画结束时执行检测,而不是每帧都检测。
  • 对标注进行批量处理,或者使用WebGL的遮挡查询(Occlusion Query)(Three.js的THREE.OcclusionQuery类),这种方式更适合批量遮挡检测,但实现起来稍复杂。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:38:47