🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Erosion

Published May 27, 2008
Advertisement
Finally got off my lazy butt and implemented a hackish sort of terrain erosion in Accidental. Been playing with various somewhat-realistic hydrology-based models, but most either netted poor performance or poor results (due to ambiguous specifications in the tech papers, and/or my poor efforts at implementing them). Finally settled instead on one that isn't based on water flow, shallow water equations, or anything of that nature. Performs the erosion in a single pass, eroding to a specifiable degree. While it is still a tad slow on a full-resolution pass, it is specifiable to degrade the quality of the erosion as well for better performance. Here is a preliminary test. In sequence the images are: No erosion (base map), Power=0.1, Power=0.3 and power=0.5 (maximum erosion power).



It's not perfect by any means, but it is fairly fast, and the results are acceptable.

EDIT: Some test renders of the base and fully eroded terrains:

Previous Entry Wireworld
Next Entry Back. And married.
1 likes 3 comments

Comments

LachlanL
Wow, those results look really nice! I especially like the one with the highest power.

I was wondering if it'd be too much to ask if you could expand on the algorithm you're using? I wouldn't mind being able to implement some erosion in my terrain, but I totally understand if you want to keep it under wraps.
May 27, 2008 08:01 PM
JTippetts
It's basically a hack. I spawn a bunch of 'rain drops' all over the map (which are just x/y pairs), then iterate through the list of raindrops, moving each one down by choosing it's lowest neighbor, until it can't move down anymore. At each step, I calculate new heights for the current location and the lowest neighbor by:

ht=height at current location
lowh=height of lowest neighbor
new_lowh = (ht + (1.0-power)*(lowh-ht)); // New height for lowest neighbor
new_ht = (ht + power*(lowh-ht)); // New height for current location

This has a tendency to average or smooth out these adjacent values, raising the low neighbor and lowering the current cell. At full-power (power=0.5) they meet in the middle. I clamp the power to the range [0,0.5] since values outside this range can be bad. (In particular, power > 0.5 can result in an infinite loop where the raindrop bounces back and forth between 2 locations)

Sometimes you have to run a single pass of a small Gaussian blur kernel across the final result to smooth out some jaggies, since it really is a hack of an algorithm. For some terrain types it works very well, but others not so much. I'd still like to work out a suitable hydrology-based erosion filter for more realistic results.

In my algorithm, you can specify the number of raindrops to spawn. If the number is greater than 0, then it spawns that many drops randomly located across the map. If the number is <=0 then it spawns one drop at every heightmap location, then randomly shuffles that list.

I also randomize the order in which I visit the neighbors of a raindrop each time, so that one direction isn't constantly favored. This adds another random_shuffle per step, so it is a source of slowdown. Thinking of changing it to only shuffle per raindrop rather than step.

EDIT: Here is a rendering of some mesa-style desert terrain showing the artifacts introduced by this erosion method. A blur usually takes care of these kinds of jaggies.


May 28, 2008 08:14 AM
LachlanL
Wow, thanks for that! I might end up implementing something similar for my terrain generation. Currently I only use user-seeded diamond-square, but some erosion settings might provide some better realism.

Rate up! [smile]
May 28, 2008 07:36 PM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement