I am doing terrain generation on a chunk by chunk basis and I have converted a module for Cellular Noise in order to do cave generation, but my problem is that it is quite slow on a large scale, a large scale being about 256 times per second. So if someone could help me make this more efficient that would mean a great ordeal!
The main noise method:
function CellularNoise.noise(x, y, z) local x = x or 0 local y = y or 0 local z = z or 0 local input = Vector3.new(x, y, z) local lastRandom, numPoints = 0, 0 local randomDiff, featurePoint = Vector3.new() local cubeX, cubeY, cubeZ = 0, 0, 0 local noiseArray = {6666} local evalCubeX = math.floor(x) local evalCubeY = math.floor(y) local evalCubeZ = math.floor(z) for i = -1, 1 do wait() -- I don't really like having this here as it slows down generation greatly, I want an alternative, the best would be more efficient calculations. for j = -1, 1 do for k = -1, 1 do cubeX = evalCubeX + i cubeY = evalCubeY + j cubeZ = evalCubeZ + k lastRandom = lcgRandom(hash(cubeX, cubeY, cubeZ)) numPoints = probLookup(lastRandom) for l = 1, numPoints do lastRandom = lcgRandom(lastRandom) randomDiff = randomDiff * Vector3.new(0, 1, 1) + Vector3.new(lastRandom / 0x100000000, 0, 0) lastRandom = lcgRandom(lastRandom) randomDiff = randomDiff * Vector3.new(1, 0, 1) + Vector3.new(0, lastRandom / 0x100000000, 0) lastRandom = lcgRandom(lastRandom) randomDiff = randomDiff * Vector3.new(1, 1, 0) + Vector3.new(0, 0, lastRandom / 0x100000000) featurePoint = Vector3.new(randomDiff.X + cubeX, randomDiff.Y + cubeY, randomDiff.Z + cubeZ) insert(noiseArray, math.clamp((featurePoint - input).Magnitude * 2, 0, 1)) end end end end return noiseArray[1] end
Other methods used:
-- linear congruential generator local function lcgRandom(lastValue) return math.floor((110351245 * lastValue + 12345) % 0x100000000) end local OFFSET_BASIS = 2166136261 local FNV_PRIME = 16777619 -- FNV hash local function hash(i, j, k) return bit.bxor(bit.bxor(bit.bxor(OFFSET_BASIS, i) * FNV_PRIME, j) * FNV_PRIME, k) * FNV_PRIME end -- possion distribution local function probLookup(value) if value < 393325350 then return 1 end if value < 1022645910 then return 2 end if value < 1861739990 then return 3 end if value < 2700834071 then return 4 end if value < 3372109335 then return 5 end if value < 3819626178 then return 6 end if value < 4075350088 then return 7 end if value < 4203212043 then return 8 end return 9 end -- insertion sort local function insert(arr, value) local temp, l = 0, #arr for i=l, 1, -1 do if value > arr[i] then break end temp = arr[i] arr[i] = value if (i+1 < l) then arr[i+1] = temp end end end
Any help would be great! Thanks.