Problem with noise generation function.

Started by
4 comments, last by Bad Maniac 18 years, 1 month ago
I'm working on a basic perlin noise implementation based on Hugo Elias tutorial, and It's working for the most part. but I'm having trouble with the final addition of the noise octaves. Instead of getting a Photoshop clouds sortof texture that has values evenly spread between 0.0 - 1.0 I'm getting only values in a range between maybe 0.4 and 0.8 for one octave, and the more octaves I add the higher it gets until a point where the entire map is 1.0. My noise functions are sound and tested and return reasonable values, as is my pseudo RNG, it returns numbers between 0.0 - 1.0. I think the problem is in my function to build the final noise by combining octaves, but No matter what I try I can't figure it out.
double noise(double x, double y, unsigned iterations, double persistence)
{
	unsigned n;
	double f, a, t;
	t = 0;
	for(n = 1; n < iterations + 1; ++n)
	{
		f = (2 * n) * 0.02; //scaling factor
		a = persistence / n;
		t += _noise(x * f, y * f) * a;
	}
	return t;//(t < 1.0) ? t : 1.0;
}
The function knows the total number of octaves you want, and the persistence as laid out by Hugo Elias. What I want it to do is add less of the noise per iteration, based on the persistence, so a persistence of 0.5 would mean octave one get's added 0,5, next 0.25 and so on. Problem is I want it to add up to one somehow, so I always get an even spread of numbers. Just basing it on persistence and number of octaves will not accomplish this. For example, 0.5 pers, 3 iterations: 1st iteration adds 0.5, 2nd 0.25 3rd 0.125 = 0.875. I want this to add up to 1.0 always. So, how would I accomplish this? As you may have guessed math isn't my strong point ;) Please help.
JRA GameDev Website//Bad Maniac
Advertisement
Work backwards? if you want 3 iterations, then it would go 0.5, 0.25, 0.125 normally, right? So assume 1.25 as final, then take halfsteps backwards to get to the first mark. 1.0 - 0.125 = 0.875, in half that's 0.4375. Add 0.125 to that, and it's 0.5625, your first mark. The middle one is another half step, half 0.4375 is 0.21875, + 0.125 is 0.34375. So all in all it's 0.5625, 0.34375, 0.125. (which is actually 1.03, round off)

That's just what I saw when I read the question, it's probably too obfuscated to actually be useful. Sorry! My real interest in your question was this: in your code, the noise function calls _noise. What does that little underscore do? Is that a function that's defined elsewhere?
In your code it looks like you are using persistance, persistance/2, persistance/3, etc.

You probably want to do something like this:

#include <iostream>#include <cmath>using namespace std;void noise(unsigned iterations, double persistance){  double multiplier=(1-persistance)/(1.0-pow(persistance,iterations));  for(unsigned i=0;i<iterations;++i){    cout << multiplier << endl;    multiplier*=persistance;  }}int main(){  noise(3,.5);}
Quote:Original post by FunkymunkyMy real interest in your question was this: in your code, the noise function calls _noise. What does that little underscore do? Is that a function that's defined elsewhere?
In my C code a leading _ means it's a private function, not available outside of the module.
JRA GameDev Website//Bad Maniac
I find it easiest to generate all the octaves between -1 and 1, then scale them, so that when they are added together it doesn't matter how many of them there are, the result still has the same average.

Then divide the result by the maximum size it could possibly have reached, then multiply by half the range you want it to reach, then add the average you want. In your case a range of 1.0 and an average of 0.5
That worked brilliantly Squirm. Thanks for pointing out what should have been pretty obvious. Changing the range to -1 - 1 made them average each other out. Works flawlessly now.
JRA GameDev Website//Bad Maniac

This topic is closed to new replies.

Advertisement