Sign in to follow this  
LilBudyWizer

2D Perlin Noise

Recommended Posts

LilBudyWizer    491
I have trouble seeing how you ever get outside the range of +/- 1/sqrt(2) with Perlin noise. The maximum value for the dot product is going to be if the gradiant is pointing right at the point. So the displacement from the corners is the maximum corner values for a point. The weighted average of those is the maximum value the noise function could produce for that point. That allows you to create a function that returns the maximum possible Perlin noise value for a given (u,v) coordinate. Plot that height field and the maximum is at (0.5,0.5) and is 1/sqrt(2). That drops off rapidly to 0 at the corners and not so rapidly to 0.5 at the mid-points of the sides. Am I doing something wrong here?

Share this post


Link to post
Share on other sites
Squirm    481
if you want a larger number, multiply by 2. or 20. or 276548.

If you want to remove the zero points, make 2 lots of perlin noise, offset one of them by 0.5,0.5, and add them together.

Sounds like you've got the noise function fine, but the question isn't really sensible?

Share this post


Link to post
Share on other sites
LilBudyWizer    491
So if I want numbers from 0 to 255 then what do I multiply by so that it is possible to get 0 and 255, but never get numbers <0 or >255? Does that make more sense?

Share this post


Link to post
Share on other sites
ApochPiQ    23064
If your range is +/- 1/sqrt(2), then to convert to 0-255, add 1/sqrt(2) which will move your range to 0-(2/sqrt(2)). To get to 255, just multiply by sqrt(2) * 127.5. Note that if you do this in single-precision floating point, you may end up with some rounding error; even double-precision may not work perfectly. It'd probably be in your best interests to clamp the values to 0-255 manually after the conversion just to be safe.

Share this post


Link to post
Share on other sites
LilBudyWizer    491
The question was actually what is the range of the perlin noise function. More precisely it was whether I made any mistakes in how I concluded that the range is -1/sqrt(2) to 1/sqrt(2) since I've seen a number of papers state the range as -1 to 1.

Share this post


Link to post
Share on other sites
ApochPiQ    23064
That depends a lot on the actual function. I've seen many, many different noise implementations that describe themselves as Perlin noise, but very few use his original function. Perhaps you could post some code?

Share this post


Link to post
Share on other sites
You are suppose to get a number between 1 and -1.

Let's suppose they are stored in a 2-dimensional array, called noisedata[100][100]. The data in this array is all between 1 and -1.

so here is what you do to get a range of 0 - 255.


// Run two "for" loops to access each variable in the array.
for(int i = 0; i < 100; i++)
{
for(int j = 0; j < 100; j++)
{
noisedata[i][j] += 1;
noisedata[i][j] = (noisedata[i][j]/2);
noisedata[i][j] *= 255;
}
}



this should give you noise in the range of 0 - 255

Sagar Indurkhya

Share this post


Link to post
Share on other sites
LilBudyWizer    491
Well, I'm playing with this in MathCAD so there is a worksheet rather than code. The following will give you the basic idea though.

[SOURCE]

Weight1D(t) = 6t^5-15t^4+10t^3

Weight2D(u,v) = Weight1D(u)*Weight1D(v)

MaxPerlin(u,v) = Weight2D(1-u,1-v)*|(u ,v )| +
Weight2D(u ,1-v)*|(1-u,v )| +
Weight2D(1-u,v )*|(u ,1-v)| +
Weight2D(u ,v )*|(1-u,1-v)|

[/SOURCE]


Now, in code I wouldn't use the easing functions that way since it is eight evaluations of a fifth order polynomial instead of two. MathCAD carries expressions so it isn't fast no matter what thus it makes little differance there. It is the same as a bilinear interpolation modified to use this weighting function. I have expanded that out, collected terms and factored the coefficents on terms to verify they are equivalent.

