descriptions somewhere on terrain gen?

I’m guessing that the radius value is controlling the round look. Just guessing.

Reading the voxel terrain example of @John I see a setBounds(a,b) (in blend2D) that is not defined in the docs. I see (in flatten) that noise.scale takes x, y, z, presumably the scale. I don’t know if that could have been set with the usual setX operations or not. It’s not documented.

I’d love to understand this well enough to help document it but so far I’m still at sea.

ALSO I’ve seen at least one case of changing the code without effect (commented out tree generation only to see trees appear in the next run). The run after that, no changes, also no trees. As if the module was cached or didn’t compile. Something cached in voxels and not cleared?

@RonJeffries Heres something I’m using to try and understand the terrain area.
Change the values of size, rad, posX,posZ to see what happens. I draw a brown grid and also a blue line along the x and z axis. Depending on the visible radius and terrain size, parts of the grid and axis will show.

displayMode(FULLSCREEN)

function setup()
    fill(255)
    assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")
    scene = craft.scene()    
    v=scene.camera:add(OrbitViewer,vec3(200,100,0), 600, 0, 10000)
    v.rx=45
    
    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") 
      
    size=30
    rad=13
    posX,posZ=200,200

    scene.voxels.visibleRadius=rad        -- visible terrain radius (rad * 16)
    scene.voxels:resize(vec3(size,1,size))  -- terrain area (size*16, 128, size*16)
    scene.voxels.coordinates = vec3(posX,0,posZ)  -- center of terrain area 
    
    scene.voxels:fill("DirtGrass")    
    for x=0,500,10 do   -- draw a grid of 500x500 blocks every 10 blocks
        scene.voxels:line(x,0,0,x,0,500)
        scene.voxels:line(0,0,x,500,0,x)
    end
    
    scene.voxels:fill("Water")    
    scene.voxels:line(0,0,0,500,0,0)    -- draw a blue line of blocks along the x axis
    scene.voxels:line(0,0,0,0,0,500)    -- draw a blue line of blocks along the y axis
end

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

function draw()
    update(DeltaTime)
    scene:draw()
    text("Terrain Size   "..size.." * 16 = "..size*16,WIDTH/2,HEIGHT-25)
    text("Visible Radius "..rad.." * 16 = "..rad*16,WIDTH/2,HEIGHT-50)
    text("Center at   "..posX.." , "..posZ,WIDTH/2,HEIGHT-75)
end

@RonJeffries Heres another version. Change the values for offset and waterLevel to see different things.

displayMode(FULLSCREEN)

function setup()
    assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")
    scene = craft.scene()    
    v=scene.camera:add(OrbitViewer,vec3(100,0,0), 300, 0, 10000)
    v.rx=30
    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")
    
    scene.voxels.visibleRadius=20
    scene.voxels:resize(vec3(30,1,30))          
    scene.voxels.coordinates = vec3(100,0,100)      

    offset=6
    waterLevel=2 
    val=200
    m=1/val
    h=craft.noise.perlin()

    xx,zz=0,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+offset,0,zz+offset))
            scene.voxels:fill("DirtGrass")
            scene.voxels:box(x,y*50//1-5,z,x,y*50//1,z)
            scene.voxels:fill("Water")
            scene.voxels:box(x,0,z,x,waterLevel,z)
        end
    end
end

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

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

Here’s another version. The more I play with it, the more I understand what’s happening. Alter the values for offsetX, offsetZ, and waterLevel, grassLevel, and dirtLevel.

displayMode(FULLSCREEN)

function setup()
    assert(OrbitViewer, "Please include Cameras (not Camera) as a dependency")
    scene = craft.scene()    
    v=scene.camera:add(OrbitViewer,vec3(100,0,0), 300, 0, 10000)
    v.rx=30
    sprite()
    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=20
    scene.voxels:resize(vec3(30,1,30))          
    scene.voxels.coordinates = vec3(100,0,100)      

    offsetX=3
    offsetZ=1
    dirtLevel=25
    grassLevel=10
    waterLevel=2
        
    val=200
    m=1/val
    h=craft.noise.perlin()

    xx,zz=0,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))*50//1
            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
        end
    end
end

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

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

verrrry interesting … are you seeing any pattern in what the offsets do? i’ve not discerned one. and your city-scape one was so flat with no noticeable continuity …
have you words yet for what you’re seeing?

ah.,if i do small offsets (a few 200ths) i can see the land slide over a bit. larger offsets are obvs sampling different areas, but i’ve not seen the pattern. hmm …

@RonJeffries Perlin noise is like static on an old TV screen except it’s always the same pattern for the same area. The output value is 0 for integer values of x,y,z . For fractional positions between integer values, you’ll always receive the same output, some plus or minus value, for the same input. So there will be a pattern over a large area.

ah, i see, didnt grok the xx zz. an integer change in offset samples a whole 'nother map, and we’re staying very close to home.

fun to fiddle with octaves etc now. nice, thanks, i think this will put some of john’s example into perspective. and i reckon generate can be considered nearly independently for threading and scale. probably. :slight_smile:

@RonJeffries Heres an example that shows perlin noise over an area. I’m using the absolute value from the perlin noise function. The darker the area, the closer it’s value to zero. The brighter the area, the higher the value. Slide the offset parameter to move the perlin area to the left.

displayMode(STANDARD)

function setup()
    parameter.integer("offset",0,50)
    val=5
    step=.2
    n=craft.noise.perlin()
end

function draw()
    background(0)
    for x=-val,val,step do
        for z=-val,val,step do
            y=n:getValue(x+offset,0,z)  
            y=math.abs(y)  
            fill(y*255)
            rect(x*80+WIDTH/2,z*80+HEIGHT/2,20)
        end
    end
end

thanks, interesting …

@dave1707

The output value is 0 for integer values of x,y,z

If I’m not mistaken, that’s true with frequency 0.5, the apparent default. A frequency like 0.73 or similar rando seems to have values at integer positions.

Most confusing, but slowly he learned …

Slowly I learned … step by step … inch by inch …

R

@RonJeffries Here something to play with. The output is 0 when the x,y,z values are integer values and multiples of 2.

displayMode(STANDARD)

function setup()
    fill(255)
    parameter.number("x",0,4,0)
    parameter.number("y",0,4,0)
    parameter.number("z",0,4,0)
    n = craft.noise.perlin()
end

function draw()
    background(0)
    value = n:getValue(x,y,z)
    text(value,WIDTH/2,HEIGHT/2)
end

yes, but now fuddle with n.frequency!

@dave1707 Pursuant to my question about whether anybody had made anything you could walk around in, I tried to take your terrain and make it something I could walk around in.

I just kind of did a hacky thing where I cut and pasted some code from the Voxel Terrain project, and it kind of works, kinda.

Unfortunately when I spawn the player, it turns all the blocks to water or ice. Or something blue.

After the player spawns you will have to press play to resume running, because for some reason it pauses. And it may look like all you see is blue, but if you swipe around you’ll eventually see sky also.


displayMode(FULLSCREEN)

function setup()
    assert(SEA_LEVEL, "Please include Voxel Terrain as a dependency")
    scene = craft.scene()    
    viewer=scene.camera:add(OrbitViewer,vec3(100,0,0), 300, 0, 10000)
    viewer.rx=30
    sprite()
    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=20
    scene.voxels:resize(vec3(30,1,30))          
    scene.voxels.coordinates = vec3(100,0,100)      
    
    offsetX=3
    offsetZ=1
    dirtLevel=25
    grassLevel=10
    waterLevel=2
    
    val=200
    m=1/val
    h=craft.noise.perlin()
    
    xx,zz=0,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))*50//1
            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
        end
    end
    
    -- Get a list of all loaded blocks
    allBlocks = scene.voxels.blocks:all()
    
    
    -- Spawn a player to explore the terrain
    parameter.action("Spawn Player", function()
        if viewer == nil then return end
        -- Use the current camera position as the target location to spawn the player
        local pos = vec3( viewer.target:unpack() )
        pos.y = 128
        
        -- Disable the initial viewer so it doesn't fight with the player one
        touches.removeHandler(viewer)
        scene.camera:remove(viewer)
        viewer = nil
        
        -- Get surface position using a raycast
        scene.voxels:raycast(pos, vec3(0,-1,0), 128, function(coord, id, face)
            if id and id ~= 0 then
                pos.y = coord.y + 2
                return true
            end
        end)
        
        -- Create a basic player 
        player = scene:entity():add(BasicPlayer, scene.camera:get(craft.camera), pos:unpack())
        
        -- Re-enable fog
        scene.fogEnabled = true
        
        -- Make the display fullscreen for first person mode
        viewer.mode = FULLSCREEN
        
        print("Project has paused, press play to resume.")
    end)

    --[[
    allBlocks = blocks()
    player = scene:entity():add(BasicPlayer, scene.camera:get(craft.camera), 40, 20, 40)
    ]]
end

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

function draw()
    update(DeltaTime)
    scene:draw()
if player then
    player:draw()
        end
end