Home > Mobile >  Mapping PerlinNoise to a Grid
Mapping PerlinNoise to a Grid

Time:02-24

I am trying to generate a grid across my map and add nodes depending on the perlin noise value. Depending on the value obtained from the perlin noise at a location, I will add a new Node which will be of a certain type e.g. Mountain, Water etc to represent terrian. Here I am trying to make it so that if the value is > 0.5, this mean it's only mountains and so a black coloured cubes should surround the mountain areas, However, my black cubes do not match the mountain areas from the perlin noise and I cannot seem to figure out why I am going wrong. Would appreciate any insight into how I could go about achieving this.

private void LocateWalkableCells()
{
    for(int z = 0; z < Height; z  )
    {
        for(int x = 0; x < Width; x  )
        {
            noise = GetNoiseValue(x, z);
            if(noise > 0.5) {
                grid[x,z] = new Node(new Vector3(x, 0, z), TerrainType.Mountain, 1);
            } 
            else {
                grid[x,z] = new Node(new Vector3(x, 0, z), TerrainType.Grass, 1);
            }
        }
    }
}

private float GetNoiseValue(int x, int z)
{
    int pos = (x * Width)   z;
    return Mathf.Round(terrainGenerator.noiseArray[pos] * 10) / 10;
}

// Draw gizmos to visualize colour
void OnDrawGizmos()
{
    Gizmos.DrawWireCube(transform.position, new Vector3(Width, 1, Height));
    if(grid != null)
    {
        foreach(Node n in grid)
        {
            if(n.TerrainType == TerrainType.Grass)
            {
                Gizmos.color = Color.green;
            } 
            else if(n.TerrainType == TerrainType.Mountain)
            {
                Gizmos.color = Color.black;
            } 

            Gizmos.DrawCube(n.Position, Vector3.one * (nodeDiameter - .1f));
        }
    }
}

noiseArray is used for the vertices of the terrain in the following code:

vertices = new Vector3[(Width   1) * (Depth   1)];
noiseArray = PerlinNoise();

int i = 0;
for(int z = 0; z <= Depth; z  )
{
    for(int x = 0; x <= Width; x  )
    {
        var currentHeight = noiseArray[i];

        if(currentHeight > HeightThreshold)
        {
            currentHeight *= HeightMultiplier;
        }

        vertices[i] = new Vector3(x, currentHeight, z);
        i  ;
    }
}

Output enter image description here

Result from suggested answer

Still seems to miss some mountain areas, colouring green instead of black. enter image description here

CodePudding user response:

It think the issue is in

var pos = (x * Width)   z;

since x is you index on the width of the grid you would probably rather want

var pos = z * Width   x;

in other words you want to

  • skip z rows
  • each row has Width elements
  • then from there take the xth element

assuming your terrain is laid out row-wise.

Or if it is laid out column-wise (which is rather unusual but possible)

var pos = x * Height   z;

or in other words

  • skip x columns
  • each column has Height elements
  • then from there take the zth element

See also Converting index of one dimensional array into two dimensional array i. e. row and column


Update

Now that you have showed the terrain generation code it needs to be

var pos = z * (Width   1)   x;

since the terrain array has actually Width 1 elements per row.

  • Related