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
 | 
