WIP: feat(scene) initial beauty baseline — terrain textures, sky, foam, mist, foliage, shadows
- Add 3 Terrain3D texture assets (limestone, valley grass, warm soil) - Sculpt initial Terrain3D heightmap with ridge, valley, waterfall drop - Replace plain water with emissive-tinged material - Add foam mesh, mist spheres, and procedural sky with valley fog - Add 10 StylizedTree instances around village perimeter - Enable directional light shadows with extended cascade range - Add tree height snapping to terrain surface - Add refined scaffold tests for material count, terrain height, foliage, sky, fog - Add terrain texture PNGs and StylizedTree.tscn scene - Add generate_jajce_terrain.gd tool
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
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)
|
||||
|
||||
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)
|
||||
Reference in New Issue
Block a user