Search code examples
c#perlin-noiseprocedural-generation

Animate an UV sphere with (4D?) noise


I am using a C# port of libnoise with XNA (I know it's dead) to generate planets.

There is a function in libnoise that receives the coordinates of a vertex in a sphere surface (latitude and longitude) and returns a random value (from -1 to 1).

So with that value, I can change the height of each vertex on the surface of the sphere (the altitude), creating some elevation, simulating the surface of a planet (I'm not simply wrapping a texture around the sphere, I'm actually creating each vertex from scratch).

An example of what I have:

enter image description here

Now I want to animate the sphere, like this

But the thing is, libnoise only works with 3D noise. The "planet" function maps the latitude and longitude to XYZ coordinates of a cube.

And I believe that, to animate a sphere like I want to, I need an extra coordinate there, to be the "time" dimension. Am I right? Or is it possible to do this with what libnoise offers?

OBS: As I mentioned, I'm using an UV sphere, not an icosphere or a spherical cube.

EDIT: Here is the algorithm used by libnoise to map lat/long to XYZ:

public double GetValue(double latitude, double longitude) {           

    double x=0, y=0, z=0;

    double PI = 3.1415926535897932385;
    double DEG_TO_RAD = PI / 180.0;

    double r = System.Math.Cos(DEG_TO_RAD * lat);

    x = r * System.Math.Cos(DEG_TO_RAD * lon);
    y = System.Math.Sin(DEG_TO_RAD * lat);
    z = r * System.Math.Sin(DEG_TO_RAD * lon);

    return GetNoiseValueAt(x, y, z);

}

Solution

  • Ok I think I made it.

    I just added the time parameter to the mapped XYZ coordinates.

    Using the same latitude and longitude but incrementing time by 0.01d gave me a nice result.

    Here is my code:

    public double GetValue(double latitude, double longitude, double time) {           
    
        double x=0, y=0, z=0;
    
        double PI = 3.1415926535897932385;
        double DEG_TO_RAD = PI / 180.0;
    
        double r = System.Math.Cos(DEG_TO_RAD * lat);
    
        x = r * System.Math.Cos(DEG_TO_RAD * lon);
        y = System.Math.Sin(DEG_TO_RAD * lat);
        z = r * System.Math.Sin(DEG_TO_RAD * lon);
    
        return GetNoiseValueAt(x + time, y + time, z + time);
    
    }
    

    If someone has a better solution please share it!