Files
puzzle-quest/addons/lod/lod_omni_light.gd
T
Vaillant Jeremy 81e6ceb003 Silence Godot 4 editor warnings (debugger)
Address every warning that surfaced in the running game's debugger:

- Drop deprecated 'graph_offset = Vector2(...)' lines from the three
  in-tree VisualShader resources (red.tres, green.tres,
  Summary.tscn). The property is editor-only graph pan, ignored at
  runtime but warns at load.
- Add android/.gdignore so Godot stops scanning the build template
  copies of red.tres/green.tres (which still had graph_offset). Tighten
  .gitignore to keep tracking the .gdignore marker only.
- Drop the broken 'nodes/fragment/connections = ...' line from the
  inline VisualShader in Summary.tscn — connections referenced
  out-of-bounds ports (e.g. port 1 on a 1-output node). The
  pre-compiled 'code = ...' string is kept so rendering is unaffected.
- Drop the orphaned 'ext_resource WarCraft.lmbake' from WarCraft.tscn:
  the LightmapGI node no longer references it but Godot still loaded
  the (Godot-3-format) blob from the ext_resource declaration alone,
  triggering '(p_data.size() % 4) != 0'.
- Animation tracks: SlideReset (Template.tscn), BorderAnim
  (Loading.tscn), and ObjectFindAll (ListObjects.tscn) each had a
  bezier track with empty PackedFloat32Array keys, which
  AnimationMixer rejects in Godot 4. Drop the empty x track in each
  (the y track held the actual motion).
- Re-save 57 .mesh files via scripts/migrate_misc.gd so the surface
  format is the current Godot 4 variant. sm_stackgold.mesh in
  particular triggered the deprecation warning every load.

GDScript: rename function parameters and locals that shadowed
Node.name / Node.value in:
- db/MScene.gd (set_lock, set_mesh, set_tick_reference, set_value)
- scripts/Setting.gd untouched (no shadow, false positive earlier)
- scenes/UI/choose_scenes/ChooseScene.gd (_load_scene, _build_path,
  _build_method)
- scenes/levels/Levels.gd (_create_animation_slide,
  _create_animation_warning, _add_animation_to_player,
  _create_button_info, _node_object_list)

lod plugin: Godot 4 added 'lod_bias' as a native property on
VisualInstance3D, which collided with the plugin's 'lod_bias' member
across all five lod_*.gd files. Rename to 'lod_distance_bias' so the
scripts parse again. Also drop Light3D.shadow_color writes in
lod_omni_light.gd and lod_spot_light.gd — that property was removed
in Godot 4, so the related shadow_value computation became dead code.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 21:28:22 +02:00

86 lines
3.4 KiB
GDScript

# Copyright © 2020 Hugo Locurcio and contributors - MIT License
# See `LICENSE.md` included in the source distribution for details.
@icon("res://addons/lod/lod_omni_light.svg")
class_name LODOmniLight
extends OmniLight3D
# If `false`, LOD won't update anymore. This can be used for performance comparison
# purposes.
@export var enable_lod := true
# The maximum shadow distance in units. Past this distance, the shadow will be disabled.
@export var shadow_max_distance := 25 # (float, 0.0, 1000.0, 0.1)
# The distance factor at which the shadow starts fading.
# A value of 0.0 will result in the smoothest transition whereas a value of 1.0 disables fading.
@export var shadow_fade_start := 0.8 # (float, 0.0, 1.0, 0.1)
# The maximum shadow distance in units. Past this distance, the light will be hidden.
@export var light_max_distance := 50 # (float, 0.0, 1000.0, 0.1)
# The distance factor at which the light starts fading.
# A value of 0.0 will result in the smoothest transition whereas a value of 1.0 disables fading.
@export var light_fade_start := 0.8 # (float, 0.0, 1.0, 0.1)
# The rate at which LODs will be updated (in seconds). Lower values are more reactive
# but use more CPU, which is especially noticeable with large amounts of LOD-enabled nodes.
# Set this accordingly depending on your camera movement speed.
# The default value should suit most projects already.
# Note: Slow cameras don't need to have LOD-enabled objects update their status often.
# By default, lights have their LOD updated faster than other LOD nodes since their
# light/shadow intensity needs to change as smoothly as posible.
# This can overridden by setting the project setting `lod/light_refresh_rate`.
var refresh_rate := 0.05
# The LOD bias in units.
# Positive values will decrease the detail level and improve performance.
# Negative values will improve visual appearance at the cost of performance.
# This can overridden by setting the project setting `lod/bias`.
var lod_distance_bias := 0.0
# The internal refresh timer.
var timer := 0.0
# The light's energy when it was instanced.
var base_light_energy := light_energy
func _ready() -> void:
if ProjectSettings.has_setting("lod/light_bias"):
lod_distance_bias = ProjectSettings.get_setting("lod/light_bias")
if ProjectSettings.has_setting("lod/light_refresh_rate"):
refresh_rate = ProjectSettings.get_setting("lod/light_refresh_rate")
# Add random jitter to the timer to ensure LODs don't all swap at the same time.
randomize()
timer += randf_range(0, refresh_rate)
# Despite LOD not being related to physics, we chose to run in `_physics_process()`
# to minimize the amount of method calls per second (and therefore decrease CPU usage).
func _physics_process(delta: float) -> void:
if not enable_lod:
return
# We need a camera to do the rest.
var camera := get_viewport().get_camera_3d()
if camera == null:
return
if timer <= refresh_rate:
timer += delta
return
timer = 0.0
var distance := camera.global_transform.origin.distance_to(global_transform.origin) + lod_distance_bias
visible = distance < light_max_distance
var light_fade_start_distance := light_max_distance * light_fade_start
if distance > light_fade_start_distance:
light_energy = max(0, (1 - (distance - light_fade_start_distance) / (light_max_distance - light_fade_start_distance)) * base_light_energy)
else:
# We're close enough to the light to show it at full brightness.
light_energy = base_light_energy
shadow_enabled = distance < shadow_max_distance