# How can I apply Perlin noise to generating an asteroid from cubic voxels?

I know I can use Perlin noise to generate randomised terrains, but for my current project i want to generate random asteroids of non-uniform length, width depth etc.

My first thought was to apply Perlin noise to a sphere, but i do not know how i would apply this with cubes space in a grid nor did i know whether it would make the asteroids appear random enough, my current assumption was they would all be relatively spherical still.

Is Perlin noise still the best method to be using for terrain not on a single plane?

• Take a look at this question and answer. It is explained in 2D but the same concepts can be taken into 3D and will work the same way: gamedev.stackexchange.com/questions/120471/… Jun 9, 2016 at 11:26
• @Jon but i don't understand how to take the concepts to 3D. Jun 9, 2016 at 11:40
• You just add the third dimension. You will also need a way to generate a spherical gradient, which perlin noise does not do. Jun 9, 2016 at 11:41
• @Jon I am still failing to see how i can do that, the spherical gradient i get & is a helper in the right direction, but the main point of my question is i do not understand how to apply this in 3d space. Jun 9, 2016 at 11:47
• Added code for 3D blend. This should do what you want, however, you will still have to figure out how to generate a 3d Spherical gradient pattern to blend with your perlin noise data. Jun 9, 2016 at 11:54

Here is how you can blend data of noise and gradient together, in 3D. This should provide you with asteroid style shapes.

First, our container to store the Data:

public class MapData {

public float[,,] Data;
public float Min { get; set; }
public float Max { get; set; }

public MapData(int width, int height, int depth)
{
Data = new float[width, height, depth];
Min = float.MaxValue;
Max = float.MinValue;
}
}


We init this data container as follows:

blendData = new MapData (Width, Height, Depth);


Now, if you already have your generated noise, and gradient maps, you can blend them as follows:

// first pass - blend gradient values
for (var x = 0; x < Width; x++) {
for (var y = 0; y < Height; y++) {
for (var z = 0; z < Depth; z++) {

float gradValue1 = (float)NoiseMap.Get (nx, ny, nz);

// Multiply

// keep track of the max and min values found
if (blendValue > blendData.Max) blendData.Max = blendValue;
if (blendValue < blendData.Min) blendData.Min = blendValue;

blendData.Data[x,y,z] = blendValue;
}
}


Doing so will give you some pretty crazy values, so we are going to want to normalize these in order to provide an easier way to work with this data in the future:

// secondary pass to normalize the blended values
for (var x = 0; x < Width; x++) {
for (var y = 0; y < Height; y++) {
for (var z = 0; z < Depth; z++) {
blendData.Data[x,y,z] = (blendData.Data[x,y,z] - blendData.Min) / (blendData.Max - blendData.Min);
}
}
}


Render this data, and you should see a asteroid style shape emerge.

• No i am still not getting it I am afraid. I am using the Mathf.PerlinNoise function available in Unity and am unsure how i can get a 3D NoiseMap entity from that data. Jun 9, 2016 at 12:13
• You need to generate that NoiseMap with your PerlinNoise. So you would have another step before all this, where you would fill an Array[x,y,z] with your perlin noise data. This would be your Noise Map. Jun 9, 2016 at 12:14
• So i generate 3 perlin noise maps (one for each axis) and somehow blend them together? Jun 9, 2016 at 12:18
• No. You generate 1 perlin noise map, fetching the noise data in 3 dimensions. Unfortunately I just realized that Unity only provides a lame 2D perlin noise generator. You are going to have to get an external lib to do this in 3D Jun 9, 2016 at 12:19
• Ok, that is the step i was finding hard to get over. I will attempt this. Jun 9, 2016 at 12:22