在 Three.js 或 WebGL 中,如果你加载了一个有几十万、上百万三角面的模型,然后想做下面这些事:
- 用户点击模型,拾取(Raycast)它的哪个三角形被点击?
- 你想用光线做实时路径追踪、做玻璃折射、反射——需要判断每条光线打到哪?
- 想做物理碰撞、裁剪、空间分析,比如“一个胶囊有没有穿过模型表面?”
如果你一个一个三角形去检查光线/物体有没有命中它,那性能是灾难性的(每次操作都要几十万次判断)。
three-mesh-bvh
是一个专为 Three.js 提升几何交互性能和空间查询效率的工具。它实现了 边界体积层次结构(BVH),将复杂的三角网格结构通过加速树进行组织管理,从而显著提高射线投射(raycasting)、碰撞检测、空间查询、剖面、切片等操作的速度。
BVH 会把这些三角形包成一棵“盒子树”结构,让你不再“挨个看”,而是“先看大块,有可能命中再看细节”。
比如你扔一根光线,BVH 的作用是:
→ 从顶层大盒子判断:光线有没有可能打中模型?
→ 有的话,再去看里面的子盒子
→ 一直到最后只剩下 2-4 个三角形,才做精确命中计算
原来要 检查几十万次 → 现在只查几十次,性能瞬间提升 100 倍以上。
three-mesh-bvh核心功能与优势
- 高性能 Raycasting
构建 BVH 后,500 条射线在 80k 面模型上可流畅运行 60 FPS,性能提升数十倍。 - 空间查询能力
支持形体间剖切边界检测、模型相交、点到网格最近距离、场景剖片边缘检测等复杂操作 。 - 异步构建,适配大模型
支持 Web Worker 构建 BVH,避免阻塞主线程 - Shader 内追踪能力
可将 BVH 数据打包上传至 GPU,配合带射线追踪的着色器实现实时光线追踪或场景剖切 - 支持多种场景案例
官方示例覆盖网格剖面、选区、三角形选中、剖切边缘、SDF 体素化、点云选取、角色控制和路径追踪等 。
用它可做什么?
射线检测
对复杂模型进行射线检测。
蒙皮
将带骨骼动画的网格一次构建 BVH 并在每帧仅做 refit
增量更新,使射线检测和碰撞计算依旧保持 60 FPS。 避免了传统逐面遍历与整树重建的高 CPU 开销与卡顿,实现了对复杂角色的流畅、高精度交互。
物理碰撞
游戏环境中的碰撞检测性能优化。
路径追踪渲染
大幅提升光线与三角网格的相交效率,避免每次查询都全量遍历模型,提高帧率和收敛速度
怎么用
-
为模型几何体(BufferGeometry)构建 BVH
geometry.computeBoundsTree(); // 构建 BVH,只需调用一次
-
加速拾取(Raycaster)
Mesh.prototype.raycast = acceleratedRaycast; // 替换掉默认的慢方法
-
开放空间查询 API
- 盒子、球体是否碰撞几何?
- 找出所有与射线相交的三角面?
- 求最近的碰撞点?
geometry.boundsTree.intersectsBox(box);
geometry.boundsTree.closestPointToPoint(point);
最典型的使用场景
原来的 Three.js Raycaster(慢得不行):
const raycaster = new THREE.Raycaster();
const intersects = raycaster.intersectObject(mesh); // 每次都扫全模型三角形
对大模型(比如扫描件、雕像、CAD)来说,每次点一下页面就卡顿几百毫秒甚至几秒。
用了 three-mesh-bvh
后(快 100 倍):
geometry.computeBoundsTree();
mesh.raycast = acceleratedRaycast;
const raycaster = new THREE.Raycaster();
const intersects = raycaster.intersectObject(mesh); // 使用 BVH,加速判断
即使是 100 万面模型,点击反馈也能达到 60 FPS。
✅ 总结一句话:
three-mesh-bvh
是一个插件,让你的 Three.js 模型支持快速空间查询、快速拾取、快速光线求交——解决“大模型场景中性能卡顿”的根本问题。
在做如下这些应用时,它几乎是必须引入的优化组件:
- 大模型编辑器(CAD、三维标注)
- 三维拾取(点哪选哪)
- Web 端路径追踪渲染器
- 碰撞检测 / CSG / 剖切
- AI/物理模拟中需要几何判断的场景
地址 https://github.com/gkjohnson/three-mesh-bvh?tab=readme-ov-file (opens in a new tab)