Three-mesh-bvh: A plugin for fast geometry raycasting and spatial queries!

I just released v0.5.0 this weekend which includes signature changes to a number of the BVH functions to help simplify function arguments and make the results more consistent and the ability to use SharedArrayBuffers so the same BVH memory can be used across multiple WebWorkers. The functions will log a warning if you’re using the old signature so it should hopefully make the transition easy if you’re using a function that’s changed. If you’ve just been using three-mesh-bvh to override and accelerate Mesh.raycast then no changes will be needed!

Release notes here:

And for fun a couple more path traced images made with the code from the new demo!

9 Likes

This library is awesome. I downloaded it for some collision detection, but once I’d tried the demos…

I make room/product configurators, and it would be fantastic to offer some browser based raytracing. At the moment I download a scene and take it through Blender/Cycles.
This is the most realistic lighting I’ve ever seen in threejs. Props gkjohnson!

I’ve uploaded a test room. Still needs some tweeking, but I’m amazed the difference some ambient shadows can make.
I used the gpu path tracing example as a start point, and added a color pass.
https://gkjohnson.github.io/three-mesh-bvh/example/bundle/gpuPathTracing.html

https://devine.pub/raytrace/example/

Can’t wait to see what you do next! :smiley:




7 Likes

What is the name of the example with the rabbit? Could you share the link?

In example PointCloudIntersection, is that just Intersection with the point?

@Peter_Devine this is awesome! And what a clever approach to getting color working without full material support. Thanks for sharing. After a few more changes the raycasting shader code will be available to use in the next release and I’m pretty excited about the possibilities of raytracing in a shader.

@Zvyozdo4ka

What is the name of the example with the rabbit? Could you share the link?

If you take a look at the list of demos it’s listed as the lasso selection example. The demo uses a torus knot geometry instead, though.

In example PointCloudIntersection, is that just Intersection with the point?

As explained above the point intersection example is just using degenerate triangles to emulate point queries. The demo shows raycasting but with the shapecast function you can implement any kind of spatial query you want.

2 Likes

@gkjohnson Cheers! Looking forward very much to the next release.
I couldn’t work out a way to reduce the “intensity” of the shadows, so I ended up boosting the ambient light when rendering. Must admit I still couldn’t work out quite how it worked, but was blown away by the results. Shame we don’t have AI noise reduction in the browser yet, but I suppose it’s only a matter of time :slight_smile:

1 Like

couldn’t work out a way to reduce the “intensity” of the shadows

The throughput *= 1.0 / PI; is what attenuates the intensity after a light bounce for the Lambertian model. You can change it to fit what you want stylistically but I believe 1 / PI is what is physically correct and the reason shadows and corners get dark after multiple bounces.

Shame we don’t have AI noise reduction in the browser yet, but I suppose it’s only a matter of time

There’s probably some kind of noise reduction that can be done without AI but that’s beyond the scope of the small demo, though. Possible a future project.

It certainly looks correct :slight_smile:
It’s obviously the lighting pass which it missing.
I’ll try the cpu version, which I can see includes lighting.
I just couldn’t get the workers to function from the demo.

1 Like

Version 0.5.1 of three-mesh-bvh has been released! As Peter found early the newest release includes some helpers and shader functions for raycasting against the BVH in a shader which can be used for things like path tracing, runtime lightmap generation, and other gpgpu applications! The release also includes new typescript definition files.

Here’s the latest demo for path tracing on the GPU which renders a simple Lambertian material. Perhaps at some point I’ll create a more robust gpu path tracing project:

https://gkjohnson.github.io/three-mesh-bvh/example/bundle/gpuPathTracing.html


For those interested the BVH and associated geometry vertex buffer attributes are packed into the textures so they can be sampled in the fragment shader. The shader coder for performing a raycast query is pretty simple, as well. Check out the example code for a full demonstration of how set the shader up! Looking forward to seeing what people make!

9 Likes

https://gkjohnson.github.io/three-mesh-bvh/example/bundle/clippedEdges.html

Looks awesome. Whats the best way to use this to create a cross section through terrain like:

I found this example but by the looks the lines will come out in a random order and I will have to reorder them which could be tricky: three-mesh-bvh/edgeIntersect.js at fbb6b43452ad0a02d494b629673bc9e09e4e211f · gkjohnson/three-mesh-bvh · GitHub

It’s best to come up with an algorithm for achieving the effect you’re looking for without the BVH first. With or without the BVH the results for your chart will have to be sorted based on the domain of the overhead lines you’ve drawn for the cross section chart. Once that’s been figured out you can use the BVH to accelerate the generation of the cross section.

The “clipped edges” or “selection” examples should provide a good start for how to the BVH and “shapecast” function to accelerate the intersections.

2 Likes

@gjix Here is the SO answer, evolved from another one, where contours made from sorted line segments.

1 Like

Thanks. SO answer has this:

function getNearestPointIndex(point, points){
  let index = 0;
  for (let i = 0; i < points.length; i++){
    let p = points[i];
    if (p.checked == false && p.equals(point, tolerance)){ 
      index = i;
      break;
    }
  }
  return index;
}

which would be very slow for a large number of points but Im guessing I could use BVH raycast to point cloud example to find the coincident points to greatly speed this up but it means creating a new point cloud with each point becoming a face. Is there a better way?

I’ve put together a separate repo with a demo Lambertian GPU Path Tracer using three-mesh-bvh that includes support for basic material properties, textures, an environment map, tiled renderer, and mroe. Check out the project page here!

And live demo here:

https://gkjohnson.github.io/three-gpu-pathtracing/example/bundle/lambert.html


“Interior Scene” model by Allay Design


Neko Stop Diorama model by Art by Kidd


Perseverance Rover model by NASA / JPL-Caltech


Sculpture scans model by Threedscans

6 Likes

I had to add a demo with Lego models using the LDrawLoader, as well :grin:

https://gkjohnson.github.io/three-gpu-pathtracing/example/bundle/lego.html

All LDraw Lego models are from this LDraw Model Repository. Enjoy!

6 Likes

WOW, amazing, how did you render it like this!!!

Thanks! It’s using a technique called “raytracing” or “path tracing”. There are some resources at the bottom of the README in the three-gpu-pathtracing repo.

3 Likes

Hi,
@gkjohnson I want to thank you for this great lib.

I try to use three-mesh-bvh to solve my problem.

I have a mesh A ( plan + noise ) and multiple meshes colliding with Mesh A.

I want to distort Mesh A where it collides with the other meshes.

Currently, I created a custom shader that uses the BoundingBox of the meshes to distort the mesh A as shown in the screenshot.

my question is, Can I use three-mesh-bvh instead of the BoundingBox to distort Mesh A precisely?

Thanks.

Yes you can use the “shapecast” function to determine which triangles are hit, save the indices of the triangles, and then adjust the vertices accordingly. The sculpting example does something similar if you’d like to take a look there. Just keep in mind that the BVH must be rebuilt or adjusted after the vertices have been moved so the bounds include the shifted vertices.

Here’s the function in the sculpting example that finds and adjusts the vertices.

1 Like

Great!
Thanks @gkjohnson for your help.