Dark Bit Factory & Gravity
PROGRAMMING => General coding questions => Topic started by: Pixel_Outlaw on June 06, 2008
-
I've been reading about Perlin noise and think I would like to try some.
I've read that you first take a random number generator and get some numbers.
You then interpolate between the numbers creating waveforms.
I was then told that you "added" together the waveforms. How does one add together waveforms?
Also how do you produce a 2d texture? One wave for the x and one for the y with interpolation between the two?
-
I have not done much in this area, but that Hugo Elias have a fairly detailed explaination on his site along with some pseudo code that might be leading you in the right direction.
http://freespace.virgin.net/hugo.elias/models/m_perlin.htm (http://freespace.virgin.net/hugo.elias/models/m_perlin.htm)
-
Yes, that was the page I was originally looking at. What is meant by add the function together?
-
What is meant by add the function together?
It's really just adding ("+") the values.
Just take a look at the code at the end of the article...
-
Adding functions is just like adding numbers. Perlin is usually adding the results of the same function together but with the inputs scaled.
perlin(x,y) = 0.5 * t(x,y) + 0.3 * t(x/2,y/2) + 0.2 * t(x/4,y/4)
t(x,y) is your array of noise (eg. a 2d array or a 2d texture). You have to clamp the x,y coordinates. If you make everything floats and your random numbers are between 0 and 1 then perlin(x,y) returns backs a single number which you can use to perturb another value.
Jim
-
I think I understand now. Sometimes I just can't understand things without some help from friends.
-
The newest problem is correctly implimenting the cosine interpolation of two numbers.
On this site, code is provided but it does not give expected results.
http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
from the site:
function Cosine_Interpolate(a, b, x)
ft = x * 3.1415927
f = (1 - cos(ft)) * .5
return a*(1-f) + b*f
end of function
The number should be between number a and number b. However,when I run the interpolation function numbers that are supposed to be between 0 and 10 never exceed 1. They just stay around 0.
My conversion:
Function cos_interpolate:Float(n1:Float, n2:Float, percent:Float)
Local ft:Float = percent * Float(Pi)
Local f:Float = (1 - Cos(ft)) *.5
Return n1 * (1 - f) + n2 * f
End Function
A 10 step progression from 0 to 10 is certainly not correct:
8.26772666e-005
0.000330706593
0.000744080578
0.00132278656
0.00206680736
0.00297612092
0.00405069860
0.00529050967
0.00669551594
0.00826567598
-
Seems to me it could be one of two things. Check the x value you are inputting is between 0 and 1, not 0 and 100. If this is correct the next most likely thing is that your cos function is working in degrees instead of radians. If this is the case replace 'pi' in the equation with 180 and that should fix it.
-
a simple test-loop...
for (int i=0;i<10;i++)
float x= cos_interpolate(0,10, i/10.0f);
...results in this:
0: 0.000000
1: 0.244717
2: 0.954915
3: 2.061074
4: 3.454915
5: 5.000000
6: 6.545085
7: 7.938926
8: 9.045085
9: 9.755282
So you probably use wrong input?
-
Motorherp was correct. It appears that it was working in degrees.
Dodgy high school math...
-
The newest problem is correctly implimenting the cosine interpolation of two numbers.
On this site, code is provided but it does not give expected results.
http://freespace.virgin.net/hugo.elias/models/m_perlin.htm
from the site:
function Cosine_Interpolate(a, b, x)
ft = x * 3.1415927
f = (1 - cos(ft)) * .5
return a*(1-f) + b*f
end of function
The number should be between number a and number b. However,when I run the interpolation function numbers that are supposed to be between 0 and 10 never exceed 1. They just stay around 0.
My conversion:
Function cos_interpolate:Float(n1:Float, n2:Float, percent:Float)
Local ft:Float = percent * Float(Pi)
Local f:Float = (1 - Cos(ft)) *.5
Return n1 * (1 - f) + n2 * f
End Function
A 10 step progression from 0 to 10 is certainly not correct:
8.26772666e-005
0.000330706593
0.000744080578
0.00132278656
0.00206680736
0.00297612092
0.00405069860
0.00529050967
0.00669551594
0.00826567598
take note of the "return a*(1-f) + b*f"
95% of all perlin noise implementations(and if you based yours on the info from Hugo Elias, yours aswell) returns values in the 0..1 domain... wich is why you are getting weird results.. basically, what you want to do is this:
set up your basic noise function (returns a float between 0 and 1).
set up a smoothed noise function(weighted), that interpolates noise(x,y), noise(x+1,y), noise(x,y+1), noise(x+1,y+1), which in turn returns a float between 0 and 1.
create your final perlin noise function using the smoothed noise function using basically any interpolation you see fit(linear, cosine, cubic, catmull rom, etc) to interpolate the values inbetween your points in texture space.
hope this was of some help :) if not, i'll just post my code :D