# Getting the top layer of 3D perlin Noise

I am generating 16x16x64 chunks. Afterwards I apply 3D noise to them. I want the first layer to be all grass blocks and after those I want layers of dirt.

The current problem is that I am getting some dirt blocks in my top layer. So how do I get the entire top layer of the noise?

TArray<int32> heightMap = CalculateNoise();

for (int32 x = 0; x < 16; ++x)
{
for (int32 y = 0; y<16; ++y)
{
for (int32 z = 0; z< 64; ++z)
{
int32 voxelIndex = x + (y * 16) + (z * (16*16));

int heightmapValue = heightMap[voxelIndex];

if (z == 30 + heightmapValue)
ChunkIDs[voxelIndex] = 1;
else if (z == 29 + heightmapValue)
ChunkIDs[voxelIndex] = 2;
else
ChunkIDs[voxelIndex] = 0;

}
}
}

• A heightmap should be 2 dimensional. Why do you add the z coordinate to the voxelIndex? – Bálint Oct 20 '17 at 11:21

If you want to select the top layer of the heightmap can't you simply do the following:

TArray<int32> heightMap = CalculateNoise();

for (int32 x = 0; x < 16; ++x)
{
for (int32 y = 0; y<16; ++y)
{
for (int32 z = 0; z< 64; ++z)
{
int32 voxelIndex = x + (y * 16) + (z * (16*16));

int heightmapValue = heightMap[voxelIndex];

//If the block we're looking at is at the same level as the height map it must be on the surface
if (z == heightmapValue)
ChunkIDs[voxelIndex] = 1;
else if (z < heightmapValue) //If it's less than that then it's underground
ChunkIDs[voxelIndex] = 2;
else //If it's not below or equal to then it must be air.
ChunkIDs[voxelIndex] = 0;

}
}
}


I hope this helps, Thomas.