What is wrong with my 2D Perlin Noise code?

Hi, everybody. I found some perlin noise code, written in C++, at http://freespace.virgin.net/hugo.elias/models/m_perlin.htm. I have been working to translating it to UnityScript, but with no avail. I would prefer not to use Mathf.PerlinNoise, because the function is undocumented and it only returns generic rolling hills - nothing too dynamic. Unfortunately, my code only spits back a flat terrain. Do you guys know what is wrong with it? Here is the code:

function Noise(xint : float, yint : float) {
    var seedthing : int = xint+yint;
    Random.seed = seedthing;
    return Random.value;
}

function SmoothNoise_1(xint : float,yint : float) {
  var corners : float = ( Noise(xint-1, yint-1)+Noise(xint+1, yint-1)+Noise(xint-1, yint+1)+Noise(xint+1, yint+1) ) / 16;
  var sides : float   = ( Noise(xint-1, yint)  +Noise(xint+1, yint)  +Noise(xint, yint-1)  +Noise(xint, yint+1) ) /  8;
  var thecenter : float  =  Noise(xint, yint) / 4;
  var blah : float =  corners + sides + thecenter;
  return blah;
}

function InterpolatedNoise_1(xint : float, yint : float) {

    var integer_X    = Mathf.Floor(xint);
    var fractional_X : float = xint - integer_X;

    var integer_Y    = Mathf.Floor (yint);
    var fractional_Y : float = yint - integer_Y;

    var v1 : float = SmoothNoise_1(integer_X,integer_Y);
    var v2 : float = SmoothNoise_1(integer_X + 1,integer_Y);
    var v3 : float = SmoothNoise_1(integer_X,integer_Y + 1);
    var v4 : float = SmoothNoise_1(integer_X + 1,integer_Y + 1);

    var i1 : float = InterpolateAction(v1 , v2 , fractional_X);
    var i2 : float = InterpolateAction(v3 , v4 , fractional_X);

    var finalfloat : float = InterpolateAction(i1 , i2 , fractional_Y);

    return finalfloat;
}

//I will replace this with more advanced code later
function InterpolateAction(a, b, x) {
    return  a*(1-x) + b*x;
    //Linear Interpolate

}

  function PerlinNoise_2D(xint : float,yint : float){

      var total : float = 0;
      var p = 0.5; //Persistance
      var n = 1 - 1; //Number of Octaves

      for(var i : int=0 ;i<n;i++) {

          var frequencys = 2^i;
          var amplitude = (1/2)^i;

          total = total + InterpolatedNoise_1(xint * frequencys, yint * frequencys) * amplitude;

      }

      return total;

  }

  var terrain : Terrain;

  function Start() {
    CalculatePerlinNoise();
  }

  function CalculatePerlinNoise() {

    var seedtime = Random.Range(0.0,1000.0);

    var heights : float[,] = new float[terrain.terrainData.heightmapWidth,terrain.terrainData.heightmapHeight];
        for (var i = 0; i < terrain.terrainData.heightmapWidth; i++)
        {
            for (var k = 0; k < terrain.terrainData.heightmapHeight; k++)
            {
                var iasfloat : float = i;
                var kasfloat : float = k;
                heights[i, k] = PerlinNoise_2D(iasfloat,kasfloat);
            }
        }
        terrain.terrainData.SetHeights(0, 0, heights);
        Debug.Log("Finished Perlin Noise Generation!");
  }

Very possibly this line:

var amplitude = (1/2)^i;

change it to 1/2.0 or 0.5

I was searching for something else regarding perlin noise going flat and came across this.

You probably don’t need to know anymore but incase anyone else comes and looks at this…

The following method always returns 0

  function PerlinNoise_2D(xint : float,yint : float){

  var total : float = 0;
  var p = 0.5; //Persistance
  var n = 1 - 1; //Number of Octaves

  for(var i : int=0 ;i<n;i++) {

      var frequencys = 2^i;
      var amplitude = (1/2)^i;

      total = total + InterpolatedNoise_1(xint * frequencys, yint * frequencys) * amplitude;

  }

  return total;

Because you have the line “n=1-1” which is 0, so the for loop never loops round so total remains 0, so all your noise is coming out as 0.

Also with regards to your seed in the noise method, just adding the x and y values isn’t great (it might be ok for what you are doing), but you’d rather do something a bit more unique.

Just adding x and y will result in many coordinates having the same seed.

i.e

[1,0] = [0,1] = [2,-1] = [-1,2] = etc

If you don’t allow negatives its not so bad but still, all coords which have the x and y swapped have the same seed.

A slightly better system might be to combine the two with shifting the bits. A common and simple system might be to use

seed = (x<<16) | y

Although I’ve just realised you use floats which means you can’t do this. But yeah, just wanted to point out your seed is used to create randomness, but you’ll have many duplicates with just simple addition.