Sign in to follow this  
Bad Maniac

Problem with noise generation function.

Recommended Posts

Bad Maniac    252
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.

Share this post


Link to post
Share on other sites
Funkymunky    1413
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?

Share this post


Link to post
Share on other sites
alvaro    21266
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);
}


Share this post


Link to post
Share on other sites
Bad Maniac    252
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.

Share this post


Link to post
Share on other sites
Squirm    481
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

Share this post


Link to post
Share on other sites
Bad Maniac    252
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.

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