terrain

Real-time terrain generation using marching cubes
git clone git://git.christianermann.dev/terrain
Log | Files | Refs | README | LICENSE

perlin.c (4537B)


      1 #include "perlin.h"
      2 
      3 #include <math.h>
      4 
      5 const static u16 p[512] = {
      6     151, 160, 137,  91,  90,  15, 131,  13, 201,  95,  96,  53, 194, 233,   7,
      7     225, 140,  36, 103,  30,  69, 142,   8,  99,  37, 240,  21,  10,  23, 190,
      8       6, 148, 247, 120, 234,  75,   0,  26, 197,  62,  94, 252, 219, 203, 117,
      9      35,  11,  32,  57, 177,  33,  88, 237, 149,  56,  87, 174,  20, 125, 136,
     10     171, 168,  68, 175,  74, 165,  71, 134, 139,  48,  27, 166,  77, 146, 158,
     11     231,  83, 111, 229, 122,  60, 211, 133, 230, 220, 105,  92,  41,  55,  46,
     12     245,  40, 244, 102, 143,  54,  65,  25,  63, 161,   1, 216,  80,  73, 209,
     13      76, 132, 187, 208,  89,  18, 169, 200, 196, 135, 130, 116, 188, 159,  86,
     14     164, 100, 109, 198, 173, 186,   3,  64,  52, 217, 226, 250, 124, 123,   5,
     15     202,  38, 147, 118, 126, 255,  82,  85, 212, 207, 206,  59, 227,  47,  16,
     16      58,  17, 182, 189,  28,  42, 223, 183, 170, 213, 119, 248, 152,   2,  44,
     17     154, 163,  70, 221, 153, 101, 155, 167,  43, 172,   9, 129,  22,  39, 253,
     18      19,  98, 108, 110,  79, 113, 224, 232, 178, 185, 112, 104, 218, 246,  97,
     19     228, 251,  34, 242, 193, 238, 210, 144,  12, 191, 179, 162, 241,  81,  51,
     20     145, 235, 249,  14, 239, 107,  49, 192, 214,  31, 181, 199, 106, 157, 184,
     21      84, 204, 176, 115, 121,  50,  45, 127,   4, 150, 254, 138, 236, 205,  93,
     22     222, 114,  67,  29,  24,  72, 243, 141, 128, 195,  78,  66, 215,  61, 156,
     23     180,
     24     151, 160, 137,  91,  90,  15, 131,  13, 201,  95,  96,  53, 194, 233,   7,
     25     225, 140,  36, 103,  30,  69, 142,   8,  99,  37, 240,  21,  10,  23, 190,
     26       6, 148, 247, 120, 234,  75,   0,  26, 197,  62,  94, 252, 219, 203, 117,
     27      35,  11,  32,  57, 177,  33,  88, 237, 149,  56,  87, 174,  20, 125, 136,
     28     171, 168,  68, 175,  74, 165,  71, 134, 139,  48,  27, 166,  77, 146, 158,
     29     231,  83, 111, 229, 122,  60, 211, 133, 230, 220, 105,  92,  41,  55,  46,
     30     245,  40, 244, 102, 143,  54,  65,  25,  63, 161,   1, 216,  80,  73, 209,
     31      76, 132, 187, 208,  89,  18, 169, 200, 196, 135, 130, 116, 188, 159,  86,
     32     164, 100, 109, 198, 173, 186,   3,  64,  52, 217, 226, 250, 124, 123,   5,
     33     202,  38, 147, 118, 126, 255,  82,  85, 212, 207, 206,  59, 227,  47,  16,
     34      58,  17, 182, 189,  28,  42, 223, 183, 170, 213, 119, 248, 152,   2,  44,
     35     154, 163,  70, 221, 153, 101, 155, 167,  43, 172,   9, 129,  22,  39, 253,
     36      19,  98, 108, 110,  79, 113, 224, 232, 178, 185, 112, 104, 218, 246,  97,
     37     228, 251,  34, 242, 193, 238, 210, 144,  12, 191, 179, 162, 241,  81,  51,
     38     145, 235, 249,  14, 239, 107,  49, 192, 214,  31, 181, 199, 106, 157, 184,
     39      84, 204, 176, 115, 121,  50,  45, 127,   4, 150, 254, 138, 236, 205,  93,
     40     222, 114,  67,  29,  24,  72, 243, 141, 128, 195,  78,  66, 215,  61, 156,
     41     180
     42 };
     43 
     44 static f32 fade(f32 t)
     45 {
     46     return t * t * t * (t * (t * 6 - 15) + 10);
     47 }
     48 
     49 static f32 lerp(f32 t, f32 a, f32 b)
     50 {
     51     return a + t * (b - a);
     52 }
     53 
     54 const static f32 g[16][3] = {
     55     {  1,  1,  0 },
     56     { -1,  1,  0 },
     57     {  1, -1,  0 },
     58     { -1, -1,  0 },
     59     {  1,  0,  1 },
     60     { -1,  0,  1 },
     61     {  1,  0, -1 },
     62     { -1,  0, -1 },
     63     {  0,  1,  1 },
     64     {  0, -1,  1 },
     65     {  0,  1, -1 },
     66     {  0, -1, -1 },
     67     {  1,  1,  0 },
     68     {  0, -1,  1 },
     69     { -1,  1,  0 },
     70     {  0, -1, -1 }
     71 };
     72 
     73 static f32 grad(u16 hash, f32 x, f32 y, f32 z)
     74 {
     75     u16 h = hash & 15;
     76     return g[h][0] * x + g[h][1] * y + g[h][2] * z;
     77 }
     78 
     79 f32 perlin(f32 x, f32 y, f32 z)
     80 {
     81     i32 X = (i32)floorf(x) & 255;
     82     i32 Y = (i32)floorf(y) & 255;
     83     i32 Z = (i32)floorf(z) & 255;
     84 
     85     x -= floorf(x);
     86     y -= floorf(y);
     87     z -= floorf(z);
     88     
     89     f32 u = fade(x);
     90     f32 v = fade(y);
     91     f32 w = fade(z);
     92     
     93     i32 a = p[p[p[X    ] + Y    ] + Z];
     94     i32 b = p[p[p[X + 1] + Y    ] + Z];
     95     i32 c = p[p[p[X    ] + Y + 1] + Z];
     96     i32 d = p[p[p[X + 1] + Y + 1] + Z];
     97     i32 e = p[p[p[X    ] + Y    ] + Z + 1];
     98     i32 f = p[p[p[X + 1] + Y    ] + Z + 1];
     99     i32 g = p[p[p[X    ] + Y + 1] + Z + 1];
    100     i32 h = p[p[p[X + 1] + Y + 1] + Z + 1];
    101 
    102     return lerp(w, lerp(v, lerp(u, grad(a, x    , y    , z    ),
    103                                    grad(b, x - 1, y    , z    )),
    104                            lerp(u, grad(c, x    , y - 1, z    ),
    105                                    grad(d, x - 1, y - 1, z    ))),
    106                    lerp(v, lerp(u, grad(e, x    , y    , z - 1),
    107                                    grad(f, x - 1, y    , z - 1)),
    108                            lerp(u, grad(g, x    , y - 1, z - 1),
    109                                    grad(h, x - 1, y - 1, z - 1))));
    110 }