forked from Simnation/Main
110 lines
2.8 KiB
Lua
110 lines
2.8 KiB
Lua
local Perlin = {}
|
|
|
|
-- Permutation table for random gradients
|
|
local perm = {}
|
|
local grad3 = {
|
|
{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}
|
|
}
|
|
|
|
-- Initialize permutation table
|
|
local function ShufflePermutation()
|
|
local p = {}
|
|
for i = 0, 255 do
|
|
p[i] = i
|
|
end
|
|
for i = 255, 1, -1 do
|
|
local j = math.random(i + 1) - 1
|
|
p[i], p[j] = p[j], p[i]
|
|
end
|
|
for i = 0, 255 do
|
|
perm[i] = p[i]
|
|
perm[i + 256] = p[i] -- Repeat for wrapping
|
|
end
|
|
end
|
|
|
|
ShufflePermutation() -- Randomize on load
|
|
|
|
-- Dot product helper
|
|
local function Dot(g, x, y, z)
|
|
return g[1] * x + g[2] * y + (z and g[3] * z or 0)
|
|
end
|
|
|
|
-- Fade function (smootherstep)
|
|
local function Fade(t)
|
|
return t * t * t * (t * (t * 6 - 15) + 10)
|
|
end
|
|
|
|
-- Linear interpolation
|
|
local function Lerp(a, b, t)
|
|
return a + (b - a) * t
|
|
end
|
|
|
|
-- **Perlin Noise 1D**
|
|
function Perlin.Noise1D(x)
|
|
local X = math.floor(x) & 255
|
|
x = x - math.floor(x)
|
|
local u = Fade(x)
|
|
|
|
local a = perm[X]
|
|
local b = perm[X + 1]
|
|
|
|
return Lerp(a, b, u) * (2 / 255) - 1
|
|
end
|
|
|
|
-- **Perlin Noise 2D**
|
|
function Perlin.Noise2D(x, y)
|
|
local X = math.floor(x) & 255
|
|
local Y = math.floor(y) & 255
|
|
x, y = x - math.floor(x), y - math.floor(y)
|
|
|
|
local u, v = Fade(x), Fade(y)
|
|
|
|
local aa = perm[X] + Y
|
|
local ab = perm[X] + Y + 1
|
|
local ba = perm[X + 1] + Y
|
|
local bb = perm[X + 1] + Y + 1
|
|
|
|
return Lerp(
|
|
Lerp(Dot(grad3[perm[aa] % 12 + 1], x, y), Dot(grad3[perm[ba] % 12 + 1], x - 1, y), u),
|
|
Lerp(Dot(grad3[perm[ab] % 12 + 1], x, y - 1), Dot(grad3[perm[bb] % 12 + 1], x - 1, y - 1), u),
|
|
v
|
|
)
|
|
end
|
|
|
|
-- **Perlin Noise 3D**
|
|
function Perlin.Noise3D(x, y, z)
|
|
local X = math.floor(x) & 255
|
|
local Y = math.floor(y) & 255
|
|
local Z = math.floor(z) & 255
|
|
x, y, z = x - math.floor(x), y - math.floor(y), z - math.floor(z)
|
|
|
|
local u, v, w = Fade(x), Fade(y), Fade(z)
|
|
|
|
local aaa = perm[X] + Y + Z
|
|
local aba = perm[X] + Y + Z + 1
|
|
local aab = perm[X] + Y + 1 + Z
|
|
local abb = perm[X] + Y + 1 + Z + 1
|
|
local baa = perm[X + 1] + Y + Z
|
|
local bba = perm[X + 1] + Y + Z + 1
|
|
local bab = perm[X + 1] + Y + 1 + Z
|
|
local bbb = perm[X + 1] + Y + 1 + Z + 1
|
|
|
|
return Lerp(
|
|
Lerp(
|
|
Lerp(Dot(grad3[perm[aaa] % 12 + 1], x, y, z), Dot(grad3[perm[baa] % 12 + 1], x - 1, y, z), u),
|
|
Lerp(Dot(grad3[perm[aab] % 12 + 1], x, y - 1, z), Dot(grad3[perm[bab] % 12 + 1], x - 1, y - 1, z), u),
|
|
v
|
|
),
|
|
Lerp(
|
|
Lerp(Dot(grad3[perm[aba] % 12 + 1], x, y, z - 1), Dot(grad3[perm[bba] % 12 + 1], x - 1, y, z - 1), u),
|
|
Lerp(Dot(grad3[perm[abb] % 12 + 1], x, y - 1, z - 1), Dot(grad3[perm[bbb] % 12 + 1], x - 1, y - 1, z - 1), u),
|
|
v
|
|
),
|
|
w
|
|
)
|
|
end
|
|
|
|
exports('Perlin', Perlin)
|
|
return Perlin
|