Advertisement
Xelostar

Noise API

Jul 7th, 2018
250
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.61 KB | None | 0 0
  1.  
  2. -- Made by Xelostar: https://www.youtube.com/channel/UCDE2STpSWJrIUyKtiYGeWxw
  3.  
  4. local function randomValue()
  5.     return math.random(0, 1023) / 1023
  6. end
  7.  
  8. local function getRawLayer(layerWidth, x, y, seed)
  9.     math.randomseed(seed + x * 1000 + y * 1000000)
  10.     local prelayer = {}
  11.     for x = 1, layerWidth + 2 do
  12.         prelayer[x] = {}
  13.         for y = 1, layerWidth + 2 do
  14.             local value = randomValue()
  15.             prelayer[x][y] = value
  16.         end
  17.     end
  18.  
  19.     return prelayer
  20. end
  21.  
  22. local function getValueLinear(X1, X2, Y1, Y2, X3)
  23.     local a = (Y2 - Y1) / (X2 - X1)
  24.     local b = Y2 - a * X2
  25.    
  26.     local Y3 = a * X3 + b
  27.  
  28.     return Y3
  29. end
  30.  
  31. local function getValueCosine(X1, X2, Y1, Y2, X3)
  32.     --if (X3 < X1 or X3 > X2) then error("Invalid X3!") end
  33.     --if (X1 == X2) then error("X1 shouldn't be X2!") end
  34.     --if (Y1 == Y2) then error("Y1 shouldn't be Y2!") end
  35.     local Y3 = (1-math.cos(math.pi/(X1-X2) * (X3-X1))) / 2 * (Y2-Y1) + Y1--Y3 = (Y2 - Y1) / 2 * (1 - math.cos(math.pi * (X3 - X1) / (X2 - X1))) + Y1
  36.  
  37.     return Y3
  38. end
  39.  
  40. local function createNoiseLayer(size, layerWidth, x, y, seed)
  41.     local prelayer = getRawLayer(layerWidth, x, y, seed)
  42.  
  43.     local prelayerUp = getRawLayer(layerWidth, x, y - 1, seed)
  44.     local prelayerDown = getRawLayer(layerWidth, x, y + 1, seed)
  45.     local prelayerLeft = getRawLayer(layerWidth, x - 1, y, seed)
  46.     local prelayerRight = getRawLayer(layerWidth, x + 1, y, seed)
  47.  
  48.     for x = 2, layerWidth + 1 do
  49.         prelayer[x][1] = prelayerUp[x][layerWidth + 1]
  50.     end
  51.     for x = 2, layerWidth + 1 do
  52.         prelayer[x][layerWidth + 2] = prelayerDown[x][2]
  53.     end
  54.     for y = 2, layerWidth + 1 do
  55.         prelayer[1][y] = prelayerLeft[layerWidth + 1][y]
  56.     end
  57.     for y = 2, layerWidth + 1 do
  58.         prelayer[layerWidth + 2][y] = prelayerRight[2][y]
  59.     end
  60.    
  61.     local layer = {}
  62.     for x = 2, layerWidth + 1 do
  63.         for y = 2, layerWidth + 1 do
  64.             local value = prelayer[x][y]
  65.             local valueUp = prelayer[x][y - 1]
  66.             local valueDown = prelayer[x][y + 1]
  67.             local valueLeft = prelayer[x - 1][y]
  68.             local valueRight = prelayer[x + 1][y]
  69.  
  70.             for x2 = (x - 1 - 1) * size / layerWidth + 1, (x - 1) * size / layerWidth do
  71.                 if (layer[x2] == nil) then
  72.                     layer[x2] = {}
  73.                 end
  74.                 for y2 = (y - 1 - 1) * size / layerWidth + 1, (y - 1) * size / layerWidth do
  75.                     local localX = x2 - (x - 1 - 1) * size / layerWidth
  76.                     local localY = y2 - (y - 1 - 1) * size / layerWidth
  77.  
  78.                     if (localX == size / layerWidth / 2 and localY == size / layerWidth / 2) then
  79.                         layer[x2][y2] = value
  80.                     elseif (localX - localY > 0) then -- upper right
  81.                         if (size / layerWidth - localX - localY > 0) then -- upper left
  82.                             local X1 = -size / layerWidth / 2
  83.                             local X2 = size / layerWidth / 2
  84.                             local Y1 = valueUp
  85.                             local Y2 = value
  86.                             local X3 = localY
  87.  
  88.                             local newValue = getValueCosine(X1, X2, Y1, Y2, X3)
  89.                             layer[x2][y2] = newValue -- up
  90.                         else -- bottom right
  91.                             local X1 = size / layerWidth / 2
  92.                             local X2 = size / layerWidth / 2 * 3
  93.                             local Y1 = value
  94.                             local Y2 = valueRight
  95.                             local X3 = localX
  96.  
  97.                             local newValue = getValueCosine(X1, X2, Y1, Y2, X3)
  98.                             layer[x2][y2] = newValue -- right
  99.                         end
  100.                     else -- bottom left
  101.                         if (size / layerWidth - localX - localY > 0) then -- upper left
  102.                             local X1 = -size / layerWidth / 2
  103.                             local X2 = size / layerWidth / 2
  104.                             local Y1 = valueLeft
  105.                             local Y2 = value
  106.                             local X3 = localX
  107.  
  108.                             local newValue = getValueCosine(X1, X2, Y1, Y2, X3)
  109.                             layer[x2][y2] = newValue -- left
  110.                         else -- bottom right
  111.                             local X1 = size / layerWidth / 2
  112.                             local X2 = size / layerWidth / 2 * 3
  113.                             local Y1 = value
  114.                             local Y2 = valueDown
  115.                             local X3 = localY
  116.  
  117.                             local newValue = getValueCosine(X1, X2, Y1, Y2, X3)
  118.                             layer[x2][y2] = newValue -- bottom
  119.                         end
  120.                     end
  121.                 end
  122.             end
  123.         end
  124.     end
  125.     return layer
  126. end
  127.  
  128. local function compressNoiseLayers(noiseLayers)
  129.     noise = {}
  130.     noiseSize = table.getn(noiseLayers[1])
  131.  
  132.     for layerNr, layer in pairs(noiseLayers) do
  133.         for x = 1, noiseSize do
  134.             if (noise[x] == nil) then
  135.                 noise[x] = {}
  136.             end
  137.             for y = 1, noiseSize do
  138.                 if (layerNr == 1) then
  139.                     noise[x][y] = layer[x][y]
  140.                 else
  141.                     noise[x][y] = (noise[x][y] * (layerNr - 1) + layer[x][y]) / layerNr
  142.                 end
  143.             end
  144.         end
  145.     end
  146.  
  147.     return noise
  148. end
  149.  
  150. function createNoise(size, x, y, seed, smoothness)
  151.     local smoothness = smoothness or 1
  152.     if (size == nil) then
  153.         error("createNoise arg#1: integer expected, got nil")
  154.     elseif (type(size) ~= "number") then
  155.         error("createNoise arg#1: integer expected, got "..type(size))
  156.     else
  157.         if ((size / (2 ^ smoothness)) / 2 % 1 ~= 0) then
  158.             error("createNoise arg#1 and/or arg#5: the size must be at least 2 and divisible by 2^(smoothness+1)")
  159.         end
  160.     end
  161.     if (x == nil) then
  162.         error("createNoiseLayers arg#2 integer expected, got nil")
  163.     elseif (type(x) ~= "number") then
  164.         error("createNoiseLayers arg#2: integer expected, got "..type(x))
  165.     end
  166.     if (y == nil) then
  167.         error("createNoiseLayers arg#3: integer expected, got nil")
  168.     elseif (type(y) ~= "number") then
  169.         error("createNoiseLayers arg#3: integer expected, got "..type(y))
  170.     end
  171.     if (seed == nil) then
  172.         error("createNoiseLayers arg#4: integer expected, got nil")
  173.     elseif (type(seed) ~= "number") then
  174.         error("createNoiseLayers arg#4: integer expected, got "..type(seed))
  175.     end
  176.  
  177.     local noiseLayers = {}
  178.  
  179.     local layerWidth = 2
  180.     while (layerWidth <= size / (2 ^ smoothness)) do
  181.         local layer = createNoiseLayer(size, layerWidth, x, y, seed)
  182.         table.insert(noiseLayers, layer)
  183.         layerWidth = layerWidth * 2
  184.     end
  185.  
  186.     local compressedNoise = compressNoiseLayers(noiseLayers)
  187.  
  188.     return compressedNoise
  189. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement