Improves tree and ground tile appearance

Refactors tree spawning and rendering:
- Adds seasonal color variations for trees via scripts.
- Introduces `ColorStorage` to manage tree and grass colors
- Removes unused code from tree spawning logic.
- Adjusts ground tile color for better visual appeal.
- Hides debug text on ground tiles.
This commit is contained in:
Dan Baker 2025-06-28 17:21:50 +01:00
parent 734730beee
commit ea5006e8a2
28 changed files with 454 additions and 63 deletions

View file

@ -11,8 +11,7 @@
viewport_path = NodePath("DebugText/DebugTextViewport")
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_f37ob"]
albedo_color = Color(0.133333, 0.576471, 0.47451, 1)
metallic = 1.0
albedo_color = Color(0.196078, 0.392157, 0.196078, 1)
[sub_resource type="PlaneMesh" id="PlaneMesh_oqd8f"]
@ -30,6 +29,7 @@ flip_faces = true
script = ExtResource("1_uwxqs")
[node name="DebugText" type="Node3D" parent="."]
visible = false
[node name="DebugTextViewport" type="SubViewport" parent="DebugText"]
size = Vector2i(50, 50)

View file

@ -9,6 +9,9 @@ var cell_info: CellDataResource = null
var spawners_ready: bool = false
var cached_rng: RandomClass = null
# 326432 229379
# Grass - 1a7761 1f6051
func _ready() -> void:
spawners_ready = true

View file

@ -65,50 +65,11 @@ func spawn_tree_at_position(pos: Vector3, tree_resource: TreeDataResource):
# Pass the TreeDataResource to the Tree instance
if tree_instance.has_method("set_tree_data"):
tree_instance.set_tree_data(tree_resource)
elif tree_instance.has_method("setup_tree"):
tree_instance.setup_tree(tree_resource)
else:
Log.pr("Tree instance doesn't have set_tree_data() or setup_tree() method")
Log.pr("Tree instance doesn't have set_tree_data() method")
func is_position_valid(pos: Vector3) -> bool:
for existing_pos in spawned_positions:
if pos.distance_to(existing_pos) < min_distance:
return false
return true
# Alternative method that shuffles trees for more random placement
func spawn_trees_shuffled(cell_info: CellDataResource):
if not cell_info:
return
if not parent_ground_tile:
return
# Clear existing trees
for child in get_children():
child.free()
spawned_positions.clear()
# Create a copy and shuffle for random placement order
var trees_to_spawn = cell_info.trees.duplicate()
trees_to_spawn.shuffle()
var spawned_count = 0
var attempts = 0
var max_attempts = trees_to_spawn.size() * 10
for tree_resource in trees_to_spawn:
if attempts >= max_attempts:
Log.pr("Reached max attempts, could only spawn %d of %d trees" % [spawned_count, trees_to_spawn.size()])
break
var pos = get_random_position()
if is_position_valid(pos):
spawn_tree_at_position(pos, tree_resource as TreeDataResource)
spawned_positions.append(pos)
spawned_count += 1
attempts += 1
Log.pr("Spawned %d of %d trees in cell (shuffled)" % [spawned_count, trees_to_spawn.size()])

BIN
Entities/Tree/assets/Textures/texture.png (Stored with Git LFS) Normal file

Binary file not shown.

View file

@ -0,0 +1,35 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dhajcn6k04poe"
path.s3tc="res://.godot/imported/texture.png-27d352bfc378434578d288ba141a0d45.s3tc.ctex"
metadata={
"imported_formats": ["s3tc_bptc"],
"vram_texture": true
}
[deps]
source_file="res://Entities/Tree/assets/Textures/texture.png"
dest_files=["res://.godot/imported/texture.png-27d352bfc378434578d288ba141a0d45.s3tc.ctex"]
[params]
compress/mode=2
compress/high_quality=false
compress/lossy_quality=0.7
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=true
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=0

View file

