Custom 3D Noise function incorrectly generating in Lua

I have been working on a custom noise generator (not Perlin on Simplex or whatever), which works fine in two dimensional space, but upon converting it into three dimensional space, it turns into a cube-ish thing. I could not figure out why, not even after many hours of looking. Here are screenshots of the two functions, 2D and 3D.

2D:

3D:

Here is the code for both.

2D:

local shape = {}
local deform = {}

math.randomseed(tick())

for i=1, 50 do
for j=1, 50 do
shape["i"..i.."j"..j]=(math.random(50)/10)-1.5
end
end

for x=1, 50 do
for y=1, 50 do
local q11 = shape["i"..x-1 .."j"..y]
local q12 = shape["i"..x-1 .."j"..y+1]
local q21 = shape["i"..x+1 .."j"..y]
local q22 = shape["i"..x+1 .."j"..y+1]
if not q11 then q11=0 end
if not q12 then q12=0 end
if not q21 then q21=0 end
if not q22 then q22=0 end
local q = shape["i"..x.."j"..y]
shape["i"..x.."j"..y]=(q+q11+q12+q21+q22)/10
end
end

function noise(x,y)
local q11 = shape["i"..math.floor(x).."j"..math.floor(y)]
local q12 = shape["i"..math.floor(x).."j"..math.floor(y)+1]
local q21 = shape["i"..math.floor(x)+1 .."j"..math.floor(y)]
local q22 = shape["i"..math.floor(x)+1 .."j"..math.floor(y)+1]
if not q11 then q11=0 end
if not q12 then q12=0 end
if not q21 then q21=0 end
if not q22 then q22=0 end
local lx1 = ((q21-q11)*(x-math.floor(x)))+q11
local lx2 = ((q22-q12)*(x-math.floor(x)))+q12
return ((lx2-lx1)*(y-math.floor(y)))+lx1
end

for i=0, 100 do
for j=0, 100 do
local noise = noise(i/5,j/5)
if noise>0.5 then
workspace.Terrain:SetCell(i,j,0,1,0,0)
end
end
wait()
end


3D:

local shape = {}
local deform = {}

math.randomseed(tick())

for i=1, 50 do
for j=1, 50 do
for k=1, 50 do
shape["i"..i.."j"..j.."k"..k]=(math.random(50)/10)-1.5
end
end
wait()
end
function get(i,j,k)
return shape["i"..i.."j"..j.."k"..k]
end
for i=1, 50 do
for j=1, 50 do
for k=1,50 do
local x = math.floor(i)
local y = math.floor(j)
local z = math.floor(k)
local xyz=get(x-1,y-1,z-1)
local xYz=get(x-1,y+1,z-1)
local Xyz=get(x+1,y-1,z-1)
local XYz=get(x+1,y+1,z-1)
local xyZ=get(x-1,y-1,z+1)
local xYZ=get(x-1,y+1,z+1)
local XyZ=get(x+1,y-1,z+1)
local XYZ=get(x+1,y+1,z+1)
if not xyz then xyz=0 end
if not xYz then xYz=0 end
if not Xyz then Xyz=0 end
if not XYz then XYz=0 end
if not xyZ then xyZ=0 end
if not xYZ then xYZ=0 end
if not XyZ then XyZ=0 end
if not XYZ then XYZ=0 end
local g = shape["i"..x.."j"..y.."k"..z]
shape["i"..x.."j"..y.."k"..z] = (xyz+xYz+Xyz+XYz+xyZ+xYZ+XyZ+XYZ+g)/9
end
end
end

function lerp(a,b,c)
return ((b-a)*(c))+a
end

function lerpX(a,b,c)
return lerp(a,b,c)
end

function lerpY(a,b,c)
return lerp(b,a,c)
end

function lerpZ(a,b,c)
return lerp(b,a,c)
end

function noise(i,j,k)
local x = math.floor(i)
local y = math.floor(j)
local z = math.floor(k)
local xyz=get(x-1,y-1,z-1)
local xYz=get(x-1,y+1,z-1)
local Xyz=get(x+1,y-1,z-1)
local XYz=get(x+1,y+1,z-1)
local xyZ=get(x-1,y-1,z+1)
local xYZ=get(x-1,y+1,z+1)
local XyZ=get(x+1,y-1,z+1)
local XYZ=get(x+1,y+1,z+1)
if not xyz then xyz=0 end
if not xYz then xYz=0 end
if not Xyz then Xyz=0 end
if not XYz then XYz=0 end
if not xyZ then xyZ=0 end
if not xYZ then xYZ=0 end
if not XyZ then XyZ=0 end
if not XYZ then XYZ=0 end
local lx1 = lerpX(xyz,Xyz,i-math.floor(i))
local lx2 = lerpX(xYz,XYz,i-math.floor(i))
local ly1 = lerpY(lx1,lx2,j-math.floor(j))
local lx3 = lerpX(xyZ,XyZ,i-math.floor(i))
local lx4= lerpX(xYZ,XYZ,i-math.floor(i))
local ly2 = lerpY(lx3,lx4,j-math.floor(j))
return lerpZ(ly1,ly2,k-math.floor(k))
end

for i=0, 60 do
for j=0, 60 do
for k=0,60 do
local noise = noise(i/10,j/10,k/10)
if noise>0.5 then
workspace.Terrain:SetCell(i,j,k,1,0,0)
end
end
if true then wait() end
end
end


Any help would be greatly appreciated!

• I do not understand lua much, but why two different codes? Why not just promote the "noise" variable in 2d to Z coordinate? (=map it on desired Z interval) Alternatively, create lowest 2D level and logic AND it with level above, repeat. – wondra Oct 30 '14 at 11:41

I imagine it's because you're only passing the iterators i, j, k to SetCell which will limit cell placement to 60 along all three axes, creating the outline of a cube.