feat(environment): add painterly skies and living meadows

This commit is contained in:
Rijad Zuzo
2026-09-05 20:27:09 +02:00
parent 7899d36f03
commit ec16e2f2ca
71 changed files with 2280 additions and 213 deletions
+33 -51
View File
@@ -7,15 +7,20 @@ enum CanopyVariant {
}
const COLORS := {
CanopyVariant.GREEN: Color(0.32, 0.51, 0.29),
CanopyVariant.DARK_GREEN: Color(0.22, 0.41, 0.30),
CanopyVariant.YELLOW_GREEN: Color(0.49, 0.60, 0.28),
CanopyVariant.GREEN: Color(0.40, 0.62, 0.28),
CanopyVariant.DARK_GREEN: Color(0.26, 0.51, 0.34),
CanopyVariant.YELLOW_GREEN: Color(0.55, 0.67, 0.29),
}
const TREE_MODEL := preload("res://assets/painterly/painterly_tree.glb")
const WIND_SHADER := preload("res://world/jajce/materials/wind.gdshader")
const WIND_STRENGTH := 0.07
const WIND_SPEED := 0.55
static var _canopy_mesh: Mesh
static var _trunk_mesh: Mesh
static var _bark_material: StandardMaterial3D
func _ready() -> void:
for child in get_children():
@@ -28,76 +33,56 @@ func _ready() -> void:
var canopy_radius := 1.25 + rng.randf() * 0.6
var wind_phase := rng.randf_range(0.0, TAU)
var trunk_mesh := CylinderMesh.new()
trunk_mesh.top_radius = 0.22
trunk_mesh.bottom_radius = 0.32
trunk_mesh.height = 3.4
trunk_mesh.radial_segments = 9
var trunk_mat := StandardMaterial3D.new()
trunk_mat.albedo_color = Color(0.27, 0.16, 0.09)
trunk_mat.roughness = 0.95
trunk_mesh.material = trunk_mat
_ensure_shared_meshes()
var trunk := MeshInstance3D.new()
trunk.name = "Trunk"
trunk.mesh = trunk_mesh
trunk.position = Vector3(0, 1.7, 0)
trunk.mesh = _trunk_mesh
trunk.material_override = _bark_material
add_child(trunk)
_add_branch(Vector3(-0.18, 2.45, 0.0), Vector3(0.0, 0.0, 42.0), 1.45, trunk_mat)
_add_branch(Vector3(0.2, 2.6, 0.08), Vector3(24.0, 0.0, -38.0), 1.25, trunk_mat)
var canopy_color: Color = COLORS[canopy_variant]
var crown_height := 3.7 + (canopy_radius - 1.2) * 0.45
_add_canopy(
"Canopy",
Vector3(0.0, crown_height, 0.0),
Vector3(canopy_radius * 1.12, canopy_radius, canopy_radius),
Vector3(canopy_radius * 1.18, canopy_radius * 0.96, canopy_radius * 1.05),
canopy_color,
wind_phase
)
_add_canopy(
"CanopyLeft",
Vector3(-0.82, crown_height - 0.15, 0.1),
Vector3(canopy_radius * 0.78, canopy_radius * 0.72, canopy_radius * 0.76),
Vector3(-0.94, crown_height - 0.27, 0.14),
Vector3(canopy_radius * 0.84, canopy_radius * 0.79, canopy_radius * 0.84),
canopy_color.lightened(0.05),
wind_phase + 0.12
)
_add_canopy(
"CanopyRight",
Vector3(0.78, crown_height - 0.05, -0.12),
Vector3(canopy_radius * 0.74, canopy_radius * 0.68, canopy_radius * 0.72),
Vector3(0.91, crown_height - 0.08, -0.2),
Vector3(canopy_radius * 0.82, canopy_radius * 0.73, canopy_radius * 0.79),
canopy_color.darkened(0.04),
wind_phase - 0.1
)
_add_canopy(
"CanopyTop",
Vector3(0.08, crown_height + 0.72, 0.04),
Vector3(canopy_radius * 0.72, canopy_radius * 0.66, canopy_radius * 0.7),
Vector3(0.13, crown_height + 0.68, -0.08),
Vector3(canopy_radius * 0.78, canopy_radius * 0.74, canopy_radius * 0.75),
canopy_color.lightened(0.08),
wind_phase + 0.05
)
func _add_branch(
branch_position: Vector3,
branch_rotation_degrees: Vector3,
branch_height: float,
material: StandardMaterial3D
) -> void:
var mesh := CylinderMesh.new()
mesh.top_radius = 0.08
mesh.bottom_radius = 0.14
mesh.height = branch_height
mesh.radial_segments = 7
mesh.material = material
var branch := MeshInstance3D.new()
branch.name = "Branch"
branch.mesh = mesh
branch.position = branch_position
branch.rotation_degrees = branch_rotation_degrees
add_child(branch)
static func _ensure_shared_meshes() -> void:
if _canopy_mesh != null:
return
var source := TREE_MODEL.instantiate()
_canopy_mesh = (source.find_child("Canopy", true, false) as MeshInstance3D).mesh
_trunk_mesh = (source.find_child("Trunk", true, false) as MeshInstance3D).mesh
_bark_material = StandardMaterial3D.new()
_bark_material.vertex_color_use_as_albedo = true
_bark_material.roughness = 0.95
_bark_material.specular_mode = BaseMaterial3D.SPECULAR_DISABLED
source.free()
func _add_canopy(
@@ -107,11 +92,6 @@ func _add_canopy(
canopy_color: Color,
wind_phase: float
) -> void:
var mesh := SphereMesh.new()
mesh.radius = 1.0
mesh.height = 2.0
mesh.radial_segments = 12
mesh.rings = 6
var material := ShaderMaterial.new()
material.shader = WIND_SHADER
material.set_shader_parameter("albedo", canopy_color)
@@ -119,10 +99,12 @@ func _add_canopy(
material.set_shader_parameter("wind_strength", WIND_STRENGTH)
material.set_shader_parameter("wind_speed", WIND_SPEED)
material.set_shader_parameter("wind_phase", wind_phase)
mesh.material = material
material.set_shader_parameter("painted_vertex_weight", 1.0)
var canopy := MeshInstance3D.new()
canopy.name = canopy_name
canopy.mesh = mesh
canopy.mesh = _canopy_mesh
canopy.material_override = material
canopy.position = canopy_position
canopy.scale = canopy_scale
canopy.rotation.y = wind_phase * 0.43 + canopy_position.x * 0.31
add_child(canopy)