Best way to add physics to a voxel terrain?

Hi everyone! I am working on a personal project with threejs, it consists of a voxel terrain generated randomly using perlin noise.

In order to optimize the game, only the visible vertex are rendered, and the map is splitted by 32x32x32 chunks, each one consisting of a BufferGeometry.

The thing is, I want to add an animal that can move around, I would need physics to control collisions between the animal and the terrain.

I have tried Physijs and used the Physijs.ConcaveMesh shape to give physics to the terrain, however, the start-up of the game becames very slow, going even to minutes.
I also tried enable3d, but I was not able to give Physics to the terrain as it is not a common shape.

What should be the best solution for this problem? Since this is a personal project I am open to try new libraries or do some changes to the terrain creation.


After digging around and asking some friends, I finally ended implementing my own “physics engine” actually I just have a simple velocity+acceleration vectors and small collision detection. But it works for what I expect for this project!

1 Like

That’s what I did in Edelweiss too, sometimes it’s just simpler.

If I may just suggest a little trick to improve performance a lot :
When you import (or create) the map, you should pack the cubes in arrays of 25 cubes, corresponding to 5x5 tiles of your map. You would put these arrays in a two-dimensional array organised according to the whole map.
This would allow you to only check intersection between the characters and the 25 cubes chunk of map in which the character is.

I did it (but split my map vertically, which made more sense with my game), and it helped a lot.

You can do it with enable3d, just pass the shape you want to the options object.

// enable debugging

// add physics to the terrainMesh
physics.add.existing( terrainMesh , { shape: 'concaveMesh' } )

See the shapes example.


Regarding performance. See the game on the website. It uses one huge concaveMesh shape.

1 Like

If you only need basic collisions (like minecraft) and not physically correct and extensive physics you can do it much more efficient with a custom implementation and preferably performing the collision tests against what your terrain generated, not the generated mesh, depending on the complexity.

If the distance field function is complex you might use other techniques, caching or just fixed chunk sizes. If you always store it in a buffer it’s cheaper anyway. Using the equation and “raster” it then to the voxelated shape, to get precise collisions of the actual mesh, not the smooth surface it would represent.