Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A small suggestion to script (refactor and usability improvement) #8

Open
roalyr opened this issue Jul 31, 2022 · 3 comments
Open

A small suggestion to script (refactor and usability improvement) #8

roalyr opened this issue Jul 31, 2022 · 3 comments
Labels
enhancement New feature or request

Comments

@roalyr
Copy link

roalyr commented Jul 31, 2022

I'll leave it here just in case. don't want to poke you over this since Godot 4 has it covered, but still.
What's changed:

  1. Structured scene.
  2. Meshes are attached as children to Scene_items nodes, so no need to name them in any specific way.
  3. LOD distances are relative, values are multiplied by the size of the parent node LODs
  4. removed get_children() loop.

Scene with embedded script:
image

[gd_scene load_steps=2 format=2]

[sub_resource type="GDScript" id=1]
script/source = "# Copyright © 2020 Hugo Locurcio and contributors - MIT License
# See `LICENSE.md` included in the source distribution for details.
extends Spatial

# 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_relative_distance = 5

# The maximum LOD 1 (medium quality) distance in units.
export var lod_1_relative_distance = 25

# The maximum LOD 2 (low quality) distance in units.
# Past this distance, all LOD variants are hidden.
export var lod_2_relative_distance = 150

# 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`.
export var refresh_rate = 0.25

# The internal refresh timer.
var timer = 0.0


func _ready():

	# Add random jitter to the timer to ensure LODs don't all swap at the same time.
	randomize()
	timer += rand_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):
	if not enable_lod:
		# Show
		show_scenes(\"LOD0\")
		# Hide
		hide_scenes(\"LOD1\")
		hide_scenes(\"LOD2\")
		hide_scenes(\"LOD3\")
		return

	# We need a camera to do the rest.
	var camera = get_viewport().get_camera()
	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)
	# The LOD level to choose (lower is more detailed).
	# Multiply distance values by scale for relativism.
	if distance < lod_0_relative_distance * self.scale.length():
		# Show
		show_scenes(\"LOD0\")
		# Hide
		hide_scenes(\"LOD1\")
		hide_scenes(\"LOD2\")
		hide_scenes(\"LOD3\")
	elif distance < lod_1_relative_distance * self.scale.length():
		# Show
		show_scenes(\"LOD1\")
		# Hide
		hide_scenes(\"LOD2\")
		hide_scenes(\"LOD0\")
		hide_scenes(\"LOD3\")
	elif distance < lod_2_relative_distance * self.scale.length():
		# Show
		show_scenes(\"LOD2\")
		# Hide
		hide_scenes(\"LOD1\")
		hide_scenes(\"LOD0\")
		hide_scenes(\"LOD3\")
	else:
		# Show
		show_scenes(\"LOD3\")
		# Hide
		hide_scenes(\"LOD0\")
		hide_scenes(\"LOD1\")
		hide_scenes(\"LOD2\")
		

func show_scenes(lod_name):
	self.get_node(lod_name).get_node(\"Scene_items\").show()
			
func hide_scenes(lod_name):
	self.get_node(lod_name).get_node(\"Scene_items\").hide()
"

[node name="LODs" type="Spatial"]
script = SubResource( 1 )
__meta__ = {
"_editor_description_": "Do not rename or edit the nodes.
Put meshes into Scene Items nodes"
}

[node name="LOD0" type="Spatial" parent="."]
__meta__ = {
"_edit_lock_": true
}

[node name="Scene_items" type="Spatial" parent="LOD0"]
__meta__ = {
"_edit_lock_": true
}

[node name="LOD1" type="Spatial" parent="."]
__meta__ = {
"_edit_lock_": true
}

[node name="Scene_items" type="Spatial" parent="LOD1"]
__meta__ = {
"_edit_lock_": true
}

[node name="LOD2" type="Spatial" parent="."]
__meta__ = {
"_edit_lock_": true
}

[node name="Scene_items" type="Spatial" parent="LOD2"]
__meta__ = {
"_edit_lock_": true
}

[node name="LOD3" type="Spatial" parent="."]
__meta__ = {
"_edit_lock_": true
}

[node name="Scene_items" type="Spatial" parent="LOD3"]
__meta__ = {
"_edit_lock_": true
}
@roalyr
Copy link
Author

roalyr commented Jul 31, 2022

image

@Calinou Calinou added the enhancement New feature or request label Jul 31, 2022
@Calinou
Copy link
Member

Calinou commented Jul 31, 2022

I'd prefer focusing on having people test #4 and make sure it works well in production, as it has a greater potential for performance optimization by using fewer script instances. Both your proposal and #4 will break compatibility, so it'll require bumping the version of this add-on to 2.0.0.

Note that LOD is slated to be implemented in 3.6 by godotengine/godot#53778, so this add-on may not be relevant anymore in the future.

@roalyr
Copy link
Author

roalyr commented Jul 31, 2022

I'd prefer focusing on having people test #4 and make sure it works well in production, as it has a greater potential for performance optimization by using fewer script instances. Both your proposal and #4 will break compatibility, so it'll require bumping the version of this add-on to 2.0.0.

Note that LOD is slated to be implemented in 3.6 by godotengine/godot#53778, so this add-on may not be relevant anymore in the future.

Oh, that would be great! Still might want to have a small wrapper script to automate LOD ranges absolute values (proportional to object scale).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants