Voxel Terrain has gaps

I’ve been working on a project involving voxels, and I’ve managed to whip up a pretty good terrain generator. However, there can sometimes be gaps between voxels. I know this is because the neighbouring voxel is higher than a block but I’ve tried everything I’ve looked at and could think of but nothing has worked. If someone can please help, that would be greatly appreciated! Here’s the code so far:

assert(OrbitViewer)
seed = math.random(1, 10^10)

function setup()
    -- Create a new craft scene
    scene = craft.scene()
    scene.camera:add(OrbitViewer, vec3(0, 0, 0), 10, 0, 100000000)
    scene.camera.farPlane = math.maxinteger
    generateArea()
end

function generateArea()
    scene.voxels.blocks:addAssetPack("Blocks")
    local grass = scene.voxels.blocks:new("Grass")
    grass.setTexture(ALL, "Blocks:Dirt Grass")
    grass.setTexture(UP, "Blocks:Grass Top")
    grass.setTexture(DOWN, "Blocks:Dirt")
    local snow = scene.voxels.blocks:new("Snow")
    snow.setTexture(ALL, "Blocks:Snow")
    local sand = scene.voxels.blocks:new("Sand")
    sand.setTexture(ALL, "Blocks:Sand")
    
    scene.voxels:resize(vec3(10^4, 1, 10^4))
    scene.voxels.visibleRadius = 40
    scene.voxels.coordinates = vec3(0, 0, 0)
    scene.voxels:iterateBounds(vec3(0, 0, 0), vec3(100, 1, 100), generateVoxels)
end
 
function update(dt)
    -- Update the scene (physics, transforms etc)
    scene:update(dt)
end

-- Called automatically by codea 
function draw()
    update(DeltaTime)

    -- Draw the scene
    scene:draw()	
end

function generateVoxels(x, y, z, id)
    local perlin = craft.noise.perlin()
    local height = perlin:getValue(x / 280, z / 292, seed)
    if height >= math.random(7, 8) / 10 * -1 then
        scene.voxels:fill("Grass")
    else
        if math.random(1, 10000) / height < 500 then
            scene.voxels:fill("Snow")
        end
    end
    if height >= .00001 then
        scene.voxels:fill("Sand")
    end
    scene.voxels:block(vec3(x, height * -56, z))
end

I looked at my terrain program and it has the blank spots too. I guess I can look into this to see why and what code changes are needed, but I never really worried about it.

viewer.mode=FULLSCREEN

function setup()
    assert(OrbitViewer, "Please include Cameras as a dependency")
    scene = craft.scene() 
    v=scene.camera:add(OrbitViewer,vec3(250,100,100), 1000, 0, 2000)
    v.camera.farPlane=10000
    v.rx,v.ry=20,-10
    
    scene.voxels.blocks:addAssetPack("Blocks")
    dirtgrass = scene.voxels.blocks:new("DirtGrass")
    dirtgrass.setTexture(ALL, "Blocks:Dirt Grass")
    water = scene.voxels.blocks:new("Water")
    water.setTexture(ALL, "Blocks:Water")
    snow = scene.voxels.blocks:new("Snow")
    snow.setTexture(ALL, "Blocks:Snow")
    grass = scene.voxels.blocks:new("Grass Top")
    grass.setTexture(ALL, "Blocks:Grass Top")
    
    scene.voxels.visibleRadius=40
    scene.voxels:resize(vec3(30,1,30))          
    scene.voxels.coordinates = vec3(100,0,100) 

    offsetX=math.random(500)
    offsetZ=math.random(500)   
    dirtLevel=math.random(70,90)
    grassLevel=math.random(40,60)
    waterLevel=math.random(5,15)
    
    print("offsetX    "..offsetX)
    print("offsetZ    "..offsetZ)
    print("dirtLevel  "..dirtLevel)
    print("grassLevel "..grassLevel)
    print("waterLevel "..waterLevel)
    
    val=600
    m=1/val
    h=craft.noise.perlin()
    xx=0 
    for x=1,val do
        xx=xx+m
        zz=0
        for z=1,val do  
            zz=zz+m
            y=math.abs(h:getValue(xx+offsetX,0,zz+offsetZ))*158//1
            if y>127 then
                y=127-(y-127)
            end
            if y>=dirtLevel then
                scene.voxels:fill("Snow")
                scene.voxels:block(x,y,z)
            elseif y>=grassLevel then
                scene.voxels:fill("DirtGrass")
                scene.voxels:block(x,y,z)
            elseif y>=waterLevel then
                scene.voxels:fill("Grass Top")
                scene.voxels:block(x,y,z)
            else
                scene.voxels:fill("Water")
                scene.voxels:block(x,waterLevel,z)
            end
            scene.voxels:block(x,y-1,z)
            scene.voxels:block(x,y-2,z)
        end
    end
end

function update(dt)
    scene:update(dt)
end

function draw()
    update(DeltaTime)
    scene:draw()
end

@dave1707 , I know that it happens because due to how the blocks are being set, they can sometimes be set one block higher than their neighbours, causing gaps.

@dave1707 @creator27 - just ran both your demos and can see what I think are some blocks incomplete. Not many and I can’t see a trend when I run the demo from @dave1707.

However, @Creator27 demo crashes my iPad in v3 and V4. By remming out calls it would appear to be in the generateVoxels() function.

@john @sim posted an error report but after several crashes the error report dialogue didn’t pop up.

In those cases, the code needs to fill the blank spots with a Voxel. I’m just wondering if that can be coded for and can the condition be known.

@dave1707 , it’s okay I solved it by placing a block in the same position as the block that has just been generated except that it’s one block below.

That’s one way to fix it, maybe the only way without adding a lot of code. That’s also adding a lot more voxels. I isolated one of the blank spots in my code and determined it’s the perlin code that’s causing the problem. Wherever there’s a blank spot, the perlin “y” value isn’t a smooth transition compared to the points around it. Multiplying by some number just increases the problem and pushes the Voxel one level higher.

I added code to draw a Voxel 1 level down to my code. That cut down the blank spots, but sometime there’s still a few blank spots. Looking at the voxels, it might need a Voxel to be drawn 2 levels down.

Edit: Added 2 lines of code to my program above to draw a Voxel -1 and -2 levels down to fix the blank problem.

If it’s of any interest, I did a bunch of messing around with @dave1707 ’s terrain on my own.

The project needs the included JoystickPlayer project as a dependency to run.

Voxel and Vertex Terrain.zip (358.5 KB)
Joystick Player.zip (871.7 KB)