Zylann / godot_voxel

Voxel module for Godot Engine
MIT License
2.62k stars 246 forks source link

How do I use the generator to generate advanced terrain #163

Closed KylaCpper closed 4 years ago

KylaCpper commented 4 years ago

For example, now I use a generator to generate a mountain range, Then I’m going to add trees or buildings on the mountain. Suppose the trees or buildings are too high and exceed 16 voxel What should i do, Should I use get_voxel_tool() to generate these trees and buildings?

Sorry, this may not be about a bug

Zylann commented 4 years ago

Assuming you use blocky voxels, this is a problem that gets discussed already around the internet I believe, with Minecraft clones being quite common. So you should be able to find information out there.

If you don't know how to generate things at all in the first place, look into implementing VoxelGenerator. There is an example of this linked by Tinmanjuggernaut, "custom stream": https://github.com/tinmanjuggernaut/voxelgame/tree/master/project/fps_demo This lets you receive the grid of voxels of a chunk and fill it in either with a bunch of set_voxel or with VoxelTool.

I don't have much time to explain the details of generation algorithm as this is an R&D subject for me as well, but mountain ranges and trees are two different kinds of problems.

Mountains are just a particular configuration of fractal noise (layers of perlin, simplex...) with a high range, which can get blended in particular spots using another kind of noise for biomes. These are continuous features that can be rasterized easily with noise algorithms per-voxel, so it's fine to do that chunk by chunk.

Structures like trees require more thought. One way I've been approaching it was to consider each block of 16x16 along the XZ plane can potentially be the source of a fixed amount of trees, determined by a random value seeded by the chunk's coordinates (i.e, like noise too). That means given a particular chunk, it's possible to tell which tree will grow from it, and which tree will grow from its neighbors. So based on the size of the structure, you'd calculate all tree origins from your chunk and its neighors, find those intersecting with the chunk, and rasterize them. This process is done for every chunk, and looks up more neighbors if the structure is larger. It's deterministic so trees will seamlessly align. No storage is needed for making this work, although you can cache things around to speed up things in some situations, for example if your structure is an entire city.

Yet again, there are plenty Minecraft clones, including open source ones like Minetest so you could even ask there to see how they deal with that.

KylaCpper commented 4 years ago

Assuming you use blocky voxels, this is a problem that gets discussed already around the internet I believe, with Minecraft clones being quite common. So you should be able to find information out there.

If you don't know how to generate things at all in the first place, look into implementing VoxelGenerator. There is an example of this linked by Tinmanjuggernaut, "custom stream": https://github.com/tinmanjuggernaut/voxelgame/tree/master/project/fps_demo This lets you receive the grid of voxels of a chunk and fill it in either with a bunch of set_voxel or with VoxelTool.

I don't have much time to explain the details of generation algorithm as this is an R&D subject for me as well, but mountain ranges and trees are two different kinds of problems.

Mountains are just a particular configuration of fractal noise (layers of perlin, simplex...) with a high range, which can get blended in particular spots using another kind of noise for biomes. These are continuous features that can be rasterized easily with noise algorithms per-voxel, so it's fine to do that chunk by chunk.

Structures like trees require more thought. One way I've been approaching it was to consider each block of 16x16 along the XZ plane can potentially be the source of a fixed amount of trees, determined by a random value seeded by the chunk's coordinates (i.e, like noise too). That means given a particular chunk, it's possible to tell which tree will grow from it, and which tree will grow from its neighbors. So based on the size of the structure, you'd calculate all tree origins from your chunk and its neighors, find those intersecting with the chunk, and rasterize them. This process is done for every chunk, and looks up more neighbors if the structure is larger. It's deterministic so trees will seamlessly align. No storage is needed for making this work, although you can cache things around to speed up things in some situations, for example if your structure is an entire city.

Yet again, there are plenty Minecraft clones, including open source ones like Minetest so you could even ask there to see how they deal with that.

How do I visit neighbors in the generate block? Is it to store all the neighbor's VoxelBuffer? Still store the neighbor's Voxel Buffer in a variable?

Zylann commented 4 years ago

How do I visit neighbors in the generate block?

You don't. You just take your current coordinates, offset them and query the seeded random numbers to know what would generate in the neighbors. This is possible because seeded randomness is deterministic: from set of coordinates, the same results will come up. So you can know about neighbor chunks, without actually accessing them, and without having to generate them entirely. That's one way, there are other ways but you must really know what you are doing.

Is it to store all the neighbor's VoxelBuffer? Still store the neighbor's Voxel Buffer in a variable?

They don't need to be stored.

If you're new to chunked procedural generation you may need more experience or a detailed example which I have yet to add to the demo project (or you can look at other projects on the web to see how the've done it).

KylaCpper commented 4 years ago

i get it