Adds bushes and flowers to ground tiles
Implements bush and flower spawning on ground tiles based on vegetation density. Adds new assets for bushes and flowers, and introduces multi-mesh rendering for optimized performance. Introduces seasonal color variations for vegetation using a shader for bushes and materials for flowers and grass. Refactors material application into a MaterialManager to handle material assignments over multiple frames. Moves ground tile scripts into a subfolder. Adds floating particles to test scene.
This commit is contained in:
parent
ea5006e8a2
commit
3959333534
46 changed files with 559 additions and 77 deletions
|
|
@ -3,48 +3,44 @@ extends Node
|
|||
|
||||
var tree_collection = preload("res://Entities/Tree/Resources/TreeData.tres") as TreeDataCollection
|
||||
var tree_materials: Dictionary = {}
|
||||
var grass_materials: Dictionary = {"spring": {"base": Vector3(0.196, 0.392, 0.196), "top": Vector3(0.253, 0.492, 0.253), "bottom": Vector3(0.196, 0.392, 0.196)},
|
||||
"summer": {"base": null, "top": null, "bottom": null},
|
||||
"autumn": {"base": null, "top": null, "bottom": null},
|
||||
"winter": {"base": null, "top": null, "bottom": null}}
|
||||
|
||||
|
||||
## TODO - Move this out into its own class
|
||||
var material_application_queue: Array = []
|
||||
var max_materials_per_frame: int = 10 # Adjust based on performance
|
||||
var grass_materials: Dictionary = {
|
||||
"spring": {
|
||||
"bottom": Color(0.18, 0.35, 0.12), # #2e5920 - Dark forest base
|
||||
"top": Color(0.18, 0.35, 0.12), # Color(0.35, 0.65, 0.25), # #59a640 - Bright spring green
|
||||
"base": Color(0.12, 0.25, 0.08), # #1f4014 - Deep shadow green
|
||||
"flower": Color(0.776, 0.835, 0.855) # rgb(198, 213, 218) - Spring flower color
|
||||
},
|
||||
"summer": {
|
||||
"bottom": Color(0.22, 0.45, 0.18), # #38732e - Rich summer base
|
||||
"top": Color(0.22, 0.45, 0.18), # Color(0.4, 0.75, 0.3), # #66bf4d - Sun-kissed green
|
||||
"base": Color(0.15, 0.3, 0.12), # #264d1f - Shaded summer base
|
||||
"flower": Color(0.408, 0.537, 0.886) # rgb(104, 137, 226) - Summer flower color
|
||||
},
|
||||
"autumn": {
|
||||
"bottom": Color(0.35, 0.4, 0.15), # #596626 - Yellowing grass
|
||||
"top": Color(0.42, 0.45, 0.19), # #6b7330 - Muted autumn tips
|
||||
"base": Color(0.25, 0.25, 0.1), # #40401a - Dying grass base
|
||||
"flower": Color(0.820, 0.337, 0.318) # rgb(209, 86, 81) - Autumn flower color
|
||||
},
|
||||
"winter": {
|
||||
"bottom": Color(0.25, 0.3, 0.2), # #404d33 - Dormant green-brown
|
||||
"top": Color(0.35, 0.4, 0.3), # #59664d - Frost-touched tips
|
||||
"base": Color(0.2, 0.2, 0.15), # #333326 - Winter soil color
|
||||
"flower": Color(1.0, 0.8, 0.6) # #ffd9b3 - Winter flower color
|
||||
}
|
||||
}
|
||||
var bush_materials: Dictionary = {}
|
||||
var flower_materials: Dictionary = {}
|
||||
|
||||
@export var tree_colours: Array
|
||||
|
||||
func _ready() -> void:
|
||||
populate_tree_colors()
|
||||
Log.pr("Tree colors populated: %d trees" % tree_materials.size())
|
||||
|
||||
func _process(_delta):
|
||||
# Process material applications gradually over multiple frames
|
||||
process_material_queue()
|
||||
|
||||
func process_material_queue():
|
||||
var processed = 0
|
||||
while material_application_queue.size() > 0 and processed < max_materials_per_frame:
|
||||
var task = material_application_queue.pop_front()
|
||||
|
||||
# Check if the mesh instance is still valid before applying
|
||||
if is_instance_valid(task.mesh_instance) and task.mesh_instance != null:
|
||||
apply_material_immediately(task.mesh_instance, task.surface_index, task.material)
|
||||
# If invalid, just skip this task (object was freed)
|
||||
|
||||
processed += 1
|
||||
|
||||
func queue_material_application(mesh_instance: MeshInstance3D, surface_index: int, material: StandardMaterial3D):
|
||||
material_application_queue.append({
|
||||
"mesh_instance": mesh_instance,
|
||||
"surface_index": surface_index,
|
||||
"material": material
|
||||
})
|
||||
|
||||
func apply_material_immediately(mesh_instance: MeshInstance3D, surface_index: int, material: StandardMaterial3D):
|
||||
if is_instance_valid(mesh_instance):
|
||||
mesh_instance.set_surface_override_material(surface_index, material)
|
||||
populate_bush_materials()
|
||||
Log.pr("Bush materials populated: %d seasons" % bush_materials.size())
|
||||
populate_flower_materials()
|
||||
Log.pr("Flower materials populated: %d seasons" % flower_materials.size())
|
||||
|
||||
# Create materials once at startup
|
||||
func populate_tree_colors() -> void:
|
||||
|
|
@ -117,3 +113,53 @@ func get_random_trunk_material(tree_name: String, season: String) -> StandardMat
|
|||
return trunk_materials[random_key]
|
||||
|
||||
return create_material(Color(0.6, 0.4, 0.2), "fallback_trunk")
|
||||
|
||||
func populate_bush_materials() -> void:
|
||||
for season in Season.seasons:
|
||||
bush_materials[season] = {
|
||||
"1": create_bush_material(grass_materials[season]["base"], grass_materials[season]["flower"].lightened(0.1), "bush_base_%s" % season)
|
||||
}
|
||||
Log.pr("Bush materials populated for seasons: %s" % bush_materials.keys())
|
||||
|
||||
func create_bush_material(color: Color, variation: Color, material_name: String) -> ShaderMaterial:
|
||||
var material = ShaderMaterial.new()
|
||||
|
||||
var shader = load("res://leaves.gdshader")
|
||||
|
||||
material.shader = shader
|
||||
material.resource_name = material_name
|
||||
|
||||
material.set_shader_parameter("base_color", color)
|
||||
material.set_shader_parameter("variation_color", variation)
|
||||
|
||||
return material
|
||||
|
||||
func get_random_bush_material(season: String) -> ShaderMaterial:
|
||||
if bush_materials.has(season):
|
||||
var bush_materials_season = bush_materials[season]
|
||||
var material_keys = bush_materials_season.keys()
|
||||
if material_keys.size() > 0:
|
||||
var random_key = material_keys[randi() % material_keys.size()]
|
||||
return bush_materials_season[random_key]
|
||||
|
||||
Log.pr("No bush materials found for season: %s, returning fallback." % season)
|
||||
return create_bush_material(Color.GREEN, Color.GREEN, "fallback_bush")
|
||||
|
||||
func populate_flower_materials() -> void:
|
||||
for season in Season.seasons:
|
||||
flower_materials[season] = {
|
||||
"flower": create_material(grass_materials[season]['flower'], "flower_base_%s" % season),
|
||||
"stem": create_material(grass_materials[season]["top"], "flower_stem_%s" % season),
|
||||
}
|
||||
Log.pr("Flower materials populated for seasons: %s" % flower_materials.keys())
|
||||
|
||||
func get_random_flower_material(season: String) -> StandardMaterial3D:
|
||||
if flower_materials.has(season):
|
||||
var flower_materials_season = flower_materials[season]
|
||||
var material_keys = flower_materials_season.keys()
|
||||
if material_keys.size() > 0:
|
||||
var random_key = material_keys[randi() % material_keys.size()]
|
||||
return flower_materials_season[random_key]
|
||||
|
||||
Log.pr("No flower materials found for season: %s, returning fallback." % season)
|
||||
return create_material(Color(1.0, 1.0, 0.5), "fallback_flower")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue