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