# BVH scene usage

**URL:** <https://discourse.threejs.org/t/bvh-scene-usage/67887>\
**Category:** Questions\
**Created:** [July 9, 2024, 1:13am UTC](https://discourse.threejs.org/t/bvh-scene-usage/67887 "2024-07-09T01:13:43Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![dubois](https://avatars.discourse-cdn.com/v4/letter/d/e9c0ed/32.png) [@dubois](https://discourse.threejs.org/u/dubois)\
**Post date:** [July 9, 2024, 1:13am UTC](https://discourse.threejs.org/t/bvh-scene-usage/67887/1 "2024-07-09T01:13:43Z")

</div>

I’m getting started with `Three-mesh-bvh` but i’m not sure what to do with it. I have a large scene with tens of thousands of meshes. I already merge them and thats what i render, however i discard the merged geometry on the cpu. I keep the original geometries and each mesh instance around for raycasting.

I see that i need to patch the geometry and mesh to work with the structure, but it’s not clear to me how they relate afterwards. Ie. am i better off applying this to my merged geometry, or to the (invisible) individual meshes?

The example that seemed the most relevant, merges the world into one mesh using a helper from the package, i imagine i can skip that step if i already have my own version of the merged geometry.

---

<div class="post-metadata">

**Author:** ![drcmda](https://avatars.discourse-cdn.com/v4/letter/d/91b2a8/32.png) [@drcmda](https://discourse.threejs.org/u/drcmda)\
**Post date:** [July 9, 2024, 6:03am UTC](https://discourse.threejs.org/t/bvh-scene-usage/67887/2 "2024-07-09T06:03:20Z")

</div>

i believe it should not matter, it creates an oct tree of the model or the models and it knows into which segments rays fall. it won’t go through all vertices no more. merging is generally better for gpu performance due to draw calls. keeping the old unmerged geo around isn’t bad also because this can allow you to get per-mesh/face highlighting. we do this for CAD at work: bvh + merged geo + unmerged for selection/highlighting.

---

<div class="post-metadata">

**Author:** ![agargaro](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/agargaro/32/35529_2.png) [@agargaro](https://discourse.threejs.org/u/agargaro)\
**Post date:** [July 9, 2024, 7:01am UTC](https://discourse.threejs.org/t/bvh-scene-usage/67887/3 "2024-07-09T07:01:08Z")

</div>

Hi, I am writing a library to handle scene BVH if you are interested.  
It is still under development, but not long before release.

Repo + example (raycasting + frustum culling 100k different meshes) : [StackBlitz](https://stackblitz.com/~/github.com/agargaro/three-scene-bvh?file=src/examples/main.ts)

---

<div class="post-metadata">

**Author:** ![AshhadDevLab](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/ashhaddevlab/32/44111_2.png) [@AshhadDevLab](https://discourse.threejs.org/u/AshhadDevLab)\
**Post date:** [July 9, 2024, 9:06am UTC](https://discourse.threejs.org/t/bvh-scene-usage/67887/4 "2024-07-09T09:06:06Z")

</div>

`Three-Mesh-BVH` is a great library it allows to break down the geometry into a Bounding Volumetric Hierarchy which is helpful for detecting interaction with the geometry and the geometry triangles without using too much resources.

For instance take the example of the [`Three-Mesh-BVH`](https://gkjohnson.github.io/three-mesh-bvh/example/bundle/raycast.html) given on the GitHub main page the example is casting 500 rays against an 80,000 polygon model at 60fps which is if done directly without BVH will take either too much time, will make the website lag or even browser crashes.

It can be used to detect collision between geometries, better and faster raycasting and it can even find the triangles which are being collided by other geometries using shapecast.

There are a lot of benefits of using the lib. also I just saw the example given by agargaro (not mentioning him due to privacy) and I have to say thats working really smooth and great hope to see it as a full project soon.

---

<div class="post-metadata">

**Author:** ![dubois](https://avatars.discourse-cdn.com/v4/letter/d/e9c0ed/32.png) [@dubois](https://discourse.threejs.org/u/dubois)\
**Post date:** [July 9, 2024, 9:08am UTC](https://discourse.threejs.org/t/bvh-scene-usage/67887/5 "2024-07-09T09:08:45Z")

</div>

But that’s what I’m considering. I could have a first tree be all instanced cubes for bounding boxes. Once I hit that I can accelerate the triangles.

---

<div class="post-metadata">

**Author:** ![manthrax](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/manthrax/32/2596_2.png) [@manthrax](https://discourse.threejs.org/u/manthrax)\
**Post date:** [July 10, 2024, 2:50pm UTC](https://discourse.threejs.org/t/bvh-scene-usage/67887/6 "2024-07-10T14:50:39Z")

</div>

I don’t know how much doing the instanced cubes would help cull… since that’s effectively what the the BVH is doing already. so you would just be doing the same thing twice… the B in BVH are already those cubes/boxes. 😃  
I just throw my whole world at bvh and use its accelerated raycast and it “just works”.

---

<div class="post-metadata">

**Author:** ![dubois](https://avatars.discourse-cdn.com/v4/letter/d/e9c0ed/32.png) [@dubois](https://discourse.threejs.org/u/dubois)\
**Post date:** [July 10, 2024, 5:03pm UTC](https://discourse.threejs.org/t/bvh-scene-usage/67887/7 "2024-07-10T17:03:47Z")

</div>

I might be missing some basic understanding a bout BVH, but this example is confusing me:

 ![image](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/8/6/8680e97dbbb71ee48534a04b98deb6e20d9d4f4a.jpeg)

If it indeed “just worked” as @manthrax and @drcmda are suggesting, i don’t think this code would be needed:

```javascript

			// collect all geometries to merge
			environment.updateMatrixWorld( true );

			const staticGenerator = new StaticGeometryGenerator( environment );
			staticGenerator.attributes = ['position'];

			const mergedGeometry = staticGenerator.generate();
			mergedGeometry.boundsTree = new MeshBVH( mergedGeometry );

```

My understanding is that its more like this?

```javascript
scene.traverse.forEach(o=>{
  if(o instanceof Mesh){
    o.bvhTree.intersect(myRay)
  }
})

```

Otherwise the merge would be redundant? and

> the B in BVH are already those cubes/boxes. 😃

this isnt actually happening, since we are just `boxes.forEach` those first boxes.

What would a `three-scene-bvh` package do?

I think the example specifically merges the `environment` into one mesh to make a colider. It’s not even using it to optimize rendering, the `environment` is put in, non merged. If it worked magically out of the box i don’t think any of this would be needed. It would be something like `myMesh.bvh.layers.set(Static)`

---

<div class="post-metadata">

**Author:** ![dubois](https://avatars.discourse-cdn.com/v4/letter/d/e9c0ed/32.png) [@dubois](https://discourse.threejs.org/u/dubois)\
**Post date:** [July 10, 2024, 5:10pm UTC](https://discourse.threejs.org/t/bvh-scene-usage/67887/8 "2024-07-10T17:10:07Z")

</div>

> [@AshhadDevLab](#):
>
> `Three-Mesh-BVH` is a great library it allows to break down the geometry into a Bounding Volumetric Hierarchy which is helpf

😐 😐 😐 😐 😐 😐 😐 😐 😐 😐 😐 😐 😐

What is the point of using chatgpt for this?

---

<div class="post-metadata">

**Author:** ![dubois](https://avatars.discourse-cdn.com/v4/letter/d/e9c0ed/32.png) [@dubois](https://discourse.threejs.org/u/dubois)\
**Post date:** [July 10, 2024, 5:11pm UTC](https://discourse.threejs.org/t/bvh-scene-usage/67887/9 "2024-07-10T17:11:26Z")

</div>

> [@agargaro](#):
>
> Hi, I am writing a library to handle scene BVH if you are interested.

I totally didn’t see this reply. So my conclusions are correct?

---

<div class="post-metadata">

**Author:** ![manthrax](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/manthrax/32/2596_2.png) [@manthrax](https://discourse.threejs.org/u/manthrax)\
**Post date:** [July 10, 2024, 5:13pm UTC](https://discourse.threejs.org/t/bvh-scene-usage/67887/10 "2024-07-10T17:13:50Z")

</div>

Here’s all I had to do:

```javascript

import *as meshbvh from "./three-mesh-bvh.js"

geometry.boundsTree = new meshbvh.MeshBVH(geometry);

```

and then used the “optimized raycast” that patches THREEJS raycast

```javascript
THREE.Mesh.prototype.raycast = meshbvh.acceleratedRaycast;

```

and it Just Works. Raycasts are instant.

 ![image](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/0/8/0824f3acc3ad4a4c3942e3f02494459cf869ac66.jpeg)

---

<div class="post-metadata">

**Author:** ![dubois](https://avatars.discourse-cdn.com/v4/letter/d/e9c0ed/32.png) [@dubois](https://discourse.threejs.org/u/dubois)\
**Post date:** [July 10, 2024, 5:18pm UTC](https://discourse.threejs.org/t/bvh-scene-usage/67887/11 "2024-07-10T17:18:00Z")

</div>

Do you have this online somewhere? All these boxes are unique meshes and draw calls? @agargaro what are you working then?

---

<div class="post-metadata">

**Author:** ![manthrax](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/manthrax/32/2596_2.png) [@manthrax](https://discourse.threejs.org/u/manthrax)\
**Post date:** [July 10, 2024, 5:22pm UTC](https://discourse.threejs.org/t/bvh-scene-usage/67887/12 "2024-07-10T17:22:14Z")

</div>

The buildings are all one buffergeometry. I don’t have it shared publicly yet.

The accelerated raycast override will also create the BVHs automagically I think when It hits a node without one, but not sure.  
I remember seeing some option about “lazy generation” somewhere…

In that sample, I explicitly only cast against the mesh itself.

---

<div class="post-metadata">

**Author:** ![dubois](https://avatars.discourse-cdn.com/v4/letter/d/e9c0ed/32.png) [@dubois](https://discourse.threejs.org/u/dubois)\
**Post date:** [July 10, 2024, 5:26pm UTC](https://discourse.threejs.org/t/bvh-scene-usage/67887/13 "2024-07-10T17:26:42Z")

</div>

This is supporting my assumption then? You accelerated raycasting through a single mesh. That makes sense.

What you could do is, try to render the single buffer geometry, but dont raycast it. instead, make another scene, with all the boxes as meshes and try to raycast. If it worked like magic, it would be eqully fast. But if it doesnt, youll just keep on raycasting thousands of boxes in linear time. Once you actually find which box to raycast, the triangles are irrelevant, since theres like 12 of them.

All the examples do infact raycast many rays against single large objects. None of them raycast against many small meshes.

---

<div class="post-metadata">

**Author:** ![manthrax](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/manthrax/32/2596_2.png) [@manthrax](https://discourse.threejs.org/u/manthrax)\
**Post date:** [July 10, 2024, 5:29pm UTC](https://discourse.threejs.org/t/bvh-scene-usage/67887/14 "2024-07-10T17:29:13Z")

</div>

I don’t see how raycasting against an instancedmesh of boxes is gonna be faster than raycasting against the bounding boxes of a bunch of BVHed smaller meshes.

You’re still colliding the instanced box mesh in software yeah? (unless you’re doing that in a shader || webgpu, then yeah maybe you could squeeze some speed out of the broad phase)

---

<div class="post-metadata">

**Author:** ![AshhadDevLab](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/ashhaddevlab/32/44111_2.png) [@AshhadDevLab](https://discourse.threejs.org/u/AshhadDevLab)\
**Post date:** [July 10, 2024, 5:33pm UTC](https://discourse.threejs.org/t/bvh-scene-usage/67887/15 "2024-07-10T17:33:12Z")

</div>

Didn’t use ChatGPT on that, I wrote it myself. I mean I don’t know the reason why you think I used GPT but still.

To be honest GPT is trash 😄

---

<div class="post-metadata">

**Author:** ![dubois](https://avatars.discourse-cdn.com/v4/letter/d/e9c0ed/32.png) [@dubois](https://discourse.threejs.org/u/dubois)\
**Post date:** [July 10, 2024, 5:46pm UTC](https://discourse.threejs.org/t/bvh-scene-usage/67887/16 "2024-07-10T17:46:10Z")

</div>

I’ll be honest, i am now confused even more, what prompted you to write an essay on “What is three-bvh-mesh”?

---

<div class="post-metadata">

**Author:** ![dubois](https://avatars.discourse-cdn.com/v4/letter/d/e9c0ed/32.png) [@dubois](https://discourse.threejs.org/u/dubois)\
**Post date:** [July 10, 2024, 5:50pm UTC](https://discourse.threejs.org/t/bvh-scene-usage/67887/17 "2024-07-10T17:50:09Z")

</div>

say you have how man, 20k of these boxes in your image? So it’s only really 240k triangles not much.

Now imagine youve got the stanford rabbit inside each one of those boxes. 20k x stanford rabbit triagles. It’s a prettty big soup.

It would make sense to me to first look at bounding boxes, without any triangles, and once suitable ones are found proceed to intersect the mesh. I’m not sure but maybe even different heuristics would make sense eg BVH on the scene, kd-tree or something else on the triangles or something like that.

I think we best wait for @agargaro to explain why `three-bvh-scene` is needed.

---

<div class="post-metadata">

**Author:** ![dubois](https://avatars.discourse-cdn.com/v4/letter/d/e9c0ed/32.png) [@dubois](https://discourse.threejs.org/u/dubois)\
**Post date:** [July 10, 2024, 5:52pm UTC](https://discourse.threejs.org/t/bvh-scene-usage/67887/18 "2024-07-10T17:52:40Z")

</div>

> [@manthrax](#):
>
> I don’t see how raycasting against an instancedmesh of boxes is gonna be faster than raycasting

Not instanced. The first pass would be exactly what you are doing, cast against a big scene size triangle soup. Everything in the scene is in that soup, its one mesh, hence `three-bvh-MESH`.

But in the next pass you say, “ok building 1.234.567 has the stanford rabbit model with 20k triangles” and then you do the bvh mesh again.

---

<div class="post-metadata">

**Author:** ![manthrax](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/manthrax/32/2596_2.png) [@manthrax](https://discourse.threejs.org/u/manthrax)\
**Post date:** [July 10, 2024, 5:58pm UTC](https://discourse.threejs.org/t/bvh-scene-usage/67887/19 "2024-07-10T17:58:47Z")

</div>

raycasting checks against geometry.boundingSphere (if it exists) and/or checks against geometry.boundingBox (if it exists), first… then only drills into the geometry if that passes.  
So that’s functionally equivalent to casting against an array of box instances is all i’m saying.

---

<div class="post-metadata">

**Author:** ![dubois](https://avatars.discourse-cdn.com/v4/letter/d/e9c0ed/32.png) [@dubois](https://discourse.threejs.org/u/dubois)\
**Post date:** [July 10, 2024, 5:59pm UTC](https://discourse.threejs.org/t/bvh-scene-usage/67887/20 "2024-07-10T17:59:48Z")

</div>

Right, but you’re saying it’s unecessary? This library already does that under the hood sort to speak?

[Next page](https://discourse.threejs.org/t/bvh-scene-usage/67887.md?page=2)
