Water and buoyancy

We’ve had water working from a voxel rendering perspective since long, and the player movement in water and associated sound effects and rendering effects also works fine. But making the other dynamic voxel objects and mobs/NPCs to move and float in a sane way has been on the TODO-list for far too long, resulting in the current silly-looking behaviour of broken-off voxels and cows falling straight through the water to the bottom and then keeping moving there completely unobstructed 🙂

The main reason for the delay was that we weren’t satisfied with our plan on how to implement buoyancy (the force that pushes submerged things upwards in water) and rendering. We still are not, but we’ve at least started implementing it anyway now.

Pieces of a tree floating in water gracefully

Pieces of a tree floating in water gracefully

Regarding the physics part of the problem, buoyancy arises from the difference in pressure at different depths in a volume of water. When something is submerged, this pressure gradient causes forces at all points on the object perimeter, resulting in an upwards force and possibly torque on the object. If this force is larger than the gravitational weight of the object, it rises, otherwise it falls. The reason similar items with different density floats unequally is because the difference in the force of weight, while having the same buoyant force due to having the same geometry.

Illustration of how a pressure gradient results in buoyancy. Courtesy of Wikipedia.

So, to simulate properly, we need access to the exact pressure at all water depths (doable but not implemented yet), the density distribution of objects (easily implemented), and also the CPU-time to actually probe for the water pressure at enough points and to sum them. Currently we just do the tests using a trivial upwards force on the center of mass and will go back to evaluating more advanced methods later.

Half-submerged but still floating car

Half-submerged but still floating car

The render-problem comes from the fact that the water is voxelized but the items that fall into it doesn’t actually push the water voxels out of the way, as that would look bad due to the water quantization (but who knows maybe that will look better later with smaller voxels). So, currently objects are simply rendered on-top, behind or inside the half-transparent water-voxels. Thanks to z-buffering this does indeed look OK (see the image above) but the problem comes when you want to have objects that float without water *inside* them, like the inside of a boat below the waterline or a submarine. The current system will just render the waterline due to the water-voxels and that’s it.

From an effects perspective, it was easy to add some particle system versions of splashes and the associated sound effect when something enters or leaves the water. We had to be a bit careful not to let objects bobbing on the waterline to spam the effects system though so some hysteresis was needed.

Swimming under some floating objects

Swimming under some floating objects

Nevertheless, even with the simplifications the upgrade instantly produced a great addition to the realism and “gameplay”. After we’ve added the density calculations and added the rudder and water turbine blocks, it will be possible to create (shallow) boats and cruise around with your cow and pig and just experience life!

A fun failure-mode is shown in the video below, where the buoyancy forces were too large and too quantized so very light objects had a tendency to jump out of the water and just keep bouncing 🙂

Share Button