three-mesh-bvh包围体层次结构(提升射线检测和空间查询性能(碰撞测试、可见性测试))
📘 three-mesh-bvh 简介
three-mesh-bvh 是一个基于 包围体层次结构(BVH,Bounding Volume Hierarchy) 的加速库,用于提升 three.js 中网格(Mesh)几何体在执行 射线检测(Raycasting) 和 空间查询(碰撞检测、可见性测试等) 时的性能。
在 three.js 默认实现中,Raycaster 会逐个三角面检查射线是否命中,当几何体包含数十万甚至上百万个三角面时,性能会严重下降。
通过为几何体构建 BVH,检测复杂度由 O(n) 降低到 O(log n),显著提升运行效率。

这张图展示的是 Bounding Volume Hierarchy (BVH) 的概念:
-
原始的复杂模型有很多细小三角形,直接做射线检测会非常慢。
-
BVH 把模型外层先用一个大的包围体(bounding volume,比如长方体)包起来。
-
然后逐层把包围体再细分(像树结构一样),每一层都只包住其中一部分三角形。
这样射线检测时,就不用和所有三角面逐一相交,而是:
-
先看射线是否和大的包围体相交。
-
如果相交,再进入子包围体继续检测。
-
最后只检测到可能相交的少量三角形。
👉 效果就是把原本 O(n) 的检测优化成 O(log n),大幅提升效率。
📌 核心特性
-
加速射线检测:替代默认的三角面遍历,实现高效拾取与碰撞。
-
空间查询:支持包围盒(Box)、球体(Sphere)、胶囊体(Capsule)与网格的快速碰撞检测。
-
动态更新:支持
refit()方法在几何体少量修改时快速更新 BVH,而无需重建。 -
高兼容性:可直接替换 three.js 的
Mesh.raycast,无需改写业务逻辑。
📌 安装
const raycaster = new THREE.Raycaster();
raycaster.firstHitOnly = true; // 只取最近的交点,加速
// 从 (x,1000,z) 向下发射射线
raycaster.set(new THREE.Vector3(0, 1000, 0), new THREE.Vector3(0, -1, 0));
const intersects = raycaster.intersectObject(groundMesh);
if (intersects.length > 0) {
console.log('命中点:', intersects[0].point);
}
📌 碰撞检测示例(球体 vs 地形)
import { MeshBVH, MeshBVHVisualizer } from 'three-mesh-bvh';
const bvh = new MeshBVH(groundMesh.geometry);
// 定义一个球体
const sphere = new THREE.Sphere(new THREE.Vector3(0, 10, 0), 2);
// 检测是否碰撞
const hit = bvh.intersectsSphere(sphere);
console.log('是否碰撞:', hit);
📌 小车贴地应用示例(四轮射线)
const raycaster = new THREE.Raycaster();
raycaster.firstHitOnly = true; // 优化性能
const down = new THREE.Vector3(0, -1, 0);
// 车轮相对位置
const wheelOffsets = [
new THREE.Vector3( 1, 0, 1),
new THREE.Vector3(-1, 0, 1),
new THREE.Vector3( 1, 0, -1),
new THREE.Vector3(-1, 0, -1),
];
function updateCarOnGround(car, groundMesh) {
const wheelHits = [];
for (let offset of wheelOffsets) {
const worldPos = car.localToWorld(offset.clone());
raycaster.set(new THREE.Vector3(worldPos.x, 9999, worldPos.z), down);
const hit = raycaster.intersectObject(groundMesh)[0];
if (hit) wheelHits.push(hit.point);
}
if (wheelHits.length >= 3) {
// 计算车身法线
const v1 = wheelHits[1].clone().sub(wheelHits[0]);
const v2 = wheelHits[2].clone().sub(wheelHits[0]);
const normal = new THREE.Vector3().crossVectors(v1, v2).normalize();
// 对齐车身朝向
const q = new THREE.Quaternion().setFromUnitVectors(new THREE.Vector3(0, 1, 0), normal);
car.quaternion.slerp(q, 0.2);
// 设置高度
const avgY = wheelHits.reduce((sum, p) => sum + p.y, 0) / wheelHits.length;
car.position.y = THREE.MathUtils.lerp(car.position.y, avgY + 0.3, 0.2);
}
}
📌 总结
-
three-mesh-bvh 通过构建 BVH,加速射线检测和空间查询,适合处理高模地形、大规模场景。
-
主要用途:高效拾取、角色/车辆贴地、碰撞检测、视锥裁剪。
-
性能提升:从 O(n) → O(log n),对于百万级三角面的场景能带来几十倍速度提升。

浙公网安备 33010602011771号