Terrain With Dynamic Water


My terrain system now includes a water simulation where when terrain modifications are made the water will flow, over time, into new areas etc. You can also place water sources and drains and so on.

It is important that nav agents don’t walk into the water.

Before this simulation I had a single plain for the water and had a RecastMeshObj that marked the water as nav blocking. Now the water itself is rendered using a grid mesh that is offset using a height map so presently i don’t have a water mesh as such. It can obviously also be at any height.

What is the best way to do this? I have some ideas:

  • Generate a mesh that is updated with the water and add a RecastMeshObj to it.
  • Generate a flat mesh that i used to make a nav cut.
  • Use tags. It’s not clear whether this would even work because the recastmesh nodes are not at a fine granularity and so nav mesh triangles could easily have one vertex under water and the other two above.
  • Prevent the agents walking under water some other way, maybe at the path finding level somehow. I have access to both the water height map and terrain height map and so I can know on the CPU side which bits of terrain are under water.

Any tips?



If world is small enough, I would use a grid graph since they can be updated more quickly.
I assume this water covers most of the world, so any change to the water level would essentially require the navmesh for the whole world to be updated?


I used a grid graph before but it wasn’t fast enough to update for real-time painting and it also wasn’t suitable for bridges etc because of the world size and number of cells in use.

My plan for this is to generate the water mesh on the GPU and keep track of where the water changes so that only parts of the nav mesh where the terrain-under-water state changes is updated. I’ll basically only update the nav tiles where the water enters, changes or leaves so tiles that dont have water or are entirely water won’t be updated.

I’ll probably only update a few tiles per frame as well to avoid lag.