Perlin Noise for rivers...

Started by
7 comments, last by alvaro 10 years, 8 months ago

I'm using a form of perlin noise to build out my maps and terrain placements. Its working fairly nice, but as far as the water is concerned, it is only building lakes and small ponds.

Anyone have any ideas on how to get some semi jagged lines into a perlin noise equation?

My perlin noise is a custom random function that produces a number off of X, Y and PlayerId, returning a float between 0 and 1.

For Height, I get perlin + (perlin << 1) + (perlin << 2) (etc up to 4) (where the X and Y coords get bit shifted) This gives me nice smooth rolling hills with lots of variance.

For Tile Type, I'm using height < 1 = water, then does a bitshift << 3 (8x8 area) to get the default terrain type, then the closer it is to the center, the more likely it will be that type vs some random other type. This gives me nice randomized areas. The game only shows about 20 tiles across at any time, so the 8x8 tiled masses aren't noticed too much.

But I want to make this more river based, Valleys, Streams. It seems like I need another fractal equation to define rivers.

I'm very open to change on this equation.

Moltar - "Do you even know how to use that?"

Space Ghost - “Moltar, I have a giant brain that is able to reduce any complex machine into a simple yes or no answer."

Dan - "Best Description of AI ever."

Advertisement
Physically accurate (or even somewhat physically accurate) rivers are very difficult to do using implicit (ie, numeric/mathematical function) methods, and somewhat easier to do using explicit (ie, iterate over a buffer or chunk of data) methods such as erosion simulation and waterflow. There are certain ways you can nudge the generation of your Perlin terrain to be more river-like, however; just don't expect it to actually "make sense" from a physical perspective without physical modeling. One possibility: use an octave or two of ridged noise super-imposed upon the terrain.

Here's a terrain:

NctsJk7.png
upIozhi.png

Here is a single octave of ridged noise:
cdVqNCx.png

Here is the terrain with this river function super-imposed on it:
5EMTuKQ.png
5Joclmu.png

If you don't like the straightness of the rivers, you can use yet another fractal to distort the river function:
UycJ5kZ.png
bsl33qr.png

It's not even remotely physically accurate (rivers can run up and down hills at whim) but in the case of doing just a flat tile map it might be acceptable.

Additionally, there are things you can do to the base noise fractal itself, such as domain distortion, to make the underlying terrain appear more eroded. For example, here is the original terrain directly distorted by the ridged fractal (rather than having the ridged super-imposed upon it):

3I410lJ.png
zFFUkNC.png

This method creates more ridge lines and valleys (still not physically accurate) with less of an obvious network-like appearance.

Still, hacks aside, the best method is probably to run an explicit pass of some sort over your terrain after generation. Common methods involve doing an erosion simulation to build the watershed, then tracing the paths of rivers via some sort of particle-type simulation or even a full-fledge water flow and accumulation simulation. Barring that, you could just trace rivers starting from some seed point (usually the terminus, ie where it runs into the ocean or other body of water) uphill until it can't go up any higher. This at least traces the river network, though it doesn't do much for lakes and ponds.

My personal favorite is to do an erosion pass and a flow simulation to get rivers, lakes and ponds all at once.

One possibility: use an octave or two of ridged noise super-imposed upon the terrain.

I've been trying to look up ridged noise, and not finding much luck in determining an equation for it. do you have an example of how to get a value (such as a height variable) for a specific X/Y (location) value?

Thanks.

Moltar - "Do you even know how to use that?"

Space Ghost - “Moltar, I have a giant brain that is able to reduce any complex machine into a simple yes or no answer."

Dan - "Best Description of AI ever."

Ridged noise is built almost exactly the same as standard fBm noise, the only difference being that you take (1.0 - abs(val)) for each octave value before summing the octaves together. This creates "ridges" where the value of an octave crosses the 0 line.

I have never used fBm before. Can that be obtained for a specific pixel, without having to figure out any other pixels? for instance, I have a server function that wants to know the height for a given spot. To do that, it simply runs the height method I used for that particular tile with its X/Y coord.

Before I spend time figuring out Fractional Brownian Motion (presuming thats what the fBm is) can I use this method your talking about with knowledge of only my current Pixel's X & Y? or does it need a map/full image to work off of?

Thanks.

Moltar - "Do you even know how to use that?"

Space Ghost - “Moltar, I have a giant brain that is able to reduce any complex machine into a simple yes or no answer."

Dan - "Best Description of AI ever."

I haven't read through the details, but I like the results of this method: http://dl.acm.org/citation.cfm?id=2461996

EDIT: Here's a video to go with it:


I haven't read through the details, but I like the results of this method: http://dl.acm.org/citation.cfm?id=2461996

Thanks, that is a very impressive river display. Unfortunately, it is based against an existing map, as opposed to an equation that figures out a height map, pixel by pixel that provides rivers.

Thanks though.

Moltar - "Do you even know how to use that?"

Space Ghost - “Moltar, I have a giant brain that is able to reduce any complex machine into a simple yes or no answer."

Dan - "Best Description of AI ever."

I have never used fBm before. Can that be obtained for a specific pixel, without having to figure out any other pixels? for instance, I have a server function that wants to know the height for a given spot. To do that, it simply runs the height method I used for that particular tile with its X/Y coord.

Before I spend time figuring out Fractional Brownian Motion (presuming thats what the fBm is) can I use this method your talking about with knowledge of only my current Pixel's X & Y? or does it need a map/full image to work off of?

Thanks.


fBm is just a fancy name for the "standard" Perlin fractal noise that you see everywhere. In my earlier post, the first image of the base terrain is fBm. It's a sum of noise layers, with the frequency of each successive layer doubling while the amplitude halves. Ridged multifractal noise is the same, except at each layer you take the absolute value and invert it before adding it in. Each variant can be evaluated point-by-point.

I haven't read through the details, but I like the results of this method: http://dl.acm.org/citation.cfm?id=2461996


Thanks, that is a very impressive river display. Unfortunately, it is based against an existing map, as opposed to an equation that figures out a height map, pixel by pixel that provides rivers.

Thanks though.


I don't think that's true. I think their technique can be used to generate the rivers and then merge that with a noise-type terrain.

This topic is closed to new replies.

Advertisement