Improve tree gathering and rain occlusion

This commit is contained in:
Alexander Sellite 2026-08-24 14:34:58 -04:00
parent a7c71213cc
commit 3608be41ab
8 changed files with 165 additions and 2 deletions

View file

@ -0,0 +1,56 @@
class_name PrecipitationOcclusion
extends RefCounted
## A secondary visual layer used only when building the local rain height field.
## Canopy meshes remain on layer 1 for ordinary cameras.
const RENDER_LAYER_NUMBER: int = 20
const RENDER_LAYER_MASK: int = 1 << (RENDER_LAYER_NUMBER - 1)
const CANOPY_MATERIAL_NAMES: Array[String] = [
"leaf",
"leaf_light",
"leaf_mid",
"leaf_dark",
"pine",
"tree",
]
static func mark_canopy_meshes(root_node: Node) -> int:
if root_node == null:
return 0
var marked_count: int = 0
var mesh_instance := root_node as MeshInstance3D
if mesh_instance != null and _has_canopy_material(mesh_instance):
mesh_instance.layers |= RENDER_LAYER_MASK
marked_count += 1
for child: Node in root_node.get_children():
marked_count += mark_canopy_meshes(child)
return marked_count
## Generated tree definitions are already explicit terrain metadata, so every
## mesh in their visual scene can safely participate. This also supports older
## combined tree meshes whose imported material name does not identify leaves.
static func mark_tree_meshes(root_node: Node) -> int:
if root_node == null:
return 0
var marked_count: int = 0
var mesh_instance := root_node as MeshInstance3D
if mesh_instance != null:
mesh_instance.layers |= RENDER_LAYER_MASK
marked_count += 1
for child: Node in root_node.get_children():
marked_count += mark_tree_meshes(child)
return marked_count
static func _has_canopy_material(mesh_instance: MeshInstance3D) -> bool:
if mesh_instance == null or mesh_instance.mesh == null:
return false
for surface_index: int in mesh_instance.mesh.get_surface_count():
var material := mesh_instance.mesh.surface_get_material(surface_index)
if material == null:
continue
if material.resource_name.to_lower() in CANOPY_MATERIAL_NAMES:
return true
return false