Also this is intended to calculate the maximum possible noise at a given (u,v) coordinate within a cell. An actual Perlin noise function would use G.(P-Q) where G is a random unit gradiant assigned to a corner, Q is the coordinates of the corner and P is the point being evaluated. I want the max so G points in the direction of P from Q and since G is a unit vector the dot product is |P-Q|, i.e. |1||P-Q|cos(0).

I am fairly confident of the calculation. Just because I am absolutely, positively, beyond any doubt certain it is correct does not mean it is correct though. I am not that certain it is correct and a lot of papers say it produces noise in the range of -1 to 1 which is my main source of doubt.

Share this post


Link to post
Share on other sites
ApochPiQ    23064
Perhaps I'm just not seeing it because I've never used MathCAD, but I'm really not sure how this blurb is Perlin noise. Perlin noise relies on having a set of randomly generated seed points; beyond that it's really just an interpolation function and a lookup into the seed table.

Share this post


Link to post
Share on other sites
Quote:
Original post by LilBudyWizer
At this point I have to assume you intention is merely to be difficult and this is a complete waste of my time.


Don't scold ApochPiQ. He is correct. All perlin noise is is looking up the sum of different octaves of a random point, with some interpolation thrown in. If you don't know what you are doing, than making sly remarks won't help.

Share this post


Link to post
Share on other sites
Eelco    301
i think i know what your problem is, but you yourself dont. or am i being arrogant now :)?

anyway, i have also always have had problems with scaling perlin noise to 0-255 range. the problem is, when you have a lot of octaves, the possible minimum/maximum can be quite large, yet the probability of them actually occuring very low. calculating the theoretical maximum/minimum isnt hard if you know what youre doing, but if you scale this entire range to 0-255, youll get very low contrast, since 90% of all values have very little chance of occuring. in my opinion, the best solution to this is simply scaling your output slightly up, and clamp the values that go below 0 or above 255. youll need a bit of tweaking to get it right, but usually capping to half the theoretical maximum gives good results.

Share this post


Link to post
Share on other sites
_DarkWIng_    602
The maximum range of single octave is [-1,1]. But for multiple octaves you sum up more of this ranges with different amplitudes. So, toget max range just sum up amplitudes (usualy something like 1 + 1/2 + 1/4 + 1/8 + ...). But Eelco has a point. Getting maximum value has a very lov probability, so just scale this range down a bit and clamp it. You also might want to read new verison of perlin noise here. This one is using a new interpolation function and hashing and is actualy a bit faster.

Share this post


Link to post
Share on other sites
Kylotan    10010
Quote:
Original post by Sagar_Indurkhya
Quote:
Original post by LilBudyWizer
At this point I have to assume you intention is merely to be difficult and this is a complete waste of my time.


Don't scold ApochPiQ. He is correct. All perlin noise is is looking up the sum of different octaves of a random point, with some interpolation thrown in. If you don't know what you are doing, than making sly remarks won't help.


Actually, you are incorrect. Perlin noise - as opposed to any other kind of noise - is a particular implementation of noise generation.

Read Perlin's algorithm. Especially the Java demonstration.

Share this post


Link to post
Share on other sites
Dmytry    1151
Let's name one octave "Perlin noise" as "Perlin basis",just because it are sometimes used but does not have too broad meaning. Just to avoid turning this thread in definition war...
There are many basises that are (correctly and incorrectly)named "Perlin basis",and many variations,such as ridged perlin.

IIRC adding octaves together was known long before Perlin got idea about his basis.
Adding many octaves of basis are named making fractal from basis,for instance from perlin basis,or cellular/voronoi basis,or ridged perlin.
There are many ways to make fractal,and octave-adding are simplest one.Better variations rotates each noise by some angle to prevent artefacts.Also there are multifractals(google keyword:perlin multifractal Perlin are needed in keyword only because "multifractal" are too frequently used and misused)


