Skip to content

Instantly share code, notes, and snippets.

@TinkerWorX
Created May 3, 2019 18:43
Show Gist options
  • Save TinkerWorX/e5d1d1247f38c9e61e5f8b3862f83991 to your computer and use it in GitHub Desktop.
Save TinkerWorX/e5d1d1247f38c9e61e5f8b3862f83991 to your computer and use it in GitHub Desktop.
--[[---------------------------------------------
**********************************************************************************
Simplex Noise Module, Translated by Levybreak
Modified by Jared "Nergal" Hewitt for use with MapGen for Love2D
Modified by Nikolaj "William" Mariager for updates to Lua 5.3
Original Source: http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf
The code there is in java, the original implementation by Ken Perlin
**********************************************************************************
--]]---------------------------------------------
local SimplexNoise = {}
SimplexNoise.Gradients3D = {
{ 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}
}
for i=1,#SimplexNoise.Gradients3D do
SimplexNoise.Gradients3D[i-1] = SimplexNoise.Gradients3D[i]
SimplexNoise.Gradients3D[i] = nil
end
function SimplexNoise.seedP(seed)
s2 = seed * 1234567
-- reset all the things
SimplexNoise.p = {}
SimplexNoise.Prev2D = {}
SimplexNoise.PrevBlur2D = {}
local r = 0
for i=1, 256 do
SimplexNoise.p[i] = (s2 + math.floor(s2 / i)) % 256
end
-- To remove the need for index wrapping, double the permutation table length
for i=1,#SimplexNoise.p do
SimplexNoise.p[i - 1] = SimplexNoise.p[i]
SimplexNoise.p[i] = nil
end
SimplexNoise.perm = {}
for i=0,255 do
SimplexNoise.perm[i] = SimplexNoise.p[i]
SimplexNoise.perm[i + 256] = SimplexNoise.p[i]
end
end
SimplexNoise.Dot2D = function(tbl, x, y)
return tbl[1] * x + tbl[2] * y
end
SimplexNoise.Prev2D = { }
-- 2D simplex noise
SimplexNoise.Noise2D = function(xin, yin)
if SimplexNoise.Prev2D[xin] and SimplexNoise.Prev2D[xin][yin] then return SimplexNoise.Prev2D[xin][yin] end
local n0, n1, n2 -- Noise contributions from the three corners
-- Skew the input space to determine which simplex cell were in
local F2 = 0.5 * (math.sqrt(3.0) - 1.0)
local s = (xin + yin) * F2 -- Hairy factor for 2D
local i = math.floor(xin + s)
local j = math.floor(yin + s)
local G2 = (3.0 - math.sqrt(3.0)) / 6.0
local t = (i+j)*G2
local X0 = i-t -- Unskew the cell origin back to (x,y) space
local Y0 = j-t
local x0 = xin-X0 -- The x,y distances from the cell origin
local y0 = yin-Y0
-- For the 2D case, the simplex shape is an equilateral triangle.
-- Determine which simplex we are in.
local i1, j1; -- Offsets for second (middle) corner of simplex in (i,j) coords
if x0 > y0 then
i1 = 1
j1 = 0 -- lower triangle, XY order: (0,0)->(1,0)->(1,1)
else
i1 = 0
j1 = 1 -- upper triangle, YX order: (0,0)->(0,1)->(1,1)
end
-- A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
-- a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
-- c = (3-sqrt(3))/6
local x1 = x0 - i1 + G2 -- Offsets for middle corner in (x,y) unskewed coords
local y1 = y0 - j1 + G2
local x2 = x0 - 1.0 + 2.0 * G2 -- Offsets for last corner in (x,y) unskewed coords
local y2 = y0 - 1.0 + 2.0 * G2
-- Work out the hashed gradient indices of the three simplex corners
local ii = i & 255
local jj = j & 255
local gi0 = SimplexNoise.perm[ii + SimplexNoise.perm[jj]] % 12
local gi1 = SimplexNoise.perm[ii + i1 + SimplexNoise.perm[jj + j1]] % 12
local gi2 = SimplexNoise.perm[ii + 1 + SimplexNoise.perm[jj + 1]] % 12
-- Calculate the contribution from the three corners
local t0 = 0.5 - x0 * x0 - y0 * y0
if t0 < 0 then
n0 = 0.0;
else
t0 = t0 * t0
n0 = t0 * t0 * SimplexNoise.Dot2D(SimplexNoise.Gradients3D[gi0], x0, y0) -- (x,y) of Gradients3D used for 2D gradient
end
local t1 = 0.5 - x1 * x1 - y1 * y1;
if t1 < 0 then
n1 = 0.0
else
t1 = t1 * t1
n1 = t1 * t1 * SimplexNoise.Dot2D(SimplexNoise.Gradients3D[gi1], x1, y1)
end
local t2 = 0.5 - x2 * x2 - y2 * y2;
if t2 < 0 then
n2 = 0.0
else
t2 = t2 * t2
n2 = t2 * t2 * SimplexNoise.Dot2D(SimplexNoise.Gradients3D[gi2], x2, y2)
end
-- Add contributions from each corner to get the final noise value.
-- The result is scaled to return values in the localerval [-1,1].
local retval = 70.0 * (n0 + n1 + n2)
if not SimplexNoise.Prev2D[xin] then SimplexNoise.Prev2D[xin] = { } end
SimplexNoise.Prev2D[xin][yin] = retval
return retval
end
SimplexNoise.PrevBlur2D = {}
SimplexNoise.GBlur2D = function(x, y, stdDev)
if SimplexNoise.PrevBlur2D[x] and SimplexNoise.PrevBlur2D[x][y] and SimplexNoise.PrevBlur2D[x][y][stdDev] then return SimplexNoise.PrevBlur2D[x][y][stdDev] end
local pwr = ((x ^ 2 + y ^ 2) / (2 * (stdDev ^ 2))) * -1
local ret = ((1 / (2 * math.pi * (stdDev ^ 2)))*e) ^ pwr
if not SimplexNoise.PrevBlur2D[x] then PrevBlur2D[x] = {} end
if not SimplexNoise.PrevBlur2D[x][y] then PrevBlur2D[x][y] = {} end
SimplexNoise.PrevBlur2D[x][y][stdDev] = ret
return ret
end
SimplexNoise.FractalSum2DNoise = function(x, y, itier) --very expensive, much more so that standard 2D noise.
local ret = SimplexNoise.Noise2D(x,y)
for i = 1,itier do
local itier = 2 ^ itier
ret = ret + (i / itier) * (SimplexNoise.Noise2D(x * (itier / i),y * (itier / i)))
end
return ret
end
SimplexNoise.FractalSumAbs2DNoise = function(x, y, itier) --very expensive, much more so that standard 2D noise.
local ret = math.abs(SimplexNoise.Noise2D(x, y))
for i = 1,itier do
local itier = 2 ^ itier
ret = ret + (i / itier) * (math.abs(SimplexNoise.Noise2D(x * (itier / i),y * (itier / i))))
end
return ret
end
SimplexNoise.Turbulent2DNoise = function(x, y, itier) --very expensive, much more so that standard 2D noise.
local ret = math.abs(SimplexNoise.Noise2D(x, y))
for i = 1,itier do
local itier = 2 ^ itier
ret = ret + (i / itier) * (math.abs(SimplexNoise.Noise2D(x * (itier / i),y * (itier / i))))
end
return math.sin(x + ret)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment