Distribution of Unity perlin noise values


I’m working on a procedural terrain generator and I’m (of course) using the integrated UnityEngine.Mathf.PerlinNoise() method as a basis. For various reasons I wanted to know more about the value distribution and after some experiments (like generating a texture and analyzing its histogram in GIMP or writing a script that dumps 1000 values from random parts of the noise map into a text file) it occured to me that the noise distribution is kinda weird. It doesn’t follow the usual generic Perlin distribution of a plateau with sloped sides, it looks more like a Normal distribution with several peaks placed symmetrically around the center.

But that isn’t the worst thing (actually I’d say that makes it slightly better, if anything). I first noticed it in the GIMP histogram, but I thought it’s just an artifact of how I used a screenshot of the generated noise and put that into GIMP. But no, even when I used the script and put the data into excell (well, LibreOffice Calc, but I don’t think that really matters here), it’s still there - the noise seems to generate assymetrically, with bias towards lower values.

This is the code I used to generate the data (it’s in the Start() method of a script I added to the terrain generator object), output size is 1000:

 noise = new float[outputSize];
        for (int i = 0; i < outputSize; i++)
            float x = Random.Range(-1000f, 1000f);
            float y = Random.Range(-1000f, 1000f);
            noise *= Mathf.PerlinNoise(x, y);*


// Output noise into a file
foreach (float value in noise)
output += value.ToString();
output += ";

File.WriteAllText(“noiseData.txt”, output);
Debug.Log("Noise data written to " + Directory.GetCurrentDirectory());
And this is the distribution after I copy-pasted the data from 3 different attempts (the first two have a range of sampling location -10000 to 10000, the third one just -1000 to 1000) into a table, sorted from lowest to highest and made a point graph:
As you can see there’s very little difference between the three runs and all of them have more values below 0.5 than above. What’s more, there are no values above 1 (or even really close to it), which contradicts the common knowledge that the values can get both below 0 and above 1 in some rare cases.
So my question is: Does anyone know more about this? Is this some mistake in my code, my analysis, or is this a real thing about the Unity noise generation that nobody really cares / knows about? And more importantly, what is the actual range of the noise? Does anyone know?

Unity’s Perlin Noise implementation Math.PerlinNoise(float, float) repeats every 1.0 unit. If you feed in integers, you’ll always get the same value as output.

In other words, your [-1000f to 1000f] noise input range repeats the same numeric output 2000 times (per axis), while losing relative accuracy the closer you get to each extent of that input range.