Back to original question :
as i understand,LilBudyWizer want to find maximal and minimal value of certain kind of perlin basis. Yes,in many papers perlin basis are said to vary bethween -1..1,and different formules are given that are NOT in -1..1 range.bn Perlin himself said that he wanted it to be like sine wave,in -1..1 and with some period,and all.

In reality,range are only somewhere near to +/-1 ,it's mean that it's not +/-10 or +/-0.1 ,but may be +/- sqrt(2) .So LilBudyWizer are somewhat right,he are implemented single cell of perlin basis with maximal possible value by using some constants instead of random,and got +/- sqrt(2).

And it's not quite right to use perlin basis but not bother checking what minimal/maximal values it may have.

Share this post


Link to post
Share on other sites
Quote:
Original post by Kylotan
Quote:
Original post by Sagar_Indurkhya
Quote:
Original post by LilBudyWizer
At this point I have to assume you intention is merely to be difficult and this is a complete waste of my time.




Don't scold ApochPiQ. He is correct. All perlin noise is is looking up the sum of different octaves of a random point, with some interpolation thrown in. If you don't know what you are doing, than making sly remarks won't help.


Actually, you are incorrect. Perlin noise - as opposed to any other kind of noise - is a particular implementation of noise generation.

Read Perlin's algorithm. Especially the Java demonstration.


I have already seen that, and made 7 different implementations of perlin noise, including the use of the z-dist table and the f-dist table. We aren't arguing over the exact definition of perlin noise. You are suppose to get a value between -1 and 1. You then SCALE the values to fit your needs. Check out hugo elias's page, which is considered one of the best.

Share this post


Link to post
Share on other sites
ApochPiQ    23064
Perlin's original algorithm was pretty specific, and yes, to be fully accurate "Perlin noise" is supposed to be close variations of his original method. The only allowable difference is the interpolation functions, at least according to his notes that I've read.

However, in the common usage, "Perlin noise" has come to refer to an entire family of noise functions, all based on the table lookup and interpolation method. I used the term (incorrectly though it may be) to refer to the family of noise algorithms rather than the original function itself. My fault for being ambiguous there.

As Dmytry said, the actual output range of the basis function can vary quite a bit even within Perlin's original specs, depending on the interpolation function you use. Generally, scaling the output of the basis function into the desired range is considered much more appropriate than trying to get a basis function that defaults to the correct output interval [-1, 1]. Personally I use a modified Perlin algorithm, which was originally written for the Vivid raytracer, adapted for POV-Ray, and now hacked out a bit with my own changes for the Freon 2/7 raytracer. It has the advantage of naturally producing output on the interval [-1, 1] but at the expense of a small amount of quality and variance.

The real question, then, is what LilBudyWizer is really after. If the interpolation function you're using is what you need/want to use, then your best shot is to transform the output into the desired interval as I described earlier. However, if you want to naturally reach the interval without post-process transformation, you'll need to change the basis function.

In any case all I see from the MathCAD snipped that was posted is the interpolation part of Perlin-style noise; the actual seed point lookup still appears to be missing. The output range of the algorithm is heavily affected by the values of the seed points, which effectively act as scalar coefficients for the actual noise values. The range of the seed values will necessarily be the range of the noise output, unless you are using loose interpolation, i.e. the seed values are not guaranteed to lie on the interpolation curve. One of the speedup tricks I used in Freon 2/7's noise function was to scale the original seed points rather than transforming the result of the function on a per-octave basis; after multiple octaves I still need to re-clamp the range, but the individual octaves are guaranteed to lie on the appropriate interval.

Anyways, without further input from the OP, this is all rather academic.

Share this post


Link to post
Share on other sites
LilBudyWizer    491
What would be looked up is a unit vector with some random orientation. Then I would calculate a dot product with the displacement vector. This isn't a noise function though, there is nothing random about it. The dot product is maximized when the two vectors point the same direction. Since the goal is a function giving the maximum possible noise value rather than a noise function the gradiant always points the same direction as the displacement vectors. The dot product A.B = |A||B|cos(t), but since t=0 and |A| = 1 there isn't much point in calculating the dot product since it is just going to be the distance from the respective corner. Once more for clarity THIS IS NOT A NOISE FUNCTION.