@ -4,12 +4,12 @@ importer="scene"
importer_version=1
type="PackedScene"
uid="uid://brabfdgw5vs1o"
path="res://.godot/imported/tree_pineDefaultA.glb-1f3fb96752d92654789d1e25d544e1b6.scn"
path="res://.godot/imported/tree_pineDefaultA.glb-5dac8705865b7821c88a664af5de372c.scn"
[deps]
source_file="res://Entities/Tree/assets/temp/tree_pineDefaultA.glb"
dest_files=["res://.godot/imported/tree_pineDefaultA.glb-1f3fb96752d92654789d1e25d544e1b6.scn"]
source_file="res://Entities/Tree/assets/tree_pineDefaultA.glb"
dest_files=["res://.godot/imported/tree_pineDefaultA.glb-5dac8705865b7821c88a664af5de372c.scn"]
[params]

View file

@ -1,11 +1,15 @@
[gd_resource type="Resource" script_class="TreeDataCollection" load_steps=11 format=3 uid="uid://buf5mtxc5f7o"]
[gd_resource type="Resource" script_class="TreeDataCollection" load_steps=15 format=3 uid="uid://buf5mtxc5f7o"]
[ext_resource type="Script" uid="uid://dj4dhsd0m0bvd" path="res://Entities/Tree/resources/TreeDataCollection.gd" id="1_7y4l8"]
[ext_resource type="Script" uid="uid://cdudelqysppwl" path="res://Entities/Tree/resources/TreeDataResource.gd" id="2_4yk3p"]
[ext_resource type="PackedScene" uid="uid://g74ar24o4s1" path="res://Entities/Tree/assets/tree_oak.glb" id="3_4yk3p"]
[ext_resource type="PackedScene" uid="uid://bwhpbjdyl577e" path="res://Entities/Tree/assets/tree.glb" id="4_4wxxs"]
[ext_resource type="Script" uid="uid://bjsj2j01nmnfq" path="res://Entities/Tree/scripts/color_tree_oak.gd" id="3_itox7"]
[ext_resource type="PackedScene" uid="uid://besaean4w1n83" path="res://Entities/Tree/assets/tree_birch.glb" id="5_35hba"]
[ext_resource type="Script" uid="uid://de77441cemrqe" path="res://Entities/Tree/scripts/color_tree_pine.gd" id="5_cyc7o"]
[ext_resource type="PackedScene" uid="uid://b3lc1nbuv5ol8" path="res://Entities/Tree/assets/tree_detailed.glb" id="6_ibfiw"]
[ext_resource type="PackedScene" uid="uid://brabfdgw5vs1o" path="res://Entities/Tree/assets/tree_pineDefaultA.glb" id="6_itox7"]
[ext_resource type="Script" uid="uid://dk04iuaocilih" path="res://Entities/Tree/scripts/color_tree_birch.gd" id="7_cyc7o"]
[ext_resource type="Script" uid="uid://3flh70jpmq2w" path="res://Entities/Tree/scripts/color_tree_elder.gd" id="9_dydvk"]
[sub_resource type="Resource" id="Resource_7y4l8"]
script = ExtResource("2_4yk3p")
@ -17,28 +21,44 @@ moisture_range = Vector2(0.3, 0.8)
elevation_range = Vector2(0.1, 0.5)
max_height = 15.0
growth_time = 120.0
spawn_probability = 0.1
spread_radius = 5.0
seasonal_models = Array[PackedScene]([])
drops_leaves = true
leaf_color_variations = Array[Color]([])
color_script = ExtResource("3_itox7")
spring_leaf_color = Color(0.419608, 0.556863, 0.137255, 1)
summer_leaf_color = Color(0.419608, 0.556863, 0.137255, 1)
autumn_leaf_color = Color(0.624662, 0.302547, 1.92523e-07, 1)
winter_leaf_color = Color(0.784314, 0.823529, 0.745098, 1)
spring_trunk_color = Color(0.627451, 0.321569, 0.176471, 1)
summer_trunk_color = Color(0.627451, 0.321569, 0.176471, 1)
autumn_trunk_color = Color(0.4, 0.2, 0.1, 1)
winter_trunk_color = Color(0.3, 0.2, 0.1, 1)
metadata/_custom_type_script = "uid://cdudelqysppwl"
[sub_resource type="Resource" id="Resource_35hba"]
script = ExtResource("2_4yk3p")
tree_name = "Pine"
model = ExtResource("4_4wxxs")
model = ExtResource("6_itox7")
growth_stages = Array[PackedScene]([])
temperature_range = Vector2(0.1, 0.6)
moisture_range = Vector2(0.2, 0.6)
elevation_range = Vector2(0.7, 1)
max_height = 15.0
growth_time = 120.0
spawn_probability = 0.1
spread_radius = 5.0
seasonal_models = Array[PackedScene]([])
drops_leaves = true
leaf_color_variations = Array[Color]([])
color_script = ExtResource("5_cyc7o")
spring_leaf_color = Color(0.196078, 0.501961, 0.196078, 1)
summer_leaf_color = Color(0.00392157, 0.196078, 0.12549, 1)
autumn_leaf_color = Color(0.133333, 0.376471, 0.168627, 1)
winter_leaf_color = Color(0.266667, 0.376471, 0.298039, 1)
spring_trunk_color = Color(0.396078, 0.262745, 0.129412, 1)
summer_trunk_color = Color(0.396078, 0.262745, 0.129412, 1)
autumn_trunk_color = Color(0.396078, 0.262745, 0.129412, 1)
winter_trunk_color = Color(0.313726, 0.207843, 0.101961, 1)
metadata/_custom_type_script = "uid://cdudelqysppwl"
[sub_resource type="Resource" id="Resource_4wxxs"]
@ -51,11 +71,19 @@ moisture_range = Vector2(0.5, 0.6)
elevation_range = Vector2(0.1, 0.5)
max_height = 15.0
growth_time = 120.0
spawn_probability = 0.1
spread_radius = 5.0
seasonal_models = Array[PackedScene]([])
drops_leaves = true
leaf_color_variations = Array[Color]([])
color_script = ExtResource("7_cyc7o")
spring_leaf_color = Color(0.678431, 0.933333, 0.466667, 1)
summer_leaf_color = Color(0.603922, 0.803922, 0.196078, 1)
autumn_leaf_color = Color(1, 0.843137, 0, 1)
winter_leaf_color = Color(0.898039, 0.917647, 0.823529, 1)
spring_trunk_color = Color(0.960784, 0.960784, 0.862745, 1)
summer_trunk_color = Color(0.960784, 0.960784, 0.862745, 1)
autumn_trunk_color = Color(0.960784, 0.960784, 0.862745, 1)
winter_trunk_color = Color(0.862745, 0.862745, 0.784314, 1)
metadata/_custom_type_script = "uid://cdudelqysppwl"
[sub_resource type="Resource" id="Resource_54eyh"]
@ -68,11 +96,19 @@ moisture_range = Vector2(0.7, 1)
elevation_range = Vector2(0, 0.2)
max_height = 15.0
growth_time = 120.0
spawn_probability = 0.1
spread_radius = 5.0
seasonal_models = Array[PackedScene]([])
drops_leaves = true
leaf_color_variations = Array[Color]([])
color_script = ExtResource("9_dydvk")
spring_leaf_color = Color(0.564706, 0.933333, 0.564706, 1)
summer_leaf_color = Color(0.196078, 0.803922, 0.196078, 1)
autumn_leaf_color = Color(0.545098, 0.270588, 0.0745098, 1)
winter_leaf_color = Color(0.627451, 0.666667, 0.627451, 1)
spring_trunk_color = Color(0.411765, 0.411765, 0.411765, 1)
summer_trunk_color = Color(0.411765, 0.411765, 0.411765, 1)
autumn_trunk_color = Color(0.411765, 0.411765, 0.411765, 1)
winter_trunk_color = Color(0.329412, 0.329412, 0.329412, 1)
metadata/_custom_type_script = "uid://cdudelqysppwl"
[resource]

View file

@ -14,10 +14,40 @@ extends Resource
@export_group("Growth Properties")
@export var max_height: float = 15.0
@export var growth_time: float = 120.0 # Seconds to full growth
@export var spawn_probability: float = 0.1
@export var spread_radius: float = 5.0
@export_group("Seasonal Behavior")
@export var seasonal_models: Array[PackedScene] = [] # Spring, Summer, Fall, Winter
@export var drops_leaves: bool = true
@export var leaf_color_variations: Array[Color] = []
@export_group("Tree Color Management")
@export var color_script: GDScript = null
@export_group("Leaf Colors")
@export var spring_leaf_color: Color = Color(0.0, 1.0, 0.0) # Green
@export var summer_leaf_color: Color = Color(0.0, 0.5, 0.0) # Darker green
@export var autumn_leaf_color: Color = Color(1.0, 0.5, 0.0) # Orange
@export var winter_leaf_color: Color = Color(0.5, 0.5, 0.5) # Gray/Brown
@export_group("Trunk Colors")
@export var spring_trunk_color: Color = Color(0.6, 0.4, 0.2) # Brown
@export var summer_trunk_color: Color = Color(0.5, 0.3, 0.1) # Darker brown
@export var autumn_trunk_color: Color = Color(0.4, 0.2, 0.1) # Darker brown
@export var winter_trunk_color: Color = Color(0.3, 0.2, 0.1) # Very dark brown
func apply_seasonal_colors(instance_model: Node3D, season: String = "summer") -> void:
if color_script == null:
return
var script_instance = color_script.new()
# Pass the tree name and season to the color script
if script_instance.has_method("set_tree_info"):
script_instance.set_tree_info(tree_name, season)
if script_instance.has_method("set_leaf_color"):
script_instance.set_leaf_color(instance_model)
if script_instance.has_method("set_trunk_color"):
script_instance.set_trunk_color(instance_model)

