top | item 34409475

(no title)

mehwoot | 3 years ago

The basic technique is from a research paper: https://www.researchgate.net/publication/4295561_Fast_Hydrau...

My first attempt at creating a simulation of water and erosion before I saw this paper was pretty bad as well.

Yes, it's a grid based system. When you choose map size (e.g. 1024x1024) that's the resolution of the underlying simulation. My refinement of this approach is there is an extra step that "smooths" everything out. The vertex points for rendering are offset depending on how the water flows, which allows rivers to appear to flow at angles other than 90 degrees. Without this, it would either be very blocky or cover a much smaller area- there are other implementations of that paper floating around and the scale is an order of magnitude less, as a river needs to be many grid points across. In my implementation, you can get a nice looking river from a sequence of single points.

The drawback is this complicates a lot of other things. E.g. you can no longer easily tell what the height is at a point on the map is- there is no easy way to know what vertices to interpolate between since they can be offset in different directions. So when rendering trees, there's a whole GPU calculation to produce a separate data layer just to know what height the ground they're sitting on is at. But it's worth it to get a map that covers a big area with a full water flow simulation.

In general terms, the simulation is done as a series of grids of values (called layers, in reality just textures on the GPU) and operations that take some of them as input to generate another. Some layers persist always (e.g. the water flow) and update themselves iteratively. Other layers are produced on the fly when needed, and can be at different resolutions. E.g. you zoom into an area of the map- the water layer is read to determine the biome layer for just that part of the map. The water layer is read to determine the heights layer I talked about previously. Then the biome layer, water layer and heights layer are combined into a trees layer where one grid vertex is one possible instance of a tree. The values represent whether a tree is there, the position of its base, the type of tree, etc.

That's used as input for the rendering system, there's a mesh that uses that trees layer to render all the trees. It's also used as input for the animals system, so the animals walk around the trees, etc. It's basically a big dependency graph of data layers and the operations needed to generate them. Most of the work so far has been building all that tooling and getting it running asynchronously so the game doesn't lag if it takes multiple frames to generate what is needed.

discuss

order

alex_duf|3 years ago

Thanks for taking the time for such a thorough response, I appreciate. Really interesting stuff!