three-mesh-bvh包圍體層次結構(提升射線檢測和空間查詢性能(碰撞測試、可見性測試))
?? three-mesh-bvh 簡介
three-mesh-bvh 是一個基于 包圍體層次結構(BVH,Bounding Volume Hierarchy) 的加速庫,用于提升 three.js 中網格(Mesh)幾何體在執(zhí)行 射線檢測(Raycasting) 和 空間查詢(碰撞檢測、可見性測試等) 時的性能。
在 three.js 默認實現中,Raycaster 會逐個三角面檢查射線是否命中,當幾何體包含數十萬甚至上百萬個三角面時,性能會嚴重下降。
通過為幾何體構建 BVH,檢測復雜度由 O(n) 降低到 O(log n),顯著提升運行效率。

這張圖展示的是 Bounding Volume Hierarchy (BVH) 的概念:
-
原始的復雜模型有很多細小三角形,直接做射線檢測會非常慢。
-
BVH 把模型外層先用一個大的包圍體(bounding volume,比如長方體)包起來。
-
然后逐層把包圍體再細分(像樹結構一樣),每一層都只包住其中一部分三角形。
這樣射線檢測時,就不用和所有三角面逐一相交,而是:
-
先看射線是否和大的包圍體相交。
-
如果相交,再進入子包圍體繼續(xù)檢測。
-
最后只檢測到可能相交的少量三角形。
?? 效果就是把原本 O(n) 的檢測優(yōu)化成 O(log n),大幅提升效率。
?? 核心特性
-
加速射線檢測:替代默認的三角面遍歷,實現高效拾取與碰撞。
-
空間查詢:支持包圍盒(Box)、球體(Sphere)、膠囊體(Capsule)與網格的快速碰撞檢測。
-
動態(tài)更新:支持
refit()方法在幾何體少量修改時快速更新 BVH,而無需重建。 -
高兼容性:可直接替換 three.js 的
Mesh.raycast,無需改寫業(yè)務邏輯。
?? 安裝
const raycaster = new THREE.Raycaster();
raycaster.firstHitOnly = true; // 只取最近的交點,加速
// 從 (x,1000,z) 向下發(fā)射射線
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; // 優(yōu)化性能
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,加速射線檢測和空間查詢,適合處理高模地形、大規(guī)模場景。
-
主要用途:高效拾取、角色/車輛貼地、碰撞檢測、視錐裁剪。
-
性能提升:從 O(n) → O(log n),對于百萬級三角面的場景能帶來幾十倍速度提升。

浙公網安備 33010602011771號