I'm attempting to create a sphere with terrain (aka planet). I managed to procedurally create an icosahedron, and I am able to subdivide it (yay), but now I'm stuck on terrain.

My current idea was to create a Perlin like "3D Noise Field" and sample density where each of the spheres vertices fall (as a height-map value). this way i should be able to tweak the noise (add octaves, etc) to roughen the "NoiseField" and thus the spheres surface.

pseudo example and result:

public void Terrain(float Scale)
    if (Scale < 0.01) return;

    List<Vector3> terrain = new List<Vector3>();
    for ( int i = 0; i < surface.vertices.Count; i++)
        Vector3 vert = sphere.verts[i];
        Vector3 direction = vert.normalized;
        Vector3 newpoint = vert * Sample3DNoise(direction, Scale);

    //this line replaces the original shape!        
    surface.vertices = terrain;

    Debug.Log("terrain Update");

public float Sample3DNoise(Vector3 point, float scale)
    //Vector3 direction = point.normalized;

    float u = point.normalized.x * scale;
    float v = point.normalized.y * scale;
    float w = point.normalized.z * scale;

    //poor attempt at 3d noise field
    //PerlinNoise(float, float );
    float x = Mathf.PerlinNoise(u , 0f);
    float y = Mathf.PerlinNoise(0f, v);
    float z = Mathf.PerlinNoise(u , v);

    //the average of the coords, returns "density at this point"
    return (x + y + z) / 3;

enter image description here


so while it appears i was able to achieve this, it's is clearly not the "terrain on surface of sphere" look I was aiming for. Any suggestions on how can I change the "noise field" so my surface is more planet like? or how else can i achieve this?

  • \$\begingroup\$ I would recomend you to check this youtube playlist, It covers exactly what you are looking for. youtube.com/playlist?list=PLFt_AvWsXl0cONs3T0By4puYy6GM22ko8 \$\endgroup\$ – BlackBox Aug 31 '19 at 17:48
  • \$\begingroup\$ I did check him out, I wouldn't have gotten this far without him XD. But there is a fundamental difference, he is using 6 faces to make a cube/sphere, adding noise to a flat surface is pretty easy! My icosahedron doesn't flatten out well so I'm trying to manipulate the surface with a noise field. It works, just not well. :/ Thanks though. \$\endgroup\$ – kei Aug 31 '19 at 22:35
  • 1
    \$\begingroup\$ Keep in mind that if the Earth were the size of an apple, the tallest mountain would be no thicker than the apple's skin. You're not going to see that from space as anything more than the equivalent of a normal map. \$\endgroup\$ – user1118321 Sep 6 '19 at 3:29

the answer was simple enough

Vector3 vector = original[i] + ((normal * noise) * amplitude);

basically i want to take the "original vert" and add "some noise in the correct direction" and scale by amplitude.

i ended up changing quite a bit of the project, but if anyone's curious it pretty much breaks down too...

    public void UpdateNoise(/* int layer,*/ float amplitude, float period)//, float frequency)
    List<Vector3> original  = Octaves[Octaves.Count - 2];//input verts
    List<Vector3> octave    = new List<Vector3>();

    for ( int i = 0; i < original.Count; i++)
        Vector3 normal = original[i].normalized;
        float u = (normal.x * period);
        float v = (normal.y * period);
        float noise = Mathf.PerlinNoise(u, v);
        Vector3 vector = original[i] + ((normal * noise) * amplitude);

    this.vertices = octave;//output verts
    //Octaves[Octaves.Count - 1] = octave;

enter image description here


It seems to me that if you want more of a planetary terrain effect, you would add the modifier to the original vert instead of multiplying them and change your scale value to a number that is a small percentage of the sphere's radius. Good luck.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.