Share this post


Link to post
Share on other sites
ApochPiQ    23064
I really don't understand how you can be looking for the maximum value of a noise function when you aren't examining an actual noise function. As I said above the range of the function is partially dependent on the values in the seed points; if all the seed points are on the interval [0, 0.15] then your maximum noise value will be 0.15 unless your interpolation/easing function is not guaranteed to pass through the control points (I know there's a technical adjective for this behavior but I can't remember it at the moment).

I'm having trouble understanding your reasoning for why your function is set up the way it is. When the gradient for each lattice point is oriented the same direction as the vector from your sample point to that lattice point, the dot product is as you mentioned maximized (ie. 1). The easiest example is to take one lattice cube and have the sample point in the dead center, and the eight gradient vectors being simply extensions of the rays from the sample point out through the lattice points (corners of the cube). Assume all of the gradient vectors have length G. At this point all of your dot products are 1. If we leave out the easing function, the linear interpolations will result in a maximum weight of 1.0 * G. If we then replace the easing function, the maximum weight becomes f(1.0) * G.

By this logic, the theoretical maximum value is entirely dependent on two factors: your easing function, and the weights used in the seed points - which is what I've been saying all along. If this isn't the result you're looking for, it'd help immensely if you could describe your train of thought a bit more as to why exactly your function is set up the way it is.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
There's no need to multiple result by constant or change algo to get value in -1..+1
Just change constants in "easing function",hehehehe.

ApochPiQ:
But dot products are not one for center because direction vectors from corners are not one unit big,and for 2d case,are sqrt(2)/2 big.
Here and later i'm discussing 2d case because it's subject.

Let's gradientX and gradientY are independent and in -1..+1 range.So maximal gradient length are sqrt(2)
As maximum,w/o ease curve,at center we have sqrt(2)/2 * 4 * sqrt(2) that is 4;

As in original implementation 1,at center we have gradient multiplied with
(f(0.5))2
that are equal to
(3*0.25-2*0.125)2 that is equal to 0.52= 0.25.
Multiplied with 4 it gives 1. So,this perlin basis/noise 1 in 2d are really +/- 1 . In other dimenstions it are +/- 1 too because w/o ease we have 2dim and ease are equal to 0.5dim and it gives one.
Literature:
1: original implementation of perlin noise

Share this post


Link to post
Share on other sites
Dmytry    1151
AP was me.

Sorry for double post.HTML needed.
*****

There's no need to multiple result by constant or change algo to get value in -1..+1
Just change constants in "easing function",hehehehe.

ApochPiQ:
But dot products are not one for center because direction vectors from corners are not one unit big,and for 2d case,are sqrt(2)/2 big.
Here and later i'm discussing 2d case because it's subject.

Let's gradientX and gradientY are independent and in -1..+1 range.So maximal gradient length are sqrt(2)
As maximum,w/o ease curve,at center we have sqrt(2)/2 * 4 * sqrt(2) that is 4;

As in original implementation 1,at center we have gradient multiplied with
(f(0.5))2
that are equal to
(3*0.25-2*0.125)2 that is equal to 0.52= 0.25.
Multiplied with 4 it gives 1. So,this perlin basis/noise 1 in 2d are really +/- 1 . In other dimenstions it are +/- 1 too because w/o ease we have 2dim and ease are equal to 0.5dim and it gives one.
Literature:
1: original implementation of perlin noise

Share this post


Link to post
Share on other sites
Dmytry    1151
OP used 6t^5-15t^4+10t^3 as ease curve.
Let's find it for t=0.5 . If it are 0.5 too,result is one for same reason as in my previous post.
6/32-15/16+10/8= 0.5

So it are in -1 ... +1 range,with assumptions as in my previous post...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this