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.
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.