View file

@ -0,0 +1,108 @@
class_name TreeColorDefault
extends RefCounted
var tree_name: String = ""
var current_season: String = "summer"
var mesh_instances: Array[MeshInstance3D] = []
func set_tree_info(name: String, season: String):
tree_name = name
current_season = season
func set_leaf_color(model_instance: Node3D):
#Log.pr("Setting leaf color to: %s" % color)
pass
func set_trunk_color(model_instance: Node3D):
#Log.pr("Setting trunk color to: %s" % color)
pass
# Update a specific material by name with a new color
func update_material_by_name(root_node: Node, material_name: String, new_color: Color) -> bool:
var updated = false
for mesh_instance in mesh_instances:
if update_material_in_mesh_instance(mesh_instance, material_name, new_color):
updated = true
return updated
# Update multiple materials at once
func update_materials_by_names(root_node: Node, material_updates: Dictionary) -> Dictionary:
var results = {}
# Initialize results
for material_name in material_updates.keys():
results[material_name] = false
for mesh_instance in mesh_instances:
for material_name in material_updates.keys():
var new_color = material_updates[material_name]
if update_material_in_mesh_instance(mesh_instance, material_name, new_color):
results[material_name] = true
return results
# Get all material names from a model
func get_all_material_names(root_node: Node) -> Array[String]:
var material_names: Array[String] = []
for mesh_instance in mesh_instances:
var mesh = mesh_instance.mesh
if mesh:
for i in range(mesh.get_surface_count()):
var material = mesh.surface_get_material(i)
if material and material.resource_name:
if not material.resource_name in material_names:
material_names.append(material.resource_name)
return material_names
func update_material_by_name_with_material(root_node: Node, material_name: String, new_material: StandardMaterial3D) -> bool:
var updated = false
for mesh_instance in mesh_instances:
var mesh = mesh_instance.mesh
if mesh:
for i in range(mesh.get_surface_count()):
var current_material = mesh.surface_get_material(i)
if current_material and current_material.resource_name == material_name:
apply_material_with_queue(mesh_instance, i, new_material)
#mesh_instance.set_surface_override_material(i, new_material)
updated = true
#Log.pr("Updated material '%s' with pre-made material" % material_name)
return updated
# Helper function - find all mesh instances recursively
func find_all_mesh_instances(node: Node) -> Array[MeshInstance3D]:
if node is MeshInstance3D:
mesh_instances.append(node)
for child in node.get_children():
mesh_instances += find_all_mesh_instances(child)
return mesh_instances
# Helper function - update material in a specific mesh instance
func update_material_in_mesh_instance(mesh_instance: MeshInstance3D, material_name: String, new_color: Color) -> bool:
var updated = false
var mesh = mesh_instance.mesh
if mesh:
for i in range(mesh.get_surface_count()):
var material = mesh.surface_get_material(i)
if material and material.resource_name == material_name:
var new_material = material.duplicate()
new_material.albedo_color = new_color
mesh_instance.set_surface_override_material(i, new_material)
#Log.pr("Updated material '%s' to color: %s" % [material_name, new_color])
updated = true
return updated
func apply_material_with_queue(mesh_instance: MeshInstance3D, index: int, material: StandardMaterial3D):
ColorData.queue_material_application(mesh_instance, index, material)
return

