- Home /

# Tiling problem with Perlin generated terrain chunks

I'm trying to create a procedural generator for terrain using Unity's Perlin Noise generator. I've managed to create a grid of 3x3 terrains with what seems to be a working repetition, except at the very top and right edges of each terrain they take a plunge to 0.

I've looked around for solutions to this (mostly trying to offset the noise applied by 1 pixel up and right), but nothing seems to work. Any ideas what I'm doing wrong? Thanks in advance!

```
void GenerateMesh (int xOrg, int yOrg)
{
float[,] Heights= MultiDim.FloatArray ((int)m_MapSize.x, (int)m_MapSize.y);
Heights=CalcNoise (xOrg,yOrg);
TerrainData NewTerrain= new TerrainData();
NewTerrain.heightmapResolution = (int)m_MapSize.x;
NewTerrain.size = new Vector3 (m_MapSize.x, m_MaxHeight, m_MapSize.y);
NewTerrain.baseMapResolution = (int)m_MapSize.x/2;
NewTerrain.SetDetailResolution (1024, 16);
NewTerrain.SetHeights(0,0,Heights);
GameObject TerrainSquare= Terrain.CreateTerrainGameObject(NewTerrain);
TerrainSquare.transform.position = new Vector3 ((xOrg*m_MapSize.x)-m_MapSize.x/2, 0,(yOrg*m_MapSize.y)-m_MapSize.y/2);
}
public float PerlinNoise(float x, float y)
{
float noise = Mathf.PerlinNoise (x/(m_MapSize.x)*m_ScaleRED,(y/(m_MapSize.y)*m_ScaleRED));
return noise;
}
float[,] CalcNoise(int xOrg, int yOrg)
{
float y = 0.0f;
float [,] finalheight =MultiDim.FloatArray ((int)m_MapSize.x, (int)m_MapSize.y);
while (y < m_NoiseTexture.height)
{
float x= 0.0f;
while (x < m_NoiseTexture.width)
{
float Xcoord = xOrg*m_MapSize.x+(x-1);
float Ycoord = yOrg*m_MapSize.y+(y-1);
float ColorSample = PerlinNoise(Xcoord,Ycoord);
m_PixelColor[(int)y*m_NoiseTexture.width+(int)x]= new Color(ColorSample,ColorSample,ColorSample);
finalheight[(int)y,(int)x]=0+(ColorSample);
x++;
}
y++;
}
m_NoiseTexture.SetPixels (m_PixelColor);
m_NoiseTexture.Apply ();
return finalheight;
}
```

**Answer** by alucardj
·
Jun 25, 2014 at 11:56 AM

The problem is heightmaps are to the **power of 2 + 1**. Imagine it like this :

Each black dot is a member of the heightmap array. Each color square is a member of the NoiseTexture array.

Factoring this in, your Heights Arrays would be *(int)m_MapSize.x + 1* (same for y). For the noise you would also need to loop through every member of the heightmap array. But with your texture you have to check if you havn't exceeded the texture array size. (Or also for the colours you may want to interpolate a sample that is in between the heightmap array values).

eg :

```
void GenerateMesh (int xOrg, int yOrg)
{
float[,] Heights= MultiDim.FloatArray ((int)m_MapSize.x + 1, (int)m_MapSize.y + 1);
Heights = CalcNoise (xOrg,yOrg);
TerrainData NewTerrain = new TerrainData();
NewTerrain.heightmapResolution = (int)m_MapSize.x;
NewTerrain.size = new Vector3 (m_MapSize.x, m_MaxHeight, m_MapSize.y);
NewTerrain.baseMapResolution = (int)m_MapSize.x/2;
NewTerrain.SetDetailResolution(1024, 16);
NewTerrain.SetHeights(0,0,Heights);
GameObject TerrainSquare = Terrain.CreateTerrainGameObject(NewTerrain);
TerrainSquare.transform.position = new Vector3 ((xOrg*m_MapSize.x)-m_MapSize.x/2, 0,(yOrg*m_MapSize.y)-m_MapSize.y/2);
}
public float PerlinNoise(float x, float y)
{
float noise = Mathf.PerlinNoise (x/(m_MapSize.x)*m_ScaleRED,(y/(m_MapSize.y)*m_ScaleRED));
return noise;
}
float[,] CalcNoise(int xOrg, int yOrg)
{
float [,] finalheight =MultiDim.FloatArray ((int)m_MapSize.x + 1, (int)m_MapSize.y + 1);
float y = 0.0f;
while (y < m_NoiseTexture.height + 1)
{
float x = 0.0f;
while (x < m_NoiseTexture.width + 1)
{
float Xcoord = xOrg*m_MapSize.x+(x-1);
float Ycoord = yOrg*m_MapSize.y+(y-1);
float ColorSample = PerlinNoise(Xcoord,Ycoord);
finalheight[(int)y,(int)x]=0+(ColorSample);
if ( y < m_NoiseTexture.height && x < m_NoiseTexture.width ) // check if within the texture array
m_PixelColor[(int)y*m_NoiseTexture.width+(int)x]= new Color(ColorSample,ColorSample,ColorSample);
x++;
}
y++;
}
m_NoiseTexture.SetPixels (m_PixelColor);
m_NoiseTexture.Apply ();
return finalheight;
}
```

Oh my, thank you! This fixes it (other than a few very slight seams, but they're almost innoticeable) quite elegantly. I do have to say it seems very strange to me for the heightmaps to use odd dimensions, any idea why this is the case?

On another note, I just noticed that around the seams the terrain is behaving oddly. I get a lot of shapes like the one in the screenshot. Did I do something wrong in the tiling of the noisemap, or is this something else?

TerrainData is a highly guarded secret by Unity! All my findings are based on trial and error rather than actual knowledge, but I shall try to answer.

I can only guess that the heightmaps are 2^n+1 for using the heightmap vertices as UV coordinates for the splatmap data. Like the picture in my answer, one quad would need 4 vertices for generating the triangles and assigning UVs.

The noticeable 'seams' are probably the calculations for the normal of each vertex in the terrain. At the edges, the terrain cannot get all of the adjacent vertices (because they don't exist from the perspective of each terrain object), therefore they are calculated as flat rather than in relation to where the adjacent vertices of the next terrain piece are.

Regarding your image, this looks like mirroring of the perlin noise. All I can assume is you are assigning your terrain chunks between a negative value and a positive value. Perlin Noise doesn't continue into the negative axis, rather the results are a mirror of the positive axis, eg :

```
// both of these will return the same value
Mathf.PerlinNoise ( 1, 1 );
Mathf.PerlinNoise ( -1, 1 );
// both of thee will return the same value
Mathf.PerlinNoise ( 2, 1 );
Mathf.PerlinNoise ( -2, 1 );
// etc etc
```

the only way to compensate for this would be to start your chunks at (0,0), and increment positively. Or add an offset in your PerlinNoise function with a magnitude greater than half of your world size so that all perlin noise values returned are in the values of positive perlin axis.

### Your answer

### Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.

### Follow this Question

### Related Questions

How can I correctly offset seeded perlin noise over multiple terrains? 1 Answer

Tile generation problem 1 Answer

Terrain and PerlinNoise Glitch 0 Answers

2D Efficient Realtime Terrain Generation 0 Answers

How exactly is Perlin Noise implemented? 4 Answers