Fast RayTracing in a speckle viewer

  • Objective: Fastest way to raytrace in a speckle scene loaded in the viewer.

  • Issue: Currently I’m doing raycastings as follows:

  
  // Get the SpeckleRenderer from the viewer
    
    const renderer = viewer.getRenderer();

    // Create a ray from origin and direction
    const ray = new THREE.Ray(origin, direction);
      
  
    // Get intersections using Speckle's raycasting system
    const intersections = renderer.intersections.intersectRay(
      renderer.scene,
      renderer.renderingCamera,
      ray,
      ObjectLayers.STREAM_CONTENT_MESH,
      false, // nearest
      undefined, // bounds
      firstOnly, // firstOnly 
      false // tasOnly
    );

This works; however, it’s currently very computationally taxing to run. Is there another way to do ray scene intersection besides doing shape casting that could achieve a similar goal?

Hi @Leul_Tesfaye

You are using the recommended way of doing ray-scene intersection. All intersection functions from intersections will use the BVH for testing which is very fast. In fact, internally the camera controller is using the same function for computing the best near plane value each time the camera moves.

What is your use case, how are you using intersectRay, and what is the end goal? If it’s actual ray tracing like the title says which implies that you shoot a ray from each pixel on your screen then I’m afraid that might be too much since the viewer is not at all tailored for software raytracing. But even so, if you’d explain more what you are trying to achieve, we might be able to help

Cheers

Hey Alex,

Thanks for the prompt reply! My current objective is to design something that can raytrace in cardinal direction around an object to find the closest object in that path. For my purposes I choose to return full intersection since I’m interested in avoiding self-collisions with the center object and then doing manual post processing to figure out the correct object. Currently, the full intersection in 6 directions corresponding to +X,-X,+Y,-Y,+Z,-Z around the center of the object’s bounding box results in about a 7-second computation delay, and I was wondering what the best way would be to minimize this as much as possible.

Hey @Leul_Tesfaye

If what you need is to find the closest object starting from a point (which would be another object’s center) and going in a specific direction (which would be +x, -X, +Y, -Y, +Z, -Z) then you can use an existing method provided by the top acceleration structure called closestPointToPointHalfplane.

The viewer also uses the same method when it wants to find the nearest geometry point to the camera. Because it’s being called essentially every frame as long as the camera is moving, it needs to be very fast. That’s why it’s only querying the top level acceleration structure, and the results it provides are not 100% accurate in the sense that it will provide you with a hit result on other object’s bounding box instead of it’s actual geometry.

The good news is that if you need 100% accuracy you can still use the same approach but instead of querying the top level acceleration structure only, you could query the bottom level which holds BVHs for actual geometry.

A 7 second execution time for such task is unacceptable. I would imagine an operation like this to execute in the range of milliseconds if we can be smart about it. I’ll gladly help you out, but first you need to share with me a stackblitz (like we did in the past) with what you have going right now, and we can iterate on it together.

Cheers