View file

@ -0,0 +1 @@
uid://dmgn1sve22e8a

View file

@ -0,0 +1,19 @@
extends TreeColorDefault
func set_leaf_color(model_instance: Node3D):
find_all_mesh_instances(model_instance)
var material = ColorData.get_random_leaf_material(tree_name, current_season)
update_material_by_name_with_material(model_instance, "leafsGreen", material)
return
func set_trunk_color(model_instance: Node3D):
find_all_mesh_instances(model_instance)
var material = ColorData.get_random_trunk_material(tree_name, current_season)
update_material_by_name_with_material(model_instance, "woodBark", material)
return

View file

@ -0,0 +1 @@
uid://dk04iuaocilih

View file

@ -0,0 +1,19 @@
extends TreeColorDefault
func set_leaf_color(model_instance: Node3D):
find_all_mesh_instances(model_instance)
var material = ColorData.get_random_leaf_material(tree_name, current_season)
update_material_by_name_with_material(model_instance, "leafsGreen", material)
return
func set_trunk_color(model_instance: Node3D):
find_all_mesh_instances(model_instance)
var material = ColorData.get_random_trunk_material(tree_name, current_season)
update_material_by_name_with_material(model_instance, "woodBark", material)
return

View file

@ -0,0 +1 @@
uid://3flh70jpmq2w

View file

@ -0,0 +1,19 @@
extends TreeColorDefault
func set_leaf_color(model_instance: Node3D):
find_all_mesh_instances(model_instance)
var material = ColorData.get_random_leaf_material(tree_name, current_season)
update_material_by_name_with_material(model_instance, "leafsGreen", material)
return
func set_trunk_color(model_instance: Node3D):
find_all_mesh_instances(model_instance)
var material = ColorData.get_random_trunk_material(tree_name, current_season)
update_material_by_name_with_material(model_instance, "woodBark", material)
return

View file

@ -0,0 +1 @@
uid://bjsj2j01nmnfq

View file

@ -0,0 +1,19 @@
extends TreeColorDefault
func set_leaf_color(model_instance: Node3D):
find_all_mesh_instances(model_instance)
var material = ColorData.get_random_leaf_material(tree_name, current_season)
update_material_by_name_with_material(model_instance, "leafsDark", material)
return
func set_trunk_color(model_instance: Node3D):
find_all_mesh_instances(model_instance)
var material = ColorData.get_random_trunk_material(tree_name, current_season)
update_material_by_name_with_material(model_instance, "woodBark", material)
return

View file

@ -0,0 +1 @@
uid://de77441cemrqe

View file

