81e6ceb003
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>
89 lines
3.0 KiB
GDScript
89 lines
3.0 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_spatial.svg")
|
|
class_name LODSpatial
|
|
extends Node3D
|
|
|
|
# If `false`, LOD won't update anymore. This can be used for performance comparison
|
|
# purposes.
|
|
@export var enable_lod := true
|
|
|
|
# The maximum LOD 0 (high quality) distance in units.
|
|
@export var lod_0_max_distance := 10 # (float, 0.0, 1000.0, 0.1)
|
|
|
|
# The maximum LOD 1 (medium quality) distance in units.
|
|
@export var lod_1_max_distance := 25 # (float, 0.0, 1000.0, 0.1)
|
|
|
|
# The maximum LOD 2 (low quality) distance in units.
|
|
# Past this distance, all LOD variants are hidden.
|
|
@export var lod_2_max_distance := 100 # (float, 0.0, 1000.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.
|
|
# This can overridden by setting the project setting `lod/refresh_rate`.
|
|
var refresh_rate := 0.25
|
|
|
|
# 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
|
|
|
|
|
|
func _ready() -> void:
|
|
if ProjectSettings.has_setting("lod/spatial_bias"):
|
|
lod_distance_bias = ProjectSettings.get_setting("lod/spatial_bias")
|
|
if ProjectSettings.has_setting("lod/refresh_rate"):
|
|
refresh_rate = ProjectSettings.get_setting("lod/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
|
|
# The LOD level to choose (lower is more detailed).
|
|
var lod: int
|
|
if distance < lod_0_max_distance:
|
|
lod = 0
|
|
elif distance < lod_1_max_distance:
|
|
lod = 1
|
|
elif distance < lod_2_max_distance:
|
|
lod = 2
|
|
else:
|
|
# Hide the LOD object entirely.
|
|
lod = 3
|
|
|
|
for node in get_children():
|
|
# `-lod` also matches `-lod0`, `-lod1`, `-lod2`, …
|
|
if node.has_method("set_visible"):
|
|
if "-lod0" in node.name:
|
|
node.visible = lod == 0
|
|
if "-lod1" in node.name:
|
|
node.visible = lod == 1
|
|
if "-lod2" in node.name:
|
|
node.visible = lod == 2
|