Search Unity

Sol Escape - procedural planet - code samples and screens

Discussion in 'Works In Progress - Archive' started by jackmott, Feb 3, 2014.

  1. jackmott

    jackmott

    Joined:
    Jan 5, 2014
    Posts:
    167
    Thought I would show the development progression of the procedural planets we will be using in Sol Escape for fun:

    First step, was to generate perlin/simplex noise, often the base of any game procedural development. I used Stefan Gustavson's C++ implementation here http://staffwww.itn.liu.se/~stegu/aqsis/aqsis-newnoise/noise1234.cpp as a base and ported it to C# for use in Sol Escape

    Now the tricky part about procedural planets is getting the texture to wrap nicely around the sphere, 2d perlin noise won't do that, so instead we need to use 3d perlin noise AND we have to map it to a texture such that it will look good when uv mapped onto the sphere model. For each x,y of the texture we need to figure out the spherical coordinates on a unit sphere andthen convert the spherical coordinates into cartesian 3d coordinates:
    Code (csharp):
    1.  
    2.                 float theta = twopi * (x/(float)planetTex.width);
    3.                 float phi = pi * (y/(float)planetTex.height);
    4.  
    5.                 float x3d = Mathf.Cos(theta) * Mathf.Sin(phi);
    6.                 float y3d = Mathf.Sin(theta) * Mathf.Sin(phi);
    7.                 float z3d = -Mathf.Cos(phi);
    8.  
    If we pass those x,y,z coordinates into our basic perlin noise function we get a random noise texture that will wrap around a sphere, notice how it gets stretchted out at the top of the texture:




    Next up, apply your texture to a sphere and make sure it looks good:



    No seams! But this isn't a very interesting planet, it looks more like a fuzzy polluted cloud. Fun thing about perlin noise is that by doing multiple passes at different frequencies and averaging them together, you can create finer details that start to resemble real world terrain. This is called Fractal Brownian Motion, and a sample code snippet:

    Code (csharp):
    1. public float fbm3(float x, float y, float z, int octaves, float lacunarity, float gain)
    2.     {
    3.         float sum = 0f;
    4.         float frequency = 1;
    5.         float amplitude = 1;
    6.         for (int i = 1; i <= octaves; i++)
    7.         {
    8.             sum += (1f / frequency) * noise3(x * amplitude, y * amplitude,z*amplitude);
    9.             frequency *= lacunarity;
    10.             amplitude *= gain;
    11.  
    12.         }
    13.         return Mathf.Clamp(.8f*(sum - .205f),0,1);
    14.     }
    15.  
    You can tweak the parameters to create all kinds of interesting effects. Here is our sphere with fractal noise wrapped on it:



    Still doesn't look like much, our noise is just black and white. But if we build a lookup table to convert each grayscale value into a color we immediately get something that starts to look like a planet:



    Add in some lighting and maybe a detail texture makes for a nice effect:



    Build a few different color gradient tables and you can create a whole universe of different planets. Just swapping in a different color gradient turns our earth like planet into a hell planet:



    Or maybe a normal map and replace the water with a tweaked Unity Basic Water shader:



    Sol Escape will be using these techniques to provide unique game play in a rouge-like strategy game.
     
  2. jackmott

    jackmott

    Joined:
    Jan 5, 2014
    Posts:
    167
    A sample of some random planets that get generated by varying the fractal noise parameters and color gradients:

     
  3. GregMeach

    GregMeach

    Joined:
    Dec 5, 2012
    Posts:
    249
    Some very interesting planets there....
     
  4. erick_weil

    erick_weil

    Joined:
    Feb 3, 2014
    Posts:
    5