1

I've got a three.js project going where I need to be able to pick individual faces upon mouse movement on meshes of around 200,000 - 300,000 triangles.

I'm using a function like this:

function raycast (x, y) {
    //transform mouse coords relative to main window and normalize
    var normalized = normalizeCoordinates(x, y);

    // create a Ray with origin at the mouse position and direction into the scene (camera direction)
    var vector = new THREE.Vector3( normalized.x, normalized.y, 1 );
    projector.unprojectVector( vector, camera );
    raycaster.set( camera.position, vector.sub( camera.position ).normalize() );

    // create an array containing all objects in the list with which the ray intersects
    return raycaster.intersectObject(mesh);
}

Where normalizeCoordinates is just converting mouse page coordinates to normalized device coordinates.

When mesh uses a THREE.Geometry it's workable, albeit a little slow. For a variety of reasons I decided to try out BufferGeometry instead. This sees great results throughout some other aspects of the project but raycasting becomes too slow. When mesh uses a THREE.BufferGeometry (non-indexed) instead the intersectObject method takes around 4.5 times as long to complete.

Firstly, is this expected behaviour with BufferGeometry, and secondly is there any thing I could look at doing to improve raycasting performance in general (whether Geometry or BufferGeometry)? I'm relatively new to shaders but in particular I wondered whether using a shader to perform accelerated raycasting could be doable.

sja_626
  • 11
  • 1
  • 2
  • Since the data of the BufferGeometry is entirely in the buffers, the intersect calculations are more complicated, I asume. The three.js documentation states : It is mainly interesting when working with static objects. The question is, what you want to do with the intersected objects. To optimize the performance, you can reduce the raycast calls, by calculating only on every 2nd or 3rd. – raphaelRauwolf Jun 02 '14 at 08:53
  • For reference, see an example of GPU picking here: http://stackoverflow.com/questions/17739760/complex-shape-character-outline/21863009#21863009. See an example of octree ray casting here: http://threejs.org/examples/webgl_octree_raycasting.html. – WestLangley Jun 02 '14 at 08:54
  • The thing I'm trying to accomplish is to clone the faces that are picked into a new Geometry to essentially allow "painting" of meshes with layers of color that can be individual turned on and off and have varying transparency. I could perhaps accomplish the same with materials and shaders but either way I'd be raycasting to pick the faces to begin with. It's slow to the extent that even doing it 1 in 3 times would cause the program to stutter too much. I'll take a good look at GPU picking and octree raycasting. Thanks for the references. – sja_626 Jun 02 '14 at 22:46
  • 7 years later, I have a game that relies on a lot of raycasting for collision detection, and I was using Geometry then switched yesterday to BufferGeometry and the frame rate went from 60fps to sometimes 10fps... This is unfortunate but it makes sense the way intersect is implemented. – Octo Poulos Aug 09 '21 at 19:06

0 Answers0