Improved world generation:

- Taller trees with more leaves
- Terraces
- Water ponds
- Dead shrubs
master
Marc Gilleron 2020-08-05 20:11:16 +01:00
parent f2eeb2c6c7
commit e17d36ff18
5 changed files with 64 additions and 23 deletions

View File

@ -3,6 +3,7 @@ extends VoxelGenerator
const Structure = preload("./structure.gd")
const TreeGenerator = preload("./tree_generator.gd")
const HeightmapCurve = preload("./heightmap_curve.tres")
# TODO Don't hardcode, get by name from library somehow
const AIR = 0
@ -13,6 +14,7 @@ const WATER_TOP = 13
const LOG = 4
const LEAVES = 25
const TALL_GRASS = 8
const DEAD_SHRUB = 26
#const STONE = 8
const _CHANNEL = VoxelBuffer.CHANNEL_TYPE
@ -31,8 +33,8 @@ const _moore_dirs = [
var _tree_structures := []
var _heightmap_min_y := -32
var _heightmap_max_y := 64
var _heightmap_min_y := int(HeightmapCurve.min_value)
var _heightmap_max_y := int(HeightmapCurve.max_value)
var _heightmap_range := 0
var _heightmap_noise := OpenSimplexNoise.new()
var _trees_min_y := 0
@ -96,21 +98,36 @@ func generate_block(buffer: VoxelBuffer, origin_in_voxels: Vector3, lod: int):
gx = int(origin_in_voxels.x)
for x in block_size:
var h := _get_height_at(gx, gz)
var rh := h - oy
if rh > block_size:
var height := _get_height_at(gx, gz)
var relative_height := height - oy
# Dirt and grass
if relative_height > block_size:
buffer.fill_area(DIRT,
Vector3(x, 0, z), Vector3(x + 1, block_size, z + 1), _CHANNEL)
elif rh > 0:
elif relative_height > 0:
buffer.fill_area(DIRT,
Vector3(x, 0, z), Vector3(x + 1, rh, z + 1), _CHANNEL)
if h > 0:
buffer.set_voxel(GRASS, x, rh - 1, z, _CHANNEL)
if rh < block_size and rng.randf() < 0.2:
buffer.set_voxel(TALL_GRASS, x, rh, z, _CHANNEL)
# TODO Tall grass
Vector3(x, 0, z), Vector3(x + 1, relative_height, z + 1), _CHANNEL)
if height >= 0:
buffer.set_voxel(GRASS, x, relative_height - 1, z, _CHANNEL)
if relative_height < block_size and rng.randf() < 0.2:
var foliage = TALL_GRASS
if rng.randf() < 0.1:
foliage = DEAD_SHRUB
buffer.set_voxel(foliage, x, relative_height, z, _CHANNEL)
# Water
if height < 0 and oy < 0:
var start_relative_height := 0
if relative_height > 0:
start_relative_height = relative_height
buffer.fill_area(WATER_FULL,
Vector3(x, start_relative_height, z),
Vector3(x + 1, block_size, z + 1), _CHANNEL)
if oy + block_size == 0:
# Surface block
buffer.set_voxel(WATER_TOP, x, block_size - 1, z, _CHANNEL)
gx += 1
@ -168,5 +185,5 @@ static func get_chunk_seed_2d(cpos: Vector3) -> int:
func _get_height_at(x: int, z: int) -> int:
return int(_heightmap_min_y + _heightmap_range \
* (0.5 + 0.5 * _heightmap_noise.get_noise_2d(x, z)))
var t = 0.5 + 0.5 * _heightmap_noise.get_noise_2d(x, z)
return int(HeightmapCurve.interpolate_baked(t))

View File

@ -0,0 +1,6 @@
[gd_resource type="Curve" format=2]
[resource]
min_value = -32.0
max_value = 96.0
_data = [ Vector2( 0, -32 ), 0.0, 38.2641, 0, 0, Vector2( 0.357923, 5.05263 ), 123.284, 123.284, 0, 0, Vector2( 0.387978, 12.9123 ), 80.4028, 80.4028, 0, 0, Vector2( 0.532787, 24.1404 ), 80.1849, 80.1849, 0, 0, Vector2( 0.551913, 37.614 ), 61.6421, 61.6421, 0, 0, Vector2( 0.713115, 47.7193 ), 83.0877, 83.0877, 0, 0, Vector2( 0.754098, 80.2807 ), 110.784, 110.784, 0, 0, Vector2( 1, 96 ), 20.0462, 0.0, 0, 0 ]

View File

@ -2,12 +2,13 @@ extends Node
const Generator = preload("./generator.gd")
const Util = preload("res://common/util.gd")
const VoxelLibraryResource = preload("../blocks/voxel_library.tres")
const _materials = [
preload("../blocks/terrain_material.tres"),
preload("../blocks/terrain_material_foliage.tres"),
preload("../blocks/terrain_material_transparent.tres")
preload("../blocks/terrain_material_transparent.tres"),
preload("../blocks/terrain_material_foliage.tres")
]
@ -20,6 +21,12 @@ var _generator = Generator.new()
func _ready():
VoxelLibraryResource.bake()
_generate()
var wireframe = Util.create_wirecube_mesh()
var wireframe_instance = MeshInstance.new()
wireframe_instance.mesh = wireframe
wireframe_instance.scale = Vector3(16, 16, 16)
add_child(wireframe_instance)
func _input(event):
@ -40,6 +47,12 @@ func _input(event):
KEY_UP:
_origin.z += 16
_generate()
KEY_PAGEUP:
_origin.y += 16
_generate()
KEY_PAGEDOWN:
_origin.y -= 16
_generate()
func _generate():

View File

@ -8,4 +8,7 @@ script = ExtResource( 1 )
[node name="MeshInstance" type="MeshInstance" parent="."]
[node name="Camera" type="Camera" parent="."]
transform = Transform( 0.655427, 0.51168, -0.555516, 0, 0.735531, 0.677491, 0.755258, -0.444046, 0.482087, -4.3852, 14.6874, 18.075 )
transform = Transform( 0.655427, 0.511681, -0.555516, 0, 0.735531, 0.677491, 0.755258, -0.444046, 0.482087, -4.3852, 19.7889, 21.7283 )
[node name="DirectionalLight" type="DirectionalLight" parent="."]
transform = Transform( 0.976372, -0.108245, 0.187034, -0.0529668, 0.719227, 0.692753, -0.209507, -0.686291, 0.6965, 0, 0, 0 )

View File

@ -2,8 +2,8 @@
const Structure = preload("./structure.gd")
var trunk_len_min := 4
var trunk_len_max := 12
var trunk_len_min := 6
var trunk_len_max := 15
var log_type := 1
var leaves_type := 2
var channel := VoxelBuffer.CHANNEL_TYPE
@ -36,13 +36,15 @@ func generate() -> Structure:
# Leaves
var log_positions := voxels.keys()
log_positions.shuffle()
var leaf_count := len(log_positions) / 3
var leaf_count := int(0.75 * len(log_positions))
log_positions.resize(leaf_count)
var dirs := [
Vector3(-1, 0, 0),
Vector3(1, 0, 0),
Vector3(0, 0, -1),
Vector3(0, 0, 1)
Vector3(0, 0, 1),
Vector3(0, 1, 0),
Vector3(0, -1, 0)
]
for c in leaf_count:
var pos = log_positions[c]