Perlin Noise Exposed

Started by
14 comments, last by technobot 19 years, 7 months ago
A more accurate solution would be as follows:

Suppose you know the distribution of values output from Perlin noise, say some distribution p(x).

To generate a uniform random value, start by computing your perlin noise function to get a value x. Then compute integral 0..x, p(t)dt. This will give you a value between 0 and 1, uniformly distributed. And since this is a continuous transformation of the output of your Perlin noise function, it will still be nice and smooth like the original.

Also note that you no longer need to use perlin noise, it can also be some kind of fractal noise, etc.

I suppose the only part left would be figuring out the distribution for your noise function, but this should be easy using statistical techniques.
"Math is hard" -Barbie
Advertisement
Take any four uniformly distributed numbers and average them. You should indeed get a gaussian distribution. This is what you're basically doing with the 4 perlin corner vectors(uniform) and your DotGrad function.

Consider it this way. Generate a random number in the range [0,1]. Say 0.7. You only have a 30.0% chance to land in the range [0.7,1] again. Multiply four 30.0% chances together. You only have a 0.81% chance that you'll land in the upper 30% for all four.

Consider also that most of the time this is the desired result. You only want really really tall mountains or really really low valleys less than 1% of the time. If this is not the case and you want truly uniform values, try using a standard Psuedo-random number generator(PRNG) where you feed two input values and get back a predictable result each time. (I would recommend RANROT)
A conclusion is simply the place where you got tired of thinking.
Quote:Original post by technobot
Quote:Original post by Dmytry
Strange. My re-implementation of improved perlin noise gives values in range
-0.97...0.98
after 106 tests.

With 10^6 random samples, I get that range as well. But there are only very few samples near the extremes of that range. I get the reduced ranges when sampling at regular intervals inside some area around the origin, the way it's done when generating terrain. Try counting how many values you get outside of [-0.8, 0.8]. If the distribution is anywhere near uniform, you should get fairly large counts. If the distribution is gaussian, you should only get a very small fraction of the total.


Anyway, it seems I'll just divide by 0.75 and clamp. That seems to work reasonably well...

I don't think perlin noise have really gaussian distribution. Yes,it's looks kinda like, but it surely not.
(IIRC if you add up infinitely many uniform distributions you'll get gaussian, if it's not so my text doesn't make much sense and i need to renew my statistics)

I would not clamp. I might multiply, but i think it's not very good to clamp. There's ~106 points on the screen. It will be sometimes visible. Also, you get derivative discontinuity.

You can try to get some function of noise to change distribution.
For instance something like
f(x)=x/sqrt(x2+1)
clamps to range more-or-less gently.
So you can use
noise2=f(noise(...blabla...)*k)/f(k)
(try with different k.)

In fact, by taking carefully choosen function of noise value you can get any distribution you want, if you know distribution of noise. Read some statistics books for more detailed information.

To convert to uniform you need to make function that returns probability that value is less than parameter. (can't remember correct English term). Approximation can be done by sorting many samples., so you get table of that, then least-square-fitting polynomial of high enough degree, so you'll not need big table.

Then, to convert uniform to distribution you want, you need to take function that is inverse function of intergal of distribution_you_want.

edit: OPS, Pragma and Vystrax was first.
Anyway, Perlin isn't really gaussian because there's only 4 random numbers and also because of spline(it changes distribution).
Quote:To convert to uniform you need to make function that returns probability that value is less than parameter. (can't remember correct English term).


It's called a CDF or Cumulative Distribution Function.
"Math is hard" -Barbie
Quote:Original post by Pragma
Quote:To convert to uniform you need to make function that returns probability that value is less than parameter. (can't remember correct English term).


It's called a CDF or Cumulative Distribution Function.

Thanks.

BTW, about my post,
"
You can try to get some function of noise to change distribution.
For instance something like
f(x)=x/sqrt(x2+1)
clamps to range more-or-less gently.
So you can use
noise2=f(noise(...blabla...)*k)/f(k)
(try with different k.)
"
, f(x) _looks_ like CDF of some distribution with peak at 0.
Ok, thanks guys. Running the noise function trhough f(x)=(2-|x|)*x gives a near uniform ditribution in the [-0.5,0.5] range, and linear distribution outside that. It's as uniform as I could get it so far without using look-up tables.

Vystrax, that's a good point about the tall moutains etc. It occured to me as well some time ago. Still, the chance for extreme values in the unmodified perlin noise seems a bit too low to me. I'll have to play with it some more to see what looks best.
Michael K.

This topic is closed to new replies.

Advertisement