Files
2026-09-10 07:47:15 -04:00

73 lines
1.5 KiB
GDScript

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())