The default raycaster does a bounds check first… I don’t know if meshbvh does that… but I assume it does. And yeah… It does not create a Bvh of the scene itself as a broadphase. afaik.
And that… leads into what argargaro is hacking on.
I will try to summarize by also stating obvious things if someone less experienced should read.
the BVH is a tree-like data structure that allows bounding boxes (usually) of Object3D or triangles to be stored hierarchically.
Calculating the intersection with a ray becomes extremely fast because if the bounding box of a node is not intersected, it is discarded along with all the child nodes.
The raycast method of the Mesh class, checks if there is intersection with the BoundingSphere and, if there is, with the bounding box. After that it checks if all triangles in the geometry are intersecte
three-mesh-bvh is a library that allows you to create the BVH using the triangles of a geometry and override the Mesh.raycast function.
If you have many meshes with the same geometry, there are several ways to speed up raycasting:
Iterate all the meshes and call accelerated raycasting on each one: the slowest but most flexible method. Slower does not mean slow, except in rare cases (geometries with huge bounding boxes that overlap other meshes, probably). The extra calculations are due to always reiterating the BVH from the root and applying transformations to the ray making it consistent with the BVH orientation.
Create a merged geometry: the fastest method but consumes more memory and makes it more complicated to figure out which mesh has been intersected (if I am not mistaken).
Create a BVH containing all scene objects, so you can filter out objects to iterate individually later (faster approach than iterating them all if the scene is very large)
So a scene BVH and a BVH for each geometry is usually really good strategy.
In this example, a scene BVH with 100k objects is created to benchmark frustum culling and raycasting.
Frustum culling can become slow if there are many objects in the camera frustum, while raycasting is always much faster.
It is possible to change the variable ‘useBVH’ on line 15 to check the performance without BVH.
PS: this is an example not meant to be a demo, since I’m still working on it, but it makes the point
To add to this, you can set the firstHitOnly flag to true to speed up the intersected result, returning only the rays first hit