73 lines
1.5 KiB
GDScript
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())
|