Open skalimoi opened 1 year ago
Currently you can do that with some terrain configuration, and either a script generator or a graph.
This is not something provided by VoxelGeneratorImage
currently. Generally, you will often want to use a scripted or graph generator anyways, because the basic ones are, well, basic. They serve as example or testing, and can't provide all the details a full game would need.
Assuming you want smooth terrain, with a script you can implement a VoxelGeneratorScript
which populates the SDF channel of voxels with the distance field of the heightmap (which could be an image or anything that takes 2D coordinates and returns a height). Heightmap distance field can usually be simplified like this (pseudocode):
func _generate_block(buffer: VoxelBuffer, origin_in_voxels: Vector3i, lod: int):
var quantization_scale := 0.01
for z in buffer.get_size().x:
for x in buffer.get_size().z:
var world_position_2d := Vector2i(
origin_in_voxels.x + (x << lod),
origin_in_voxels.z + (z << lod))
var world_height := <code to get height from world_position_2d>
for y in buffer.get_size().y:
var world_y := origin_in_voxels.y + (y << lod)
var signed_distance := world_y - world_height
buffer.set_voxel_f(signed_distance * quantization_scale,
x, y, z, VoxelBuffer.CHANNEL_SDF)
If the source is an Image
, then <code to get height from world_position_2d>
will need to contain some code that uses get_pixel
, possibly with linear interpolation (if you want to stretch a smaller image), and does some scaling, clamping of coordinates at the border and whatnot.
A similar result can be achieved with a VoxelGeneratorGraph
, which has an Image
node, though it will repeat the image if input coordinates aren't clamped in some way.
By default, the terrain system is streamed and "infinite" by defaulting to very large bounds. You could then make it so empty space (SDF=1) is returned outside the bounds of the image in your generator, but you can also tell the terrain to have fixed bounds by reducing them in the inspector. Just note that such bounds must be a multiple of the biggest LOD chunk size. In VoxelTerrain
that will be 16, and in VoxelLodTerrain
it will be larger depending how many LODs you have.
Thanks a lot for the superb response, Zylann. I guess I'll tinker a bit with the Graph (which I just discovered) since I didn't know the basic generators weren't prepared for complex use cases, though it makes a lot of sense!
Hey there,
The docs say that
VoxelGeneratorImage
generates a map from an image, infinitely, by repeating the image over and over.I want to generate a finite map, that is, not repeating the image. Is this possible?
Say I'd want a finite 64000 x 64000 unit map - the ideal case would be for the provided heightmap to stretch to that size, or whatever it is.