extends MeshInstance3D @export var max_lights := 256 @export var camera: Camera3D var lights: Array[Light3D] = [] func _ready() -> void: find_lights(get_tree().current_scene) func find_lights(node: Node) -> void: if node is Light3D: lights.append(node) for child in node.get_children(): find_lights(child) func _process(_delta: float) -> void: var mat := material_override as ShaderMaterial if mat == null: return if camera == null: camera = get_viewport().get_camera_3d() if camera == null: return mat.set_shader_parameter( "inv_projection", camera.get_camera_projection().inverse() ) mat.set_shader_parameter( "inv_view", camera.global_transform ) if mat == null: return var positions := PackedVector3Array() var colors := PackedColorArray() var energies := PackedFloat32Array() var ranges := PackedFloat32Array() for light in lights: if not is_instance_valid(light): continue if not light.visible: continue positions.append(light.global_position) colors.append(light.light_color) energies.append(light.light_energy) if light is OmniLight3D: ranges.append(light.omni_range) elif light is SpotLight3D: ranges.append(light.spot_range) else: ranges.append(100.0) if positions.size() >= max_lights: break mat.set_shader_parameter("light_positions", positions) mat.set_shader_parameter("light_colors", colors) mat.set_shader_parameter("light_energies", energies) mat.set_shader_parameter("light_ranges", ranges) mat.set_shader_parameter("light_count", positions.size())