@ -20,10 +20,6 @@ func set_tree_data(data: TreeDataResource):
tree_data = data
spawn_model()
func setup_tree(data: TreeDataResource):
# Alternative method name if you prefer
set_tree_data(data)
func spawn_model():
if not tree_data or not tree_data.model:
Log.pr("No tree data or model provided")
@ -37,7 +33,9 @@ func spawn_model():
# Instantiate the model from the TreeDataResource
model_instance = tree_data.model.instantiate()
tree_data.apply_seasonal_colors(model_instance, "spring")
add_child(model_instance)
# Create base circle after model is loaded
if not base_circle:
@ -45,6 +43,7 @@ func spawn_model():
# Re-scan for mesh instances in the new model
find_all_mesh_instances(model_instance)
update_outline_materials()
# Apply any additional properties from tree_data
@ -63,7 +62,7 @@ func apply_tree_properties():
var scale_variation = randf_range(0.8, 1.2)
model_instance.scale *= scale_variation
func setup_outline_material():
func setup_outline_material() -> void:
# Create outline material with your shader
outline_material = ShaderMaterial.new()
outline_material.shader = preload("res://outline.gdshader")

View file

@ -0,0 +1,119 @@
class_name ColorStorageClass
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
@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)
# Create materials once at startup
func populate_tree_colors() -> void:
for tree in tree_collection.trees:
Log.pr("Loading tree: %s" % tree.tree_name)
tree_materials[tree.tree_name] = {
"spring": {
"leaf": create_leaf_materials(tree.spring_leaf_color, "spring", tree.tree_name),
"trunk": create_trunk_materials(tree.spring_trunk_color, "spring", tree.tree_name)
},
"summer": {
"leaf": create_leaf_materials(tree.summer_leaf_color, "summer", tree.tree_name),
"trunk": create_trunk_materials(tree.summer_trunk_color, "summer", tree.tree_name)
},
"autumn": {
"leaf": create_leaf_materials(tree.autumn_leaf_color, "autumn", tree.tree_name),
"trunk": create_trunk_materials(tree.autumn_trunk_color, "autumn", tree.tree_name)
},
"winter": {
"leaf": create_leaf_materials(tree.winter_leaf_color, "winter", tree.tree_name),
"trunk": create_trunk_materials(tree.winter_trunk_color, "winter", tree.tree_name)
}
}
func create_leaf_materials(base_color: Color, season: String, tree_name: String) -> Dictionary:
var materials = {}
materials = {
"1": create_material(base_color, "%s_leaf_%s_primary" % [tree_name, season]),
"2": create_material(base_color.darkened(0.1), "%s_leaf_%s_secondary" % [tree_name, season]),
"3": create_material(base_color.lightened(0.1), "%s_leaf_%s_highlight" % [tree_name, season]),
"4": create_material(base_color.darkened(0.3), "%s_leaf_%s_shadow" % [tree_name, season])
}
return materials
func create_trunk_materials(base_color: Color, season: String, tree_name: String) -> Dictionary:
var materials = {}
materials = {
"1": create_material(base_color, "%s_trunk_%s_primary" % [tree_name, season]),
"2": create_material(base_color.darkened(0.2), "%s_trunk_%s_bark" % [tree_name, season]),
"3": create_material(Color(0.2, 0.4, 0.1), "%s_trunk_%s_moss" % [tree_name, season]),
"4": create_material(base_color.lightened(0.1), "%s_trunk_%s_highlight" % [tree_name, season])
}
return materials
func create_material(color: Color, material_name: String) -> StandardMaterial3D:
var material = StandardMaterial3D.new()
material.albedo_color = color
material.metallic = 0.0
material.roughness = 0.8
material.resource_name = material_name
return material
func get_random_leaf_material(tree_name: String, season: String) -> StandardMaterial3D:
if tree_materials.has(tree_name) and tree_materials[tree_name].has(season):
var leaf_materials = tree_materials[tree_name][season]["leaf"]
var material_keys = leaf_materials.keys()
if material_keys.size() > 0:
var random_key = material_keys[randi() % material_keys.size()]
return leaf_materials[random_key]
return create_material(Color.GREEN, "fallback_leaf")
func get_random_trunk_material(tree_name: String, season: String) -> StandardMaterial3D:
if tree_materials.has(tree_name) and tree_materials[tree_name].has(season):
var trunk_materials = tree_materials[tree_name][season]["trunk"]
var material_keys = trunk_materials.keys()
if material_keys.size() > 0:
var random_key = material_keys[randi() % material_keys.size()]
return trunk_materials[random_key]
return create_material(Color(0.6, 0.4, 0.2), "fallback_trunk")

