Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Minecraft like game map generator

Discussion in 'Scripting' started by logang, Jan 27, 2014.

  1. logang

    logang

    Joined:
    Feb 1, 2013
    Posts:
    63
    So I have been working on a game like minecraft and I have got the block breaking and block placing down and then I started working on the map generation, I works fine its just it is dumb looking the way it works is that it generates down line by line and will randomly go up or down and just does not feel natural. I would like to learn Perlin Noise and a more efficient of going about this, I also was going to do the map save by righting every block and block position to the note pad and then when you load it up it reads the file and places the blocks and the positions. please tell me if there is a better way of doing this. I want to learn it and under stand how to go about this.( I first posted this and untiy answers and they told me to come here) thanks :)
     
  2. Moredice

    Moredice

    Joined:
    Sep 2, 2013
    Posts:
    5
    YouTube is full of tutorials on this matter, for example this one I found within 5 seconds after searching "Unity voxel tutorial":

    http://www.youtube.com/watch?v=_1u2RA158FM


    Don't underestimate the learning power of YT videos.
     
    Scorpio112 likes this.
  3. jackmott

    jackmott

    Joined:
    Jan 5, 2014
    Posts:
    167
    Here is a C# conversion of Perlin Noise along with 2d fractal brownian motion which I added. You will want to extend that to 3d and play with it.

    fractal brownian motion uses multiple passes of perlin noise averaged together which produces more natural looking terrain.

    Code (csharp):
    1. using UnityEngine;
    2. // noise1234
    3. //
    4. // Original Author: Stefan Gustavson, 2003-2005
    5. // Contact: stegu@itn.liu.se
    6. //
    7. // This code was GPL licensed until February 2011.
    8. // As the original author of this code, I hereby
    9. // release it into the public domain.
    10. // Please feel free to use it for whatever you want.
    11. // Credit is appreciated where appropriate, and I also
    12. // appreciate being told where this code finds any use,
    13. // but you may do as you like.
    14.  
    15. /** \file
    16.         \brief Implements the noise1 to noise4 functions for Perlin noise.
    17.         \author Stefan Gustavson (stegu@itn.liu.se)
    18. */
    19.  
    20. /*
    21.  * This implementation is "Improved Noise" as presented by
    22.  * Ken Perlin at Siggraph 2002. The 3D function is a direct port
    23.  * of his Java reference code available on www.noisemachine.com
    24.  * (although I cleaned it up, made it faster and made the code
    25.  * more readable), but the 1D, 2D and 4D cases were implemented
    26.  * from scratch by me.
    27.  *
    28.  * This is a backport to C of my improved noise class in C++.
    29.  * It is highly reusable without source code modifications.
    30.  *
    31.  */
    32.  
    33.  
    34. /*
    35.  * Ported to C# and fractal brownian noise added by Jack Mott
    36.  *
    37.  *
    38.  */
    39.  
    40. //#include  "noise1234.h"
    41.  
    42. // This is the new and improved, C(2) continuous interpolant
    43. // Original C defines converted to C# functions below
    44. //#define FADE(t) ( t * t * t * ( t * ( t * 6 - 15 ) + 10 ) )
    45. //#define FASTFLOOR(x) ( ((x)>0) ? ((int)x) : ((int)x-1 ) )
    46. //#define LERP(t, a, b) ((a) + (t)*((b)-(a)))
    47.  
    48. public class Noise
    49. {
    50.  
    51.     float FADE(float t)
    52.     {
    53.         return (t * t * t * (t * (t * 6 - 15) + 10));
    54.     }
    55.  
    56.     int FASTFLOOR(float x)
    57.     {
    58.         if (x >= 0)
    59.             return (int)x;
    60.         return (int)(x - 1);
    61.  
    62.     }
    63.  
    64.     float LERP(float t, float a, float b)
    65.     {
    66.         return ((a) + (t) * ((b) - (a)));
    67.     }
    68.  
    69.  
    70.     //---------------------------------------------------------------------
    71.     // Static data
    72.  
    73.     /*
    74.      * Permutation table. This is just a random jumble of all numbers 0-255,
    75.      * repeated twice to avoid wrapping the index at 255 for each lookup.
    76.      * This needs to be exactly the same for all instances on all platforms,
    77.      * so it's easiest to just keep it as static explicit data.
    78.      * This also removes the need for any initialisation of this class.
    79.      *
    80.      * Note that making this an int[] instead of a char[] might make the
    81.      * code run faster on platforms with a high penalty for unaligned single
    82.      * byte addressing. Intel x86 is generally single-byte-friendly, but
    83.      * some other CPUs are faster with 4-aligned reads.
    84.      * However, a char[] is smaller, which avoids cache trashing, and that
    85.      * is probably the most important aspect on most architectures.
    86.      * This array is accessed a *lot* by the noise functions.
    87.      * A vector-valued noise over 3D accesses it 96 times, and a
    88.      * float-valued 4D noise 64 times. We want this to fit in the cache!
    89.      */
    90.  
    91.  
    92.  
    93.     short[] perm = {151,160,137,91,90,15,
    94.     131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
    95.     190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
    96.     88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
    97.     77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
    98.     102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
    99.     135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
    100.     5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
    101.     223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
    102.     129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
    103.     251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
    104.     49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
    105.     138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180,
    106.     151,160,137,91,90,15,
    107.     131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
    108.     190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
    109.     88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
    110.     77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
    111.     102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
    112.     135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
    113.     5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
    114.     223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
    115.     129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
    116.     251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
    117.     49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
    118.     138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
    119.     };
    120.  
    121.     //---------------------------------------------------------------------
    122.  
    123.     /*
    124.      * Helper functions to compute gradients-dot-residualvectors (1D to 4D)
    125.      * Note that these generate gradients of more than unit length. To make
    126.      * a close match with the value range of classic Perlin noise, the final
    127.      * noise values need to be rescaled. To match the RenderMan noise in a
    128.      * statistical sense, the approximate scaling values (empirically
    129.      * determined from test renderings) are:
    130.      * 1D noise needs rescaling with 0.188
    131.      * 2D noise needs rescaling with 0.507
    132.      * 3D noise needs rescaling with 0.936
    133.      * 4D noise needs rescaling with 0.87
    134.      * Note that these noise functions are the most practical and useful
    135.      * signed version of Perlin noise. To return values according to the
    136.      * RenderMan specification from the SL noise() and pnoise() functions,
    137.      * the noise values need to be scaled and offset to [0,1], like this:
    138.      * float SLnoise = (noise3(x,y,z) + 1.0) * 0.5;
    139.      */
    140.  
    141.     float grad1(int hash, float x)
    142.     {
    143.         int h = hash  15;
    144.         float grad = 1.0f + (h  7);  // Gradient value 1.0, 2.0, ..., 8.0
    145.         if ((h  8) == 1)
    146.             grad = -grad;         // and a random sign for the gradient
    147.         return (grad * x);           // Multiply the gradient with the distance
    148.     }
    149.  
    150.     float grad2(int hash, float x, float y)
    151.     {
    152.         int h = hash  7;      // Convert low 3 bits of hash code
    153.         float u = h < 4 ? x : y;  // into 8 simple gradient directions,
    154.         float v = h < 4 ? y : x;  // and compute the dot product with (x,y).
    155.  
    156.         if ((h  1) == 1)
    157.             u = -u;
    158.         float n = 2.0f * v;
    159.         if ((h  2) == 1)
    160.             n = -2.0f * v;
    161.  
    162.         return u + n;
    163.     }
    164.  
    165.     float grad3(int hash, float x, float y, float z)
    166.     {
    167.         int h = hash  15;     // Convert low 4 bits of hash code into 12 simple
    168.         float u = h < 8 ? x : y; // gradient directions, and compute dot product.
    169.         float v = h < 4 ? y : h == 12 || h == 14 ? x : z; // Fix repeats at h = 12 to 15
    170.         if ((h  1) == 1)
    171.             u = -u;
    172.  
    173.         if ((h  2) == 1)
    174.             v = -v;
    175.  
    176.         return u + v;
    177.     }
    178.  
    179.     float grad4(int hash, float x, float y, float z, float t)
    180.     {
    181.         int h = hash  31;      // Convert low 5 bits of hash code into 32 simple
    182.         float u = h < 24 ? x : y; // gradient directions, and compute dot product.
    183.         float v = h < 16 ? y : z;
    184.         float w = h < 8 ? z : t;
    185.  
    186.         if ((h  1) == 1)
    187.             u = -u;
    188.  
    189.         if ((h  2) == 1)
    190.             v = -v;
    191.  
    192.         if ((h  4) == 1)
    193.             w = -w;
    194.  
    195.         return u + v + w;
    196.     }
    197.  
    198.     //---------------------------------------------------------------------
    199.     /** 1D float Perlin noise, SL "noise()"
    200.      */
    201.     public float noise1(float x)
    202.     {
    203.         int ix0, ix1;
    204.         float fx0, fx1;
    205.         float s, n0, n1;
    206.  
    207.         ix0 = FASTFLOOR(x); // Integer part of x
    208.         fx0 = x - ix0;       // Fractional part of x
    209.         fx1 = fx0 - 1.0f;
    210.         ix1 = (ix0 + 1)  0xff;
    211.         ix0 = ix0  0xff;    // Wrap to 0..255
    212.  
    213.         s = FADE(fx0);
    214.  
    215.         n0 = grad1(perm[ix0], fx0);
    216.         n1 = grad1(perm[ix1], fx1);
    217.         return 0.188f * (LERP(s, n0, n1));
    218.     }
    219.  
    220.     //---------------------------------------------------------------------
    221.     /** 1D float Perlin periodic noise, SL "pnoise()"
    222.      */
    223.     public float pnoise1(float x, int px)
    224.     {
    225.         int ix0, ix1;
    226.         float fx0, fx1;
    227.         float s, n0, n1;
    228.  
    229.         ix0 = FASTFLOOR(x); // Integer part of x
    230.         fx0 = x - ix0;       // Fractional part of x
    231.         fx1 = fx0 - 1.0f;
    232.         ix1 = ((ix0 + 1) % px)  0xff; // Wrap to 0..px-1 *and* wrap to 0..255
    233.         ix0 = (ix0 % px)  0xff;      // (because px might be greater than 256)
    234.  
    235.         s = FADE(fx0);
    236.  
    237.         n0 = grad1(perm[ix0], fx0);
    238.         n1 = grad1(perm[ix1], fx1);
    239.         return 0.188f * (LERP(s, n0, n1));
    240.     }
    241.  
    242.  
    243.     //---------------------------------------------------------------------
    244.     /** 2D float Perlin noise.
    245.      */
    246.     public float noise2(float x, float y)
    247.     {
    248.         int ix0, iy0, ix1, iy1;
    249.         float fx0, fy0, fx1, fy1;
    250.         float s, t, nx0, nx1, n0, n1;
    251.  
    252.  
    253.         ix0 = (x > 0) ? (int)x : (int)(x - 1);
    254.         iy0 = (y > 0) ? (int)y : (int)(y - 1);
    255.         fx0 = x - ix0;        // Fractional part of x
    256.         fy0 = y - iy0;        // Fractional part of y
    257.         fx1 = fx0 - 1.0f;
    258.         fy1 = fy0 - 1.0f;
    259.         ix1 = (ix0 + 1)  0xff;  // Wrap to 0..255
    260.         iy1 = (iy0 + 1)  0xff;
    261.         ix0 = ix0  0xff;
    262.         iy0 = iy0  0xff;
    263.  
    264.         t = FADE(fy0);
    265.         s = FADE(fx0);
    266.  
    267.         nx0 = grad2(perm[ix0 + perm[iy0]], fx0, fy0);
    268.         nx1 = grad2(perm[ix0 + perm[iy1]], fx0, fy1);
    269.         n0 = LERP(t, nx0, nx1);
    270.  
    271.         nx0 = grad2(perm[ix1 + perm[iy0]], fx1, fy0);
    272.         nx1 = grad2(perm[ix1 + perm[iy1]], fx1, fy1);
    273.         n1 = LERP(t, nx0, nx1);
    274.  
    275.         return 0.507f * (LERP(s, n0, n1));
    276.     }
    277.  
    278.     //---------------------------------------------------------------------
    279.     /** 2D float Perlin periodic noise.
    280.      */
    281.     public float pnoise2(float x, float y, int px, int py)
    282.     {
    283.         int ix0, iy0, ix1, iy1;
    284.         float fx0, fy0, fx1, fy1;
    285.         float s, t, nx0, nx1, n0, n1;
    286.  
    287.         ix0 = (x > 0) ? (int)x : (int)(x - 1);
    288.         iy0 = (y > 0) ? (int)y : (int)(y - 1);
    289.         fx0 = x - ix0;        // Fractional part of x
    290.         fy0 = y - iy0;        // Fractional part of y
    291.         fx1 = fx0 - 1.0f;
    292.         fy1 = fy0 - 1.0f;
    293.         ix1 = ((ix0 + 1) % px)  0xff;  // Wrap to 0..px-1 and wrap to 0..255
    294.         iy1 = ((iy0 + 1) % py)  0xff;  // Wrap to 0..py-1 and wrap to 0..255
    295.         ix0 = (ix0 % px)  0xff;
    296.         iy0 = (iy0 % py)  0xff;
    297.  
    298.         t = (fy0 * fy0 * fy0 * (fy0 * (fy0 * 6 - 15) + 10));
    299.         s = (fx0 * fx0 * fx0 * (fx0 * (fx0 * 6 - 15) + 10));
    300.  
    301.         nx0 = grad2(perm[ix0 + perm[iy0]], fx0, fy0);
    302.         nx1 = grad2(perm[ix0 + perm[iy1]], fx0, fy1);
    303.         n0 = LERP(t, nx0, nx1);
    304.  
    305.         nx0 = grad2(perm[ix1 + perm[iy0]], fx1, fy0);
    306.         nx1 = grad2(perm[ix1 + perm[iy1]], fx1, fy1);
    307.         n1 = LERP(t, nx0, nx1);
    308.  
    309.         return ((0.446f * (LERP(s, n0, n1))) + .5f);
    310.     }
    311.  
    312.  
    313.     //---------------------------------------------------------------------
    314.     /** 3D float Perlin noise.
    315.      */
    316.     public float noise3(float x, float y, float z)
    317.     {
    318.         int ix0, iy0, ix1, iy1, iz0, iz1;
    319.         float fx0, fy0, fz0, fx1, fy1, fz1;
    320.         float s, t, r;
    321.         float nxy0, nxy1, nx0, nx1, n0, n1;
    322.  
    323.         ix0 = FASTFLOOR(x); // Integer part of x
    324.         iy0 = FASTFLOOR(y); // Integer part of y
    325.         iz0 = FASTFLOOR(z); // Integer part of z
    326.         fx0 = x - ix0;        // Fractional part of x
    327.         fy0 = y - iy0;        // Fractional part of y
    328.         fz0 = z - iz0;        // Fractional part of z
    329.         fx1 = fx0 - 1.0f;
    330.         fy1 = fy0 - 1.0f;
    331.         fz1 = fz0 - 1.0f;
    332.         ix1 = (ix0 + 1)  0xff; // Wrap to 0..255
    333.         iy1 = (iy0 + 1)  0xff;
    334.         iz1 = (iz0 + 1)  0xff;
    335.         ix0 = ix0  0xff;
    336.         iy0 = iy0  0xff;
    337.         iz0 = iz0  0xff;
    338.  
    339.         r = FADE(fz0);
    340.         t = FADE(fy0);
    341.         s = FADE(fx0);
    342.  
    343.         nxy0 = grad3(perm[ix0 + perm[iy0 + perm[iz0]]], fx0, fy0, fz0);
    344.         nxy1 = grad3(perm[ix0 + perm[iy0 + perm[iz1]]], fx0, fy0, fz1);
    345.         nx0 = LERP(r, nxy0, nxy1);
    346.  
    347.         nxy0 = grad3(perm[ix0 + perm[iy1 + perm[iz0]]], fx0, fy1, fz0);
    348.         nxy1 = grad3(perm[ix0 + perm[iy1 + perm[iz1]]], fx0, fy1, fz1);
    349.         nx1 = LERP(r, nxy0, nxy1);
    350.  
    351.         n0 = LERP(t, nx0, nx1);
    352.  
    353.         nxy0 = grad3(perm[ix1 + perm[iy0 + perm[iz0]]], fx1, fy0, fz0);
    354.         nxy1 = grad3(perm[ix1 + perm[iy0 + perm[iz1]]], fx1, fy0, fz1);
    355.         nx0 = LERP(r, nxy0, nxy1);
    356.  
    357.         nxy0 = grad3(perm[ix1 + perm[iy1 + perm[iz0]]], fx1, fy1, fz0);
    358.         nxy1 = grad3(perm[ix1 + perm[iy1 + perm[iz1]]], fx1, fy1, fz1);
    359.         nx1 = LERP(r, nxy0, nxy1);
    360.  
    361.         n1 = LERP(t, nx0, nx1);
    362.  
    363.         return 0.936f * (LERP(s, n0, n1));
    364.     }
    365.  
    366.     //---------------------------------------------------------------------
    367.     /** 3D float Perlin periodic noise.
    368.      */
    369.     public float pnoise3(float x, float y, float z, int px, int py, int pz)
    370.     {
    371.         int ix0, iy0, ix1, iy1, iz0, iz1;
    372.         float fx0, fy0, fz0, fx1, fy1, fz1;
    373.         float s, t, r;
    374.         float nxy0, nxy1, nx0, nx1, n0, n1;
    375.  
    376.         ix0 = FASTFLOOR(x); // Integer part of x
    377.         iy0 = FASTFLOOR(y); // Integer part of y
    378.         iz0 = FASTFLOOR(z); // Integer part of z
    379.         fx0 = x - ix0;        // Fractional part of x
    380.         fy0 = y - iy0;        // Fractional part of y
    381.         fz0 = z - iz0;        // Fractional part of z
    382.         fx1 = fx0 - 1.0f;
    383.         fy1 = fy0 - 1.0f;
    384.         fz1 = fz0 - 1.0f;
    385.         ix1 = ((ix0 + 1) % px)  0xff; // Wrap to 0..px-1 and wrap to 0..255
    386.         iy1 = ((iy0 + 1) % py)  0xff; // Wrap to 0..py-1 and wrap to 0..255
    387.         iz1 = ((iz0 + 1) % pz)  0xff; // Wrap to 0..pz-1 and wrap to 0..255
    388.         ix0 = (ix0 % px)  0xff;
    389.         iy0 = (iy0 % py)  0xff;
    390.         iz0 = (iz0 % pz)  0xff;
    391.  
    392.         r = FADE(fz0);
    393.         t = FADE(fy0);
    394.         s = FADE(fx0);
    395.  
    396.         nxy0 = grad3(perm[ix0 + perm[iy0 + perm[iz0]]], fx0, fy0, fz0);
    397.         nxy1 = grad3(perm[ix0 + perm[iy0 + perm[iz1]]], fx0, fy0, fz1);
    398.         nx0 = LERP(r, nxy0, nxy1);
    399.  
    400.         nxy0 = grad3(perm[ix0 + perm[iy1 + perm[iz0]]], fx0, fy1, fz0);
    401.         nxy1 = grad3(perm[ix0 + perm[iy1 + perm[iz1]]], fx0, fy1, fz1);
    402.         nx1 = LERP(r, nxy0, nxy1);
    403.  
    404.         n0 = LERP(t, nx0, nx1);
    405.  
    406.         nxy0 = grad3(perm[ix1 + perm[iy0 + perm[iz0]]], fx1, fy0, fz0);
    407.         nxy1 = grad3(perm[ix1 + perm[iy0 + perm[iz1]]], fx1, fy0, fz1);
    408.         nx0 = LERP(r, nxy0, nxy1);
    409.  
    410.         nxy0 = grad3(perm[ix1 + perm[iy1 + perm[iz0]]], fx1, fy1, fz0);
    411.         nxy1 = grad3(perm[ix1 + perm[iy1 + perm[iz1]]], fx1, fy1, fz1);
    412.         nx1 = LERP(r, nxy0, nxy1);
    413.  
    414.         n1 = LERP(t, nx0, nx1);
    415.  
    416.         return 0.936f * (LERP(s, n0, n1));
    417.     }
    418.  
    419.  
    420.     //---------------------------------------------------------------------
    421.     /** 4D float Perlin noise.
    422.      */
    423.  
    424.     public float noise4(float x, float y, float z, float w)
    425.     {
    426.         int ix0, iy0, iz0, iw0, ix1, iy1, iz1, iw1;
    427.         float fx0, fy0, fz0, fw0, fx1, fy1, fz1, fw1;
    428.         float s, t, r, q;
    429.         float nxyz0, nxyz1, nxy0, nxy1, nx0, nx1, n0, n1;
    430.  
    431.         ix0 = FASTFLOOR(x); // Integer part of x
    432.         iy0 = FASTFLOOR(y); // Integer part of y
    433.         iz0 = FASTFLOOR(z); // Integer part of y
    434.         iw0 = FASTFLOOR(w); // Integer part of w
    435.         fx0 = x - ix0;        // Fractional part of x
    436.         fy0 = y - iy0;        // Fractional part of y
    437.         fz0 = z - iz0;        // Fractional part of z
    438.         fw0 = w - iw0;        // Fractional part of w
    439.         fx1 = fx0 - 1.0f;
    440.         fy1 = fy0 - 1.0f;
    441.         fz1 = fz0 - 1.0f;
    442.         fw1 = fw0 - 1.0f;
    443.         ix1 = (ix0 + 1)  0xff;  // Wrap to 0..255
    444.         iy1 = (iy0 + 1)  0xff;
    445.         iz1 = (iz0 + 1)  0xff;
    446.         iw1 = (iw0 + 1)  0xff;
    447.         ix0 = ix0  0xff;
    448.         iy0 = iy0  0xff;
    449.         iz0 = iz0  0xff;
    450.         iw0 = iw0  0xff;
    451.  
    452.         q = FADE(fw0);
    453.         r = FADE(fz0);
    454.         t = FADE(fy0);
    455.         s = FADE(fx0);
    456.  
    457.         nxyz0 = grad4(perm[ix0 + perm[iy0 + perm[iz0 + perm[iw0]]]], fx0, fy0, fz0, fw0);
    458.         nxyz1 = grad4(perm[ix0 + perm[iy0 + perm[iz0 + perm[iw1]]]], fx0, fy0, fz0, fw1);
    459.         nxy0 = LERP(q, nxyz0, nxyz1);
    460.  
    461.         nxyz0 = grad4(perm[ix0 + perm[iy0 + perm[iz1 + perm[iw0]]]], fx0, fy0, fz1, fw0);
    462.         nxyz1 = grad4(perm[ix0 + perm[iy0 + perm[iz1 + perm[iw1]]]], fx0, fy0, fz1, fw1);
    463.         nxy1 = LERP(q, nxyz0, nxyz1);
    464.  
    465.         nx0 = LERP(r, nxy0, nxy1);
    466.  
    467.         nxyz0 = grad4(perm[ix0 + perm[iy1 + perm[iz0 + perm[iw0]]]], fx0, fy1, fz0, fw0);
    468.         nxyz1 = grad4(perm[ix0 + perm[iy1 + perm[iz0 + perm[iw1]]]], fx0, fy1, fz0, fw1);
    469.         nxy0 = LERP(q, nxyz0, nxyz1);
    470.  
    471.         nxyz0 = grad4(perm[ix0 + perm[iy1 + perm[iz1 + perm[iw0]]]], fx0, fy1, fz1, fw0);
    472.         nxyz1 = grad4(perm[ix0 + perm[iy1 + perm[iz1 + perm[iw1]]]], fx0, fy1, fz1, fw1);
    473.         nxy1 = LERP(q, nxyz0, nxyz1);
    474.  
    475.         nx1 = LERP(r, nxy0, nxy1);
    476.  
    477.         n0 = LERP(t, nx0, nx1);
    478.  
    479.         nxyz0 = grad4(perm[ix1 + perm[iy0 + perm[iz0 + perm[iw0]]]], fx1, fy0, fz0, fw0);
    480.         nxyz1 = grad4(perm[ix1 + perm[iy0 + perm[iz0 + perm[iw1]]]], fx1, fy0, fz0, fw1);
    481.         nxy0 = LERP(q, nxyz0, nxyz1);
    482.  
    483.         nxyz0 = grad4(perm[ix1 + perm[iy0 + perm[iz1 + perm[iw0]]]], fx1, fy0, fz1, fw0);
    484.         nxyz1 = grad4(perm[ix1 + perm[iy0 + perm[iz1 + perm[iw1]]]], fx1, fy0, fz1, fw1);
    485.         nxy1 = LERP(q, nxyz0, nxyz1);
    486.  
    487.         nx0 = LERP(r, nxy0, nxy1);
    488.  
    489.         nxyz0 = grad4(perm[ix1 + perm[iy1 + perm[iz0 + perm[iw0]]]], fx1, fy1, fz0, fw0);
    490.         nxyz1 = grad4(perm[ix1 + perm[iy1 + perm[iz0 + perm[iw1]]]], fx1, fy1, fz0, fw1);
    491.         nxy0 = LERP(q, nxyz0, nxyz1);
    492.  
    493.         nxyz0 = grad4(perm[ix1 + perm[iy1 + perm[iz1 + perm[iw0]]]], fx1, fy1, fz1, fw0);
    494.         nxyz1 = grad4(perm[ix1 + perm[iy1 + perm[iz1 + perm[iw1]]]], fx1, fy1, fz1, fw1);
    495.         nxy1 = LERP(q, nxyz0, nxyz1);
    496.  
    497.         nx1 = LERP(r, nxy0, nxy1);
    498.  
    499.         n1 = LERP(t, nx0, nx1);
    500.  
    501.         return 0.87f * (LERP(s, n0, n1));
    502.     }
    503.  
    504.     //---------------------------------------------------------------------
    505.     /** 4D float Perlin periodic noise.
    506.      */
    507.  
    508.     public float pnoise4(float x, float y, float z, float w,
    509.               int px, int py, int pz, int pw)
    510.     {
    511.         int ix0, iy0, iz0, iw0, ix1, iy1, iz1, iw1;
    512.         float fx0, fy0, fz0, fw0, fx1, fy1, fz1, fw1;
    513.         float s, t, r, q;
    514.         float nxyz0, nxyz1, nxy0, nxy1, nx0, nx1, n0, n1;
    515.  
    516.         ix0 = FASTFLOOR(x); // Integer part of x
    517.         iy0 = FASTFLOOR(y); // Integer part of y
    518.         iz0 = FASTFLOOR(z); // Integer part of y
    519.         iw0 = FASTFLOOR(w); // Integer part of w
    520.         fx0 = x - ix0;        // Fractional part of x
    521.         fy0 = y - iy0;        // Fractional part of y
    522.         fz0 = z - iz0;        // Fractional part of z
    523.         fw0 = w - iw0;        // Fractional part of w
    524.         fx1 = fx0 - 1.0f;
    525.         fy1 = fy0 - 1.0f;
    526.         fz1 = fz0 - 1.0f;
    527.         fw1 = fw0 - 1.0f;
    528.         ix1 = ((ix0 + 1) % px)  0xff;  // Wrap to 0..px-1 and wrap to 0..255
    529.         iy1 = ((iy0 + 1) % py)  0xff;  // Wrap to 0..py-1 and wrap to 0..255
    530.         iz1 = ((iz0 + 1) % pz)  0xff;  // Wrap to 0..pz-1 and wrap to 0..255
    531.         iw1 = ((iw0 + 1) % pw)  0xff;  // Wrap to 0..pw-1 and wrap to 0..255
    532.         ix0 = (ix0 % px)  0xff;
    533.         iy0 = (iy0 % py)  0xff;
    534.         iz0 = (iz0 % pz)  0xff;
    535.         iw0 = (iw0 % pw)  0xff;
    536.  
    537.         q = FADE(fw0);
    538.         r = FADE(fz0);
    539.         t = FADE(fy0);
    540.         s = FADE(fx0);
    541.  
    542.         nxyz0 = grad4(perm[ix0 + perm[iy0 + perm[iz0 + perm[iw0]]]], fx0, fy0, fz0, fw0);
    543.         nxyz1 = grad4(perm[ix0 + perm[iy0 + perm[iz0 + perm[iw1]]]], fx0, fy0, fz0, fw1);
    544.         nxy0 = LERP(q, nxyz0, nxyz1);
    545.  
    546.         nxyz0 = grad4(perm[ix0 + perm[iy0 + perm[iz1 + perm[iw0]]]], fx0, fy0, fz1, fw0);
    547.         nxyz1 = grad4(perm[ix0 + perm[iy0 + perm[iz1 + perm[iw1]]]], fx0, fy0, fz1, fw1);
    548.         nxy1 = LERP(q, nxyz0, nxyz1);
    549.  
    550.         nx0 = LERP(r, nxy0, nxy1);
    551.  
    552.         nxyz0 = grad4(perm[ix0 + perm[iy1 + perm[iz0 + perm[iw0]]]], fx0, fy1, fz0, fw0);
    553.         nxyz1 = grad4(perm[ix0 + perm[iy1 + perm[iz0 + perm[iw1]]]], fx0, fy1, fz0, fw1);
    554.         nxy0 = LERP(q, nxyz0, nxyz1);
    555.  
    556.         nxyz0 = grad4(perm[ix0 + perm[iy1 + perm[iz1 + perm[iw0]]]], fx0, fy1, fz1, fw0);
    557.         nxyz1 = grad4(perm[ix0 + perm[iy1 + perm[iz1 + perm[iw1]]]], fx0, fy1, fz1, fw1);
    558.         nxy1 = LERP(q, nxyz0, nxyz1);
    559.  
    560.         nx1 = LERP(r, nxy0, nxy1);
    561.  
    562.         n0 = LERP(t, nx0, nx1);
    563.  
    564.         nxyz0 = grad4(perm[ix1 + perm[iy0 + perm[iz0 + perm[iw0]]]], fx1, fy0, fz0, fw0);
    565.         nxyz1 = grad4(perm[ix1 + perm[iy0 + perm[iz0 + perm[iw1]]]], fx1, fy0, fz0, fw1);
    566.         nxy0 = LERP(q, nxyz0, nxyz1);
    567.  
    568.         nxyz0 = grad4(perm[ix1 + perm[iy0 + perm[iz1 + perm[iw0]]]], fx1, fy0, fz1, fw0);
    569.         nxyz1 = grad4(perm[ix1 + perm[iy0 + perm[iz1 + perm[iw1]]]], fx1, fy0, fz1, fw1);
    570.         nxy1 = LERP(q, nxyz0, nxyz1);
    571.  
    572.         nx0 = LERP(r, nxy0, nxy1);
    573.  
    574.         nxyz0 = grad4(perm[ix1 + perm[iy1 + perm[iz0 + perm[iw0]]]], fx1, fy1, fz0, fw0);
    575.         nxyz1 = grad4(perm[ix1 + perm[iy1 + perm[iz0 + perm[iw1]]]], fx1, fy1, fz0, fw1);
    576.         nxy0 = LERP(q, nxyz0, nxyz1);
    577.  
    578.         nxyz0 = grad4(perm[ix1 + perm[iy1 + perm[iz1 + perm[iw0]]]], fx1, fy1, fz1, fw0);
    579.         nxyz1 = grad4(perm[ix1 + perm[iy1 + perm[iz1 + perm[iw1]]]], fx1, fy1, fz1, fw1);
    580.         nxy1 = LERP(q, nxyz0, nxyz1);
    581.  
    582.         nx1 = LERP(r, nxy0, nxy1);
    583.  
    584.         n1 = LERP(t, nx0, nx1);
    585.  
    586.         return 0.87f * (LERP(s, n0, n1));
    587.     }
    588.  
    589.     public float pfbm2(float x, float y, int px, int py, int octaves, float alpha, float omega)
    590.     {
    591.         float sum = 0f;
    592.         float a = 1;
    593.         float b = 1;
    594.         for (int i = 1; i <= octaves; i++)
    595.         {
    596.             sum += (1f / a) * pnoise2(x * b, y * b, px, py);
    597.             a *= alpha;
    598.             b *= omega;
    599.  
    600.         }
    601.         return Mathf.Clamp(sum * (1f - (1f / alpha)) * 1.4f, 0, 1);
    602.     }
    603.  
    604.     public float fbm2(float x, float y, int px, int py, int octaves, float alpha, float omega)
    605.     {
    606.         float sum = 0f;
    607.         float a = 1;
    608.         float b = 1;
    609.         for (int i = 1; i <= octaves; i++)
    610.         {
    611.             sum += (1f / a) * noise2(x * b, y * b);
    612.             a *= alpha;
    613.             b *= omega;
    614.  
    615.         }
    616.         return Mathf.Clamp(sum * (1f - (1f / alpha)) * 1.4f, 0, 1);
    617.     }
    618. }
    619.  
     
    Greviouss likes this.
  4. beezir

    beezir

    Joined:
    Apr 3, 2009
    Posts:
    133
    If you want a simple example, I posted a long time ago on the long-running Minecraft thread with code that generates similar terrain. If I recall correctly, it uses Simplex noise generation for the terrain, then carves out caves using a second 3d noise algorithm. It's a stable algorithm so you can walk infinitely in any direction and continue to generate consistent noise for a given random seed. If you save the current seed and just the blocks that have changed, you should be able to keep your save files pretty small even though the world is huge. You can grab the unity package here:

    Unity Package

    And a webplayer to see it in action - you can remove blocks by clicking, if you have a slow computer and fall fast enough you'll probably end up with missing chunks and fall right through. I haven't touched the code in a couple years, but feel free to use it as you see fit. It's licensed under the "Throw me a bone" license. You can use it however you want, but if you make a crapload of money off of it, throw me a bone. ;)

    Web Player

    If it starts you in a bad spot or the chunks don't load correctly, just refresh and try again. It generally creates quite a few caves, so you should be able to find at least one by walking. They're different levels of complexity, so some may go for quite awhile and some may just be a tiny hole. There's definitely lots of room for improvement or adaptation to other games.
     
  5. jackmott

    jackmott

    Joined:
    Jan 5, 2014
    Posts:
    167
    Super cool beezir!
     
  6. logang

    logang

    Joined:
    Feb 1, 2013
    Posts:
    63
    I really like it, but I do not want to just use some ones code I would like to under stand it and be able to write it my self. but thanks for sharing I really like how you can it never stops..
     
  7. beezir

    beezir

    Joined:
    Apr 3, 2009
    Posts:
    133
    No problem, posted it so you at least had an example to work with. The package has full source code in it to read through and help you out with some ideas on how to put something together yourself.
     
  8. Foam

    Foam

    Joined:
    Jun 13, 2012
    Posts:
    322