So I’m making a browser game using THREE.js as the back bone. It’s a pretty ambitious game but I’ve been steadily working on it for over four years.
I’m wondering how much overhead memory THREE.Mesh takes up. The reason being that I need to do many raycaste calls with collision geometry made up of the THREE.Mesh class. To speed up the process I’ve dissected the collision geometry into small bits so that a raycaste call only need to calculate the smallest number of geometries. However, this means the program has to have hundreds of thousands of THREE.Mesh classes stored in memory and I’m wondering if I should create a new class inspired by the THREE.Mesh class but strip it down to it’s bare bones. Would it perform better?
Hmm… first reaction, this sounds like a heavy solution to me. I assume you’re still rendering using a much smaller number of meshes? How are you using the raycast mechanism?
You might be able to do other forms of raycasting in a Web Worker. Or say, render each mesh group a different color to an OffscreenCanvas in one draw call, read the appropriate pixel, and use the unique color to identify the group?
EDIT: But maybe not, I’m just guessing here. Have used picking with a framebuffer in OpenGL in the past.
the collision geometry I’m not rendering at all. It’s invisible to the scene. But basically I have a world broken into 68 parts. Each part is rendered if it’s in view. The collision meshs are divided in 272 parts. but I want to divide them even further into 200000 parts. that way when I do a mesh raycaste call I’m not checking thousands of faces for one call, but rather 1 or two.
I wonder why you use meshes instead of bounding volumes and spatial indices. That’s the common approach to increase performance. To be more precise
- Use bounding volumes like bounding spheres (THREE.Sphere), axis-aligned bounding boxes (THREE.Box3) or more advanced stuff like k-DOPs or convex hulls (THREE.QuickHull). Raycasting or intersection tests with such entities have in general a good performance.
- To improve runtime complexity of NN-queries from O(n) to O(logn), you can use a spatial index like an Octree (see example). The usage of spatial indices always comes with some overhead but in very complex scenes it can be a real game changer.
BTW: The memory consumption of simple bounding volumes like a bounding sphere or an AABB is very cheap. A single bounding sphere just requires four floats, an AABB six. An instance of
Mesh allocates much more memory.
could I use the bounding spheres to determine if a raycaste will intersect a face of an existing mesh then? Basically, instead of getting the raycaste and targeting it against the mesh, get it to target a bounding sphere for a specified face and then get a result? is there a tutorial somewhere showing how to do this?
If you do a raycast with
three.js against a mesh, the code automatically performs a raycast with the bounding sphere first. If no intersection is detected, an early out is performed:
Right now, there is always a single bounding sphere and AABB per geometry. But you can divide your geometry into multiple bounding volumes and test against them. Or you break down your geometry into individual parts. In both cases, the subdivision would be coarse. So you would not have a bounding volume per face.