View file

@ -0,0 +1 @@
uid://bbtdrg8ax8sca

10
falloff.gdshader Normal file
View file

@ -0,0 +1,10 @@
shader_type canvas_item;
uniform sampler2D gradient_fallof;
void light() {
float calculated_light_value = max(0.0, dot(NORMAL, LIGHT_DIRECTION));
float sample = clamp(calculated_light_value * LIGHT_ENERGY, 0.05, 0.95);
vec4 shaded_texture = texture(gradient_fallof, vec2(sample, 0));
LIGHT = vec4(LIGHT_COLOR.rgb * COLOR.rgb * shaded_texture.rgb, LIGHT_COLOR.a);
}

1
falloff.gdshader.uid Normal file
View file

@ -0,0 +1 @@
uid://ce7q2m8ux2l0j

View file

@ -23,6 +23,7 @@ DebugMenu="*res://addons/debug_menu/debug_menu.tscn"
MapGeneration="*res://Utilities/MapGeneration/MapGeneration.gd"
BiomeData="*res://Utilities/BiomeGeneration/BiomeData.gd"
MapData="*res://Utilities/MapData/MapData.gd"
ColorData="*res://Utilities/ColorStorage/ColorStorage.gd"
MapPopulation="*res://Utilities/MapData/MapPopulation.gd"
[editor_plugins]

View file

@ -1,14 +1,17 @@
[gd_resource type="ShaderMaterial" load_steps=3 format=3 uid="uid://b1miqvl8lus75"]
[gd_resource type="ShaderMaterial" load_steps=4 format=3 uid="uid://b1miqvl8lus75"]
[ext_resource type="Shader" uid="uid://dbduq0qcaxmyi" path="res://grass.gdshader" id="1_vnnwo"]
[sub_resource type="FastNoiseLite" id="FastNoiseLite_vnnwo"]
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_vnnwo"]
noise = SubResource("FastNoiseLite_vnnwo")
[resource]
render_priority = 0
shader = ExtResource("1_vnnwo")
shader_parameter/top_color = Color(0.102963, 0.465909, 0.382031, 1)
shader_parameter/bottom_color = Color(0.121494, 0.374954, 0.315972, 1)
shader_parameter/top_color = Color(0.252743, 0.492435, 0.25271, 1)
shader_parameter/bottom_color = Color(0.196078, 0.392157, 0.196078, 1)
shader_parameter/ambient_occlusion_factor = 0.0
shader_parameter/specular_strength = 0.0
shader_parameter/player_displacement_strength = 1.0

View file

@ -740,7 +740,7 @@ script = ExtResource("2_sdmks")
transform = Transform3D(1, 0, 0, 0, 1, -1.49012e-07, 0, 1.19209e-07, 1, 0.0410548, 0.237644, 3.45114)
projection = 1
current = true
size = 4.0
size = 3.0
near = 0.005
far = 100.0
@ -772,7 +772,7 @@ draw_pass_1 = SubResource("QuadMesh_hvb1l")
[node name="OmniLight3D" type="OmniLight3D" parent="SubViewportContainer/SubViewport/VFX/Fire"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.000509977, 0.121094, -0.00151992)
light_color = Color(0.89, 0.461613, 0.2136, 1)
light_energy = 0.668778
light_energy = 0.802091
light_indirect_energy = 1.084
light_volumetric_fog_energy = 3.764
light_size = 0.105