Sign in to follow this  
SiS-Shadowman

beloved perlin noise ( and problems )

Recommended Posts

i hope you can help me. the best perlin noise tutorial on the need has dissappeared and i didn't finish my code -.- i'm stuck with my perlin noise:
float lib::CosineInterpolate(float a, float b, float x)
{
	float ft = x * 3.1415927f;
	float f = (1.0f - cos(ft)) * 0.5f;

	return  (a*(1-f) + b*f);
}
///////////////////////////////////////////////////////////////////////////////

float Noise2d(int x, int y)
{
	int n;
	n = x + y * 57;
	n = (n<<13) ^ n;
	return (float)( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff ) / 1073741824.0);
}
///////////////////////////////////////////////////////////////////////////////

float InterpolatedNoise(float x, float y) 
{
	int Xint = (int)x;
	int Yint = (int)y;
	float Xfrac = x - Xint;
	float Yfrac = y - Yint;

	float x0y0 = Noise2d(Xint, Yint);  //find the noise values of the four corners
	float x1y0 = Noise2d(Xint+1, Yint);
	float x0y1 = Noise2d(Xint, Yint+1);
	float x1y1 = Noise2d(Xint+1, Yint+1);

	//interpolate between those values according to the x and y fractions
	float v1  = lib::CosineInterpolate(x0y0, x1y0, Xfrac); //interpolate in x direction (y)
	float v2  = lib::CosineInterpolate(x0y1, x1y1, Xfrac); //interpolate in x direction (y+1)

	return lib::CosineInterpolate(v1, v2, Yfrac);  //interpolate in y direction
}
///////////////////////////////////////////////////////////////////////////////

float PerlinNoise(int x, int y, float persistence, float frequency, int octaves)
{
	float total = 0.0f;
	for(int i = 0; i < octaves-1; i++)
	{
		float freq = pow(frequency, i);
		float amp = pow(persistence, i);
		total = total + InterpolatedNoise(x * freq, y * freq) * amp;
	}
	return total;
}
///////////////////////////////////////////////////////////////////////////////

i used as parameters: persistance: 0.5 frequency: 2.0 octaves: 8 ( i clamped the pixels before i drawed them on the bitmap, just a normal [0, 1] clamp function... ) and the result is: [img]http://www.shadowman-works.de/forum/files/2/noise.png[/img] what is wrong with my algorithm? i saw pictures produced with perlin noise and their results looked alot better than mine, although they used the same arguments as i did.

Share this post


Link to post
Share on other sites
Quote:
InterpolatedNoise(x * freq, y * freq)

With x, y and freq being integers (freq being pow(2, i)), you're just calculating independent values for each pixels - there's no interpolation whatsoever - each pixel is totally random!

Try:
0 < frequency < 1
preferably:
frequency = 0.5;

EDIT: with that change, you'd also have to adjust this line:
total = total * amp + InterpolatedNoise(x * freq, y * freq) * amp;



Another thing is with the infamous random function Noise2d. Notice how it combines two arguments into one at the beginning (n = x + y * 57) - this is a 2D line equation, so do not be surprised if the output might be symmetric along any line perpendicular to that line. You might get away with this function, but I recommend getting a better one.

Share this post


Link to post
Share on other sites
thanks for the quick answer, i noticed by myself that a starting frequency of 0.5 is much more better, but look at that picture:

http://freespace.virgin.net/hugo.elias/models/cldmap1.gif

how did they do such a thing? how many octaves do i need?
i alter all arguments frequently but it always looks crappy, not dense enough ( or too random )

you are also proposing another Noise2D function, do you know any? i haven't found a thing :((

*edit*

wow, thanks for your advice ( in the edit ).
i'm now using your formula and the result looks fabulos :D
[frequency: 0.5; persistency: 0.9; octaves: 8]

http://www.shadowman-works.de/forum/files/2/noise2.png

Share this post


Link to post
Share on other sites
Quote:
Original post by SiS-Shadowman
you are also proposing another Noise2D function, do you know any? i haven't found a thing :((


It's got to be ANY good random function.
You can start here or just with good old rand()(*);

After that it's only a case of combining two random numbers inot one.

a = random(x);
b = random(y);
return (a ^ b) + (a * b)
or something equally simple (yet, effective) should do the trick.


(*) Forgot that rand() does not take any parameters.

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