Skip to content

Instantly share code, notes, and snippets.

@jjwatt
Created October 24, 2024 17:23
Show Gist options
  • Save jjwatt/fad8b0eb4ba1855e3e7d3e42f7c4e1e0 to your computer and use it in GitHub Desktop.
Save jjwatt/fad8b0eb4ba1855e3e7d3e42f7c4e1e0 to your computer and use it in GitHub Desktop.
perlin noise function in lua
-- Permutation table with indices 0-255 repeated
local p = {
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
}
-- Double the permutation table
for i = 0, 255 do
p[i + 256] = p[i + 1]
end
-- Helper function to fade values for smoother interpolation
local function fade(t)
return t * t * t * (t * (t * 6 - 15) + 10)
end
-- Helper function for gradient calculation
local function grad(hash, x, y, z)
local h = hash % 16
local u = h < 8 and x or y
local v = h < 4 and y or ((h == 12 or h == 14) and x or z)
return ((h % 2) == 0 and u or -u) + ((h % 3) == 0 and v or -v)
end
-- Linear interpolation helper function
local function lerp(t, a, b)
return a + t * (b - a)
end
-- Main Perlin noise function
function perlin(x, y, z)
-- Add small offset to prevent floating point errors
x = x + 0.1
y = y or 0 + 0.1
z = z or 0 + 0.1
-- Calculate unit cube that contains the point
local X = math.floor(x) % 256
local Y = math.floor(y) % 256
local Z = math.floor(z) % 256
-- Get relative xyz coordinates of point within cube
x = x - math.floor(x)
y = y - math.floor(y)
z = z - math.floor(z)
-- Compute fade curves for xyz
local u = fade(x)
local v = fade(y)
local w = fade(z)
-- Hash coordinates of cube corners
local A = p[X + 1] + Y
local AA = p[A + 1] + Z
local AB = p[A + 2] + Z
local B = p[X + 2] + Y
local BA = p[B + 1] + Z
local BB = p[B + 2] + Z
-- Add blended results from 8 corners of cube
local result = lerp(w,
lerp(v,
lerp(u,
grad(p[AA + 1], x, y, z),
grad(p[BA + 1], x - 1, y, z)
),
lerp(u,
grad(p[AB + 1], x, y - 1, z),
grad(p[BB + 1], x - 1, y - 1, z)
)
),
lerp(v,
lerp(u,
grad(p[AA + 2], x, y, z - 1),
grad(p[BA + 2], x - 1, y, z - 1)
),
lerp(u,
grad(p[AB + 2], x, y - 1, z - 1),
grad(p[BB + 2], x - 1, y - 1, z - 1)
)
)
)
-- Return result in range [-1, 1]
return result
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment