Files
puzzle-quest/addons/lod/lod_cpu_particles.gd
T

61 lines
2.3 KiB
GDScript
Raw Normal View History

2021-05-23 14:49:12 +02:00
# Copyright © 2020 Hugo Locurcio and contributors - MIT License
# See `LICENSE.md` included in the source distribution for details.
@icon("res://addons/lod/lod_cpu_particles.svg")
class_name LODCPUParticles
extends CPUParticles3D
2021-05-23 14:49:12 +02:00
# If `false`, LOD won't update anymore. This can be used for performance comparison
# purposes.
@export var enable_lod := true
2021-05-23 14:49:12 +02:00
# The maximum particle emitting distance in units. Past this distance, particles will no longer emit.
@export var max_emit_distance := 50 # (float, 0.0, 1000.0, 0.1)
2021-05-23 14:49:12 +02:00
# 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`.
2026-05-16 21:28:22 +02:00
var lod_distance_bias := 0.0
2021-05-23 14:49:12 +02:00
# The internal refresh timer.
var timer := 0.0
func _ready() -> void:
if ProjectSettings.has_setting("lod/particle_bias"):
2026-05-16 21:28:22 +02:00
lod_distance_bias = ProjectSettings.get_setting("lod/particle_bias")
2021-05-23 14:49:12 +02:00
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)
2021-05-23 14:49:12 +02:00
# 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()
2021-05-23 14:49:12 +02:00
if camera == null:
return
if timer <= refresh_rate:
timer += delta
return
timer = 0.0
2026-05-16 21:28:22 +02:00
var distance := camera.global_transform.origin.distance_to(global_transform.origin) + lod_distance_bias
2021-05-23 14:49:12 +02:00
emitting = distance < max_emit_distance