2
\$\begingroup\$

I have been following a guide on Perlin noise, but I can't post the link here because of my current reputation level. I will post code if needed.

When I get noise from this distribution, I tend to get a very large fraction of values near the 0.5 range and very few on the fringes. You can see this from a sample which I turned into a quick graphic in the image below. I scaled my noise function by the width of the screen and had it increment an array at index = noise by 1 every time it generated a noise value. As you can see, the distribution is hardly Normal, as the fringes just drop out entirely.

Distribution

What is the best way to make this distribution wider towards the bottom, but not towards the top? I want most of the values to lie in a Gaussian distribution, but I can't just use a Gaussian distributed random number because I need values selected close to each other to be close to each other (Perlin noise).

How does this relate to games? I'm using the noise function to generate terrain and biome information. I have one noise array for elevation, one for temperature, and one for precipitation. I figured I could just overlay them and then determine the color of a square depending on a Whittaker plot, but with the current program, I end up only getting biomes in the midrange of the plot (Temperate forests), and I never get Tropical Rainforests or Taigas. Below are a few images of my generation:

(I need 10 reputation to post this many links and the zoomed out version shows the problem better)

And zoomed out:

Terrain 2

Here is my code for coloration. eNoise is scaled to 0-100, mNoise is scaled to 0-400, and tNoise is scaled from -15-40:

if(eNoise[i][j] < 55f) { color = Color.blue; }
            else {
                if(tNoise[i][j] < -15f) { //Tundra
                    color = Color.blue.brighter();
                } else if(tNoise[i][j] < 12f) {
                    if(mNoise[i][j] < 20f) {
                        color = Color.orange; //ST Desert
                    } else if(mNoise[i][j] < 50f) {
                        color = Color.yellow; //TG and Des
                    } else {
                        color = Color.green.darker(0.5f); //Taiga
                    }
                } else if(tNoise[i][j] < 20f) {
                    if(mNoise[i][j] < 30f) {
                        color = Color.orange; //ST Desert
                    } else if(mNoise[i][j] < 110f) {
                        color = Color.yellow; //TG and Des
                    } else if(mNoise[i][j] < 220f) {
                        color = Color.green.darker(0.3f); //TD Forest
                    } else {
                        color = Color.green.darker(0.2f); //Temp RF
                    }
                } else {
                    if(mNoise[i][j] < 50f) {
                        color = Color.orange; //ST Desert
                    } else if(mNoise[i][j] < 110f) {
                        color = Color.green.brighter(0.2f); //Savanna
                    } else if(mNoise[i][j] < 250f) {
                        color = Color.green; //TS Forest
                    } else {
                        color = Color.green.brighter(0.5f); //Tro RF
                    }}}
\$\endgroup\$
1
\$\begingroup\$

I have fixed this problem through the following method.

First, while generating noise values, I kept track of the minimum and maximum values.

Second, when storing the noise values into my array, I normalized the data: (value - min)/(max - min). This way, all my values are between 0 and 1, but are better distributed. The equation maps the minimum value to (min - min)/(max - min) or 0, and maps the largest value to (max - min)/(max - min) or 1, and it scales all the values in between.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.