noise experiments

Experimenting with terrain generation..
noise tower
simplex noise (for those unfamiliar: it’s sort of newer perlin noise algorithm but not so popular) borrowed from
http://codeflow.org/entries/2010/dec/09/minecraft-like-rendering-experiments-in-opengl-4/#volume-data
translated to pascal in case someone needs it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
//http://codeflow.org/entries/2010/dec/09/minecraft-like-rendering-experiments-in-opengl-4/#volume-data
unit core_simplex_noise;
 
{$mode objfpc}{$H+}
 
interface
 
uses
  Classes, SysUtils, math;
 
  function simplex_noise(octaves:integer;x,y,z:single):single;
  function noise3d(xin,yin,zin:single):single;
 
implementation
 
const
  grad:array[0..11,0..2] of single = (
      (1.0,1.0,0.0),(-1.0,1.0,0.0),(1.0,-1.0,0.0),(-1.0,-1.0,0.0),
      (1.0,0.0,1.0),(-1.0,0.0,1.0),(1.0,0.0,-1.0),(-1.0,0.0,-1.0),
      (0.0,1.0,1.0),(0.0,-1.0,1.0),(0.0,1.0,-1.0),(0.0,-1.0,-1.0)
  );
 
  perm:array [0..511] of integer = (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);
 
function dot(x,y,z:single; g:psingle):single;
begin
    result:= x*g[0] + y*g[1] + z*g[2];
end;
 
function noise3d(xin,yin,zin:single):single;
var
    F3, G3, t, X0, Y0, Z0, xx0, yy0, zz0, s, x1, y1, z1, x2, y2, z2, x3, y3, z3, t0, t1, t2, t3, n0, n1, n2, n3:single;
    i, j, k, ii, jj, kk, i1, j1, k1, i2, j2, k2, gi0, gi1, gi2, gi3:integer;
begin
    F3 := 1.0 / 3.0;
    s := (xin+yin+zin)*F3;
    i := round(xin+s);
    j := round(yin+s);
    k := round(zin+s);
    G3 := 1.0/6.0;
    t := (i+j+k)*G3;
    X0 := i-t;
    Y0 := j-t;
    Z0 := k-t;
    xx0 := xin-X0;
    yy0 := yin-Y0;
    zz0 := zin-Z0;
 
    if(xx0 >= yy0) then begin
        if(yy0 >= zz0) then begin
            i1:=1; j1:=0; k1:=0; i2:=1; j2:=1; k2:=0;
        end
        else if(xx0 >= zz0) then begin
             i1:=1; j1:=0; k1:=0; i2:=1; j2:=0; k2:=1;
        end
        else begin
            i1:=0; j1:=0; k1:=1; i2:=1; j2:=0; k2:=1;
        end
    end
    else begin
        if(yy0 < zz0) then begin
            i1:=0; j1:=0; k1:=1; i2:=0; j2:=1; k2:=1;
        end
        else if(xx0 < zz0) then begin
            i1:=0; j1:=1; k1:=0; i2:=0; j2:=1; k2:=1;
        end
        else begin
            i1:=0; j1:=1; k1:=0; i2:=1; j2:=1; k2:=0;
        end
    end;
 
    x1 := xx0 - i1 + G3;
//    end;
    y1 := yy0 - j1 + G3;
    z1 := zz0 - k1 + G3;
    x2 := xx0 - i2 + 2.0*G3;
    y2 := yy0 - j2 + 2.0*G3;
    z2 := zz0 - k2 + 2.0*G3;
    x3 := xx0 - 1.0 + 3.0*G3;
    y3 := yy0 - 1.0 + 3.0*G3;
    z3 := zz0 - 1.0 + 3.0*G3;
 
    ii := i and 255;
    jj := j and 255;
    kk := k and 255;
 
    gi0 := perm[ii+perm[jj+perm[kk]]] mod 12;
    gi1 := perm[ii+i1+perm[jj+j1+perm[kk+k1]]] mod 12;
    gi2 := perm[ii+i2+perm[jj+j2+perm[kk+k2]]] mod 12;
    gi3 := perm[ii+1+perm[jj+1+perm[kk+1]]] mod 12;
 
    t0 := 0.6 - xx0*xx0 - yy0*yy0 - zz0*zz0;
    if(t0<0) then begin
         n0 := 0.0;
    end
    else begin
        t0 := t0*t0;
        n0 := t0 * t0 * dot(xx0, yy0, zz0, grad[gi0]);
    end;
 
    t1 := 0.6 - x1*x1 - y1*y1 - z1*z1;
    if(t1<0) then begin
         n1 := 0.0;
    end
    else begin
        t1 := t1*t1;
        n1 := t1 * t1 * dot(x1, y1, z1, grad[gi1]);
    end;
    t2 := 0.6 - x2*x2 - y2*y2 - z2*z2;
    if(t2<0) then begin
         n2 := 0.0;
    end
    else begin
        t2 := t2*t2;
        n2 := t2 * t2 * dot(x2, y2, z2, grad[gi2]);
    end;
    t3 := 0.6 - x3*x3 - y3*y3 - z3*z3;
    if(t3<0) then begin
         n3 := 0.0;
    end
    else begin
        t3 := t3*t3;
        n3 := t3 * t3 * dot(x3, y3, z3, grad[gi3]);
    end ;
    result:= 16.0*(n0 + n1 + n2 + n3)+1.0;
end;
 
function simplex_noise(octaves:integer;x,y,z:single):single;
var
    value:single = 0.0;
    i:integer;
begin
    for i:=0 to octaves-1 do begin
        value := value + noise3d(
        x*power(2, i),
        y*power(2, i),
         z*power(2, i)
        );
    end;
    result:= value;
end;
 
end.