-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathperlin.nelua
77 lines (69 loc) · 1.88 KB
/
perlin.nelua
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
global PERLIN_SIZE <comptime> = 256
global Perlin = @record{}
local perlin: record{
rands: [PERLIN_SIZE]vec3,
permx: [PERLIN_SIZE]integer,
permy: [PERLIN_SIZE]integer,
permz: [PERLIN_SIZE]integer
}
function Perlin.generate()
for i=0,PERLIN_SIZE-1 do
perlin.rands[i] = vec3.unit(vec3{2*math.random()-1, 2*math.random()-1, 2*math.random()-1})
end
end
function Perlin.permute(perm: *[PERLIN_SIZE]integer)
for i=0,PERLIN_SIZE-1 do
perm[i] = i
end
for i=PERLIN_SIZE-1,1,-1 do
local target = math.random(0, i)
perm[i], perm[target] = perm[target], perm[i]
end
end
local function trilinear_interp(c: [2][2][2]vec3, u: number, v: number, w: number)
u, v, w = u*u*(3-2*u), v*v*(3-2*v), w*w*(3-2*w)
local accum: number = 0
for i=0,1 do
for j=0,1 do
for k=0,1 do
local weight = vec3{u-i, v-j, w-k}
accum = accum +
((i*u) + (1-i)*(1-u))*
((j*v) + (1-j)*(1-v))*
((k*w) + (1-k)*(1-w))*
vec3.dot(c[i][j][k], weight)
end
end
end
return accum
end
function Perlin.noise(p: vec3): number
local u, v, w = p.x - math.floor(p.x), p.y - math.floor(p.y), p.z - math.floor(p.z)
local pi, pj, pk = (@integer)(math.floor(p.x)), (@integer)(math.floor(p.y)), (@integer)(math.floor(p.z))
local c: [2][2][2]vec3
for i=0,1 do
for j=0,1 do
for k=0,1 do
c[i][j][k] = perlin.rands[
perlin.permx[(pi+i) & 255] ~
perlin.permy[(pj+j) & 255] ~
perlin.permx[(pk+k) & 255]]
end
end
end
return trilinear_interp(c, u, v, w)
end
function Perlin.turb(p: vec3, depth: integer)
local accum: number = 0
local weight: number = 1
for i=0,depth-1 do
accum = accum + weight * Perlin.noise(p)
weight = weight * 0.5
p = p + p
end
return math.abs(accum)
end
Perlin.generate()
Perlin.permute(perlin.permx)
Perlin.permute(perlin.permy)
Perlin.permute(perlin.permz)