96 lines
3.3 KiB
GDScript
96 lines
3.3 KiB
GDScript
extends SceneTree
|
|
|
|
const MAP_SIZE := 512
|
|
const HALF_SIZE := MAP_SIZE / 2
|
|
const HEIGHT_SCALE := 40.0
|
|
const DATA_DIRECTORY := "res://terrain/jajce/data"
|
|
const TEXTURE_DIRECTORY := "res://terrain/jajce/textures"
|
|
|
|
|
|
func _initialize() -> void:
|
|
call_deferred("_generate")
|
|
|
|
|
|
func _generate() -> void:
|
|
DirAccess.make_dir_recursive_absolute(ProjectSettings.globalize_path(TEXTURE_DIRECTORY))
|
|
_generate_texture("grass_albedo.png", Color("#516f36"), Color("#79924c"), 17)
|
|
_generate_texture("soil_albedo.png", Color("#65513b"), Color("#92734d"), 29)
|
|
_generate_texture("rock_albedo.png", Color("#55534f"), Color("#89847b"), 43)
|
|
_generate_neutral_normal()
|
|
|
|
var terrain := Terrain3D.new()
|
|
terrain.region_size = 256
|
|
root.add_child(terrain)
|
|
await process_frame
|
|
|
|
var height_map := Image.create_empty(MAP_SIZE, MAP_SIZE, false, Image.FORMAT_RF)
|
|
var noise := FastNoiseLite.new()
|
|
noise.seed = 1943
|
|
noise.frequency = 0.018
|
|
noise.fractal_octaves = 4
|
|
noise.fractal_gain = 0.45
|
|
|
|
for image_z in MAP_SIZE:
|
|
for image_x in MAP_SIZE:
|
|
var world_x := float(image_x - HALF_SIZE)
|
|
var world_z := float(image_z - HALF_SIZE)
|
|
var distance := Vector2(world_x, world_z).length()
|
|
var outside_play_area := smoothstep(20.0, 52.0, distance)
|
|
var ridge := 28.0 * _elliptical_peak(world_x, world_z, -72.0, 18.0, 72.0, 48.0)
|
|
var eastern_hill := 15.0 * _elliptical_peak(world_x, world_z, 105.0, 65.0, 110.0, 90.0)
|
|
var southern_hill := (
|
|
11.0 * _elliptical_peak(world_x, world_z, -35.0, -125.0, 130.0, 85.0)
|
|
)
|
|
var river_trench := -5.0 * exp(-pow((world_x - 25.0) / 18.0, 2.0))
|
|
var broad_slope := maxf(0.0, (-world_x - 30.0) * 0.035)
|
|
var detail := noise.get_noise_2d(world_x, world_z) * 2.4
|
|
var height := (
|
|
(ridge + eastern_hill + southern_hill + river_trench + broad_slope + detail)
|
|
* outside_play_area
|
|
)
|
|
height_map.set_pixel(image_x, image_z, Color(height / HEIGHT_SCALE, 0.0, 0.0, 1.0))
|
|
|
|
terrain.data.import_images(
|
|
[height_map, null, null], Vector3(-HALF_SIZE, 0.0, -HALF_SIZE), 0.0, HEIGHT_SCALE
|
|
)
|
|
terrain.data.save_directory(DATA_DIRECTORY)
|
|
print("[TerrainGenerator] Generated bounded Jajce terrain and textures")
|
|
quit(0)
|
|
|
|
|
|
func _elliptical_peak(
|
|
x: float, z: float, center_x: float, center_z: float, width: float, depth: float
|
|
) -> float:
|
|
return exp(-(pow((x - center_x) / width, 2.0) + pow((z - center_z) / depth, 2.0)))
|
|
|
|
|
|
func _generate_texture(
|
|
file_name: String, dark_color: Color, light_color: Color, seed_value: int
|
|
) -> void:
|
|
var noise := FastNoiseLite.new()
|
|
noise.seed = seed_value
|
|
noise.frequency = 0.035
|
|
noise.fractal_octaves = 3
|
|
var image := Image.create_empty(256, 256, false, Image.FORMAT_RGBA8)
|
|
for y in image.get_height():
|
|
for x in image.get_width():
|
|
var value := noise.get_noise_2d(x, y) * 0.5 + 0.5
|
|
var color := dark_color.lerp(light_color, value)
|
|
color.a = value
|
|
image.set_pixel(x, y, color)
|
|
image.generate_mipmaps()
|
|
var path := TEXTURE_DIRECTORY.path_join(file_name)
|
|
var error := image.save_png(path)
|
|
if error != OK:
|
|
push_error("Could not write terrain texture: " + path)
|
|
|
|
|
|
func _generate_neutral_normal() -> void:
|
|
var image := Image.create_empty(256, 256, false, Image.FORMAT_RGBA8)
|
|
image.fill(Color(0.5, 0.5, 1.0, 0.86))
|
|
image.generate_mipmaps()
|
|
var path := TEXTURE_DIRECTORY.path_join("neutral_normal.png")
|
|
var error := image.save_png(path)
|
|
if error != OK:
|
|
push_error("Could not write terrain normal texture: " + path)
|