1
\$\begingroup\$

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: Looks fine here,

3D: but now its all cube-ish.

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!

\$\endgroup\$
  • \$\begingroup\$ 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. \$\endgroup\$ – wondra Oct 30 '14 at 11:41
1
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.