Perlin Noise on a Sphere

I would need some help to apply a perlin noise correctly to a sphere.

Here is my code.

import peasy.*;
int resolution = 100;
float r = 500;
float lat,lon;
float xoff,yoff;
PVector[][] globularLandscape;
float rangeMin = -10;
float rangeMax = 40;

PeasyCam cam;

void setup() {
 size(400,400, P3D);
 cam = new PeasyCam(this, 1000);
 globularLandscape = new PVector[resolution+1][resolution+1];
 stroke(255);
 fill(50);
 for (int i = 0; i < resolution+1; i++) {
    lat = map(i, 0, resolution, 0, PI);
    xoff = 0;
   for (int j = 0; j < resolution+1; j++) {
     lon = map(j, 0, resolution, 0, TWO_PI);
     float x = r * sin(lat) * cos(lon) + map(noise(xoff, yoff),0 ,1, rangeMin, rangeMax);
     float y = r * sin(lat) * sin(lon) + map(noise(xoff, yoff),0 ,1, rangeMin, rangeMax);
     float z = r * cos(lat) + map(noise(xoff, yoff),0 ,1, rangeMin, rangeMax);
     globularLandscape[i][j] = new PVector(x, y, z);
     xoff += 0.07;
     //PVector v = PVector.random3D();
     //v.mult(7.7);
     //globularLandscape[i][j].add(v);
   }
   yoff += 0.07;
  }
}

void draw() {
  background(0);
  for (int i = 0; i < resolution; i++) {
    beginShape(TRIANGLE_STRIP);
   for (int j = 0; j < resolution+1; j++) {
     PVector v1 = globularLandscape[i][j];
     vertex(v1.x, v1.y, v1.z);
     PVector v2 = globularLandscape[i+1][j];
     vertex(v2.x, v2.y, v2.z);
   }
   endShape();
  }
}

My goal is to make a randomly generated spherical terrain (with mountains and valleys) using Perlin Noise ,and to color the triangles based on the radius of the sphere.
ex.

      if (v1.z < r) {
        fill(255);
      } else {
        fill(0);
      }

(Hope you understood what I want. If not i’ll try to explain it. If the triangle’s vertices are under the sealevel which is the radius of the sphere then color the triangle white. This will allow me to color the mountains ,hills, valleys, etc.)

And lastly when the for loop “goes around the sphere” ,at the and there`s a gap. How can I fix this.

P.S. Sorry for my bad language :frowning:
Capture1

1 Like

If I understood the gap is a result of significant difference in noise values?
In that case, I had a similar problem, but with 2d circular shape. My solution for circle was to use 3d perlin noise to smooth the difference.
In your case 4d noise might help, if there is such thing available to you.

Here are two approaches to this problem:

  1. The Noise Sphere example sketch: https://processing.org/examples/noisesphere.html
  2. Recent old forum threads: first draw an icoSphere made of triangle_fans using the Fibonacci sphere approach and hemesh library – and apply Perlin noise to the sphere points

Edit:

Also, @solub writes with a simpler method using hemesh HEC_Geodesic (and implemented in python mode):

add_library('hemesh')

def setup():
    translate(width>>1, height>>1)
    background('#DCDCDC')
    size(800, 600, P3D)
    smooth(8)
    
    render = WB_Render(this)
    creator = HEC_Geodesic().setType(WB_Geodesic.Type.OCTAHEDRON).setRadius(100).setB(12).setC(12)
    mesh = HE_Mesh(creator)
    factor = .004
    
    for v in mesh.getVertices():
        n = noise(v.xf() * factor + 1, v.yf() * factor + 2, v.zf() * factor + 3)
        pos = v.getPosition().mul(n).scaleSelf(2)
        v.set(pos)
        
    render.drawFaces(mesh)
3 Likes