mirror of
				https://github.com/osmarks/random-stuff
				synced 2025-10-31 13:53:01 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			134 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
| local defaultSeed = 1337
 | |
| 
 | |
| local dot_product = {
 | |
|   [0x0]=function(x,y,z) return  x + y end,
 | |
|   [0x1]=function(x,y,z) return -x + y end,
 | |
|   [0x2]=function(x,y,z) return  x - y end,
 | |
|   [0x3]=function(x,y,z) return -x - y end,
 | |
|   [0x4]=function(x,y,z) return  x + z end,
 | |
|   [0x5]=function(x,y,z) return -x + z end,
 | |
|   [0x6]=function(x,y,z) return  x - z end,
 | |
|   [0x7]=function(x,y,z) return -x - z end,
 | |
|   [0x8]=function(x,y,z) return  y + z end,
 | |
|   [0x9]=function(x,y,z) return -y + z end,
 | |
|   [0xA]=function(x,y,z) return  y - z end,
 | |
|   [0xB]=function(x,y,z) return -y - z end,
 | |
|   [0xC]=function(x,y,z) return  y + x end,
 | |
|   [0xD]=function(x,y,z) return -y + z end,
 | |
|   [0xE]=function(x,y,z) return  y - x end,
 | |
|   [0xF]=function(x,y,z) return -y - z end
 | |
| }
 | |
| 
 | |
| local grad = function(hash, x,y,z)
 | |
|   return dot_product[hash % 0x10](x,y,z)
 | |
| end
 | |
| 
 | |
| local fade = function(t)
 | |
|   return t * t * t * (t * (t * 6 - 15) + 10)
 | |
| end
 | |
| 
 | |
| local lerp = function(t,a,b)
 | |
|   return a + t * (b - a)
 | |
| end
 | |
| 
 | |
| local generatePermutation = function(seed)
 | |
|   math.randomseed(seed)
 | |
| 
 | |
|   local permutation = {0}
 | |
| 
 | |
|   for i=1,255 do
 | |
|     table.insert(permutation,math.random(1,#permutation+1),i)
 | |
|   end
 | |
| 
 | |
|   local p = {}
 | |
| 
 | |
|   for i=0,255 do
 | |
|     p[i] = permutation[i+1]
 | |
|     p[i+256] = permutation[i+1]
 | |
|   end
 | |
| 
 | |
|   return p
 | |
| end
 | |
| 
 | |
| perlin = {}
 | |
| perlin.__index = perlin
 | |
| 
 | |
| perlin.noise = function(self,x,y,z)
 | |
|   y = y or 0
 | |
|   z = z or 0
 | |
| 
 | |
|   local xi = math.floor(x) % 0x100
 | |
|   local yi = math.floor(y) % 0x100
 | |
|   local zi = math.floor(z) % 0x100
 | |
| 
 | |
|   x = x - math.floor(x)
 | |
|   y = y - math.floor(y)
 | |
|   z = z - math.floor(z)
 | |
| 
 | |
|   local u = fade(x)
 | |
|   local v = fade(y)
 | |
|   local w = fade(z)
 | |
| 
 | |
|   local A, AA, AB, AAA, ABA, AAB, ABB, B, BA, BB, BAA, BBA, BAB, BBB
 | |
|   A   = self.p[xi  ] + yi
 | |
|   AA  = self.p[A   ] + zi
 | |
|   AB  = self.p[A+1 ] + zi
 | |
|   AAA = self.p[ AA ]
 | |
|   ABA = self.p[ AB ]
 | |
|   AAB = self.p[ AA+1 ]
 | |
|   ABB = self.p[ AB+1 ]
 | |
| 
 | |
|   B   = self.p[xi+1] + yi
 | |
|   BA  = self.p[B   ] + zi
 | |
|   BB  = self.p[B+1 ] + zi
 | |
|   BAA = self.p[ BA ]
 | |
|   BBA = self.p[ BB ]
 | |
|   BAB = self.p[ BA+1 ]
 | |
|   BBB = self.p[ BB+1 ]
 | |
| 
 | |
|   return lerp(w,
 | |
|     lerp(v,
 | |
|       lerp(u,
 | |
|         grad(AAA,x,y,z),
 | |
|         grad(BAA,x-1,y,z)
 | |
|       ),
 | |
|       lerp(u,
 | |
|         grad(ABA,x,y-1,z),
 | |
|         grad(BBA,x-1,y-1,z)
 | |
|       )
 | |
|     ),
 | |
|     lerp(v,
 | |
|       lerp(u,
 | |
|         grad(AAB,x,y,z-1), grad(BAB,x-1,y,z-1)
 | |
|       ),
 | |
|       lerp(u,
 | |
|         grad(ABB,x,y-1,z-1), grad(BBB,x-1,y-1,z-1)
 | |
|       )
 | |
|     )
 | |
|   )
 | |
| end
 | |
| 
 | |
| setmetatable(perlin,{
 | |
|   __call = function(self,seed)
 | |
|     seed = seed or defaultSeed
 | |
| 
 | |
|     return setmetatable({
 | |
|       seed = seed,
 | |
|       p = generatePermutation(seed),
 | |
|     },self)
 | |
|   end
 | |
| })
 | |
| 
 | |
| --[[
 | |
| EXAMPLE
 | |
|   local p1 = perlin(1338)
 | |
|   local p2 = perlin(1337)
 | |
| 
 | |
|   local x,y,z = 1.0,2.0,3.0
 | |
| 
 | |
|   print(p1:noise(x,y,z))
 | |
|   print(p2:noise(x,y,z))
 | |
|   
 | |
|   >> 0.23456
 | |
|   >> 0.47598
 | |
| --]] |