Merge pull request 'feature/book-lod' (#54) from feature/book-lod into dev

Reviewed-on: Athena/game-source#54
This commit is contained in:
stilobique
2021-05-24 12:58:47 +02:00
54 changed files with 3790 additions and 257 deletions
+21
View File
@@ -0,0 +1,21 @@
# MIT License
Copyright © 2020 Hugo Locurcio and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+59
View File
@@ -0,0 +1,59 @@
# Copyright © 2020 Hugo Locurcio and contributors - MIT License
# See `LICENSE.md` included in the source distribution for details.
extends CPUParticles
class_name LODCPUParticles, "lod_cpu_particles.svg"
# If `false`, LOD won't update anymore. This can be used for performance comparison
# purposes.
export var enable_lod := true
# The maximum particle emitting distance in units. Past this distance, particles will no longer emit.
export(float, 0.0, 1000.0, 0.1) var max_emit_distance := 50
# 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_bias := 0.0
# The internal refresh timer.
var timer := 0.0
func _ready() -> void:
if ProjectSettings.has_setting("lod/particle_bias"):
lod_bias = ProjectSettings.get_setting("lod/particle_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 += 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: float) -> void:
if not enable_lod:
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) + lod_bias
emitting = distance < max_emit_distance
+1
View File
@@ -0,0 +1 @@
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m4.5587261.60940813c-.4226244 0-.7617187.3410473-.7617187.76367177v.5078126c0 .1028478.020058.199689.056641.2890624h-1.1933597c-.4226245 0-.7617188.3390944-.7617188.7617188v.921875c-.040428-.00657-.0767989-.0234375-.1191406-.0234375h-.5078125c-.42262448 0-.76367188.3410475-.76367188.7636719v.3730468c0 .4226245.3410474.7617188.76367188.7617188h.5078125c.042396 0 .078663-.016851.1191406-.023437v4.4531248c-.040428-.0066-.076799-.02344-.1191406-.02344h-.5078125c-.42262448 0-.76367188.341047-.76367188.763672v.373047c0 .422625.3410474.761718.76367188.761718h.5078125c.042396 0 .078663-.01685.1191406-.02344v1.125c0 .422624.3390944.763672.7617188.763672h1.1367187v.457031c0 .422624.3390943.763672.7617187.763672h.3730469c.4226244 0 .7636719-.341048.7636719-.763672v-.457031h4.4062501v.457031c0 .422624.339094.763672.761719.763672h.373047c.422624 0 .763671-.341048.763671-.763672v-.457031h1.269532c.422625 0 .763672-.341048.763672-.763672v-1.111328c.01774.0012.03272.0098.05078.0098h.507812c.422624 0 .763672-.339093.763672-.761718v-.373047c0-.422624-.341048-.763672-.763672-.763672h-.507812c-.01803 0-.03307.0085-.05078.0098v-4.4258454c.01774.00122.03272.00977.05078.00977h.507812c.422624 0 .763672-.3390943.763672-.7617188v-.3730512c0-.4226244-.341048-.7636719-.763672-.7636719h-.507812c-.01803 0-.03307.00855-.05078.00977v-.9082075c0-.4226244-.341047-.7617187-.763672-.7617188h-1.328125c.03658-.089375.05859-.1862118.05859-.2890624v-.5078126c0-.42262437-.341047-.76367177-.763671-.76367177h-.373047c-.422625 0-.761719.3410474-.761719.76367177v.5078126c0 .1028478.02006.1996891.05664.2890624h-4.5214809c.036585-.0893749.0585938-.1862118.0585938-.2890624v-.5078126c0-.42262437-.3410475-.76367177-.7636719-.76367177zm3.2382813 2.35742177a3.279661 3.6440678 0 0 1 3.2128906 2.9394532 2.1864407 2.1864407 0 0 1 1.888672 2.1621094 2.1864407 2.1864407 0 0 1 -2.1875 2.1855475h-5.8300782a2.1864407 2.1864407 0 0 1 -2.1855469-2.1855475 2.1864407 2.1864407 0 0 1 1.8847656-2.1640626 3.279661 3.6440678 0 0 1 3.2167969-2.9375zm-2.9160156 8.0156251a.72881355.72881355 0 0 1 .7285156.728516.72881355.72881355 0 0 1 -.7285156.730469.72881355.72881355 0 0 1 -.7285157-.730469.72881355.72881355 0 0 1 .7285157-.728516zm5.8300782 0a.72881355.72881355 0 0 1 .730469.728516.72881355.72881355 0 0 1 -.730469.730469.72881355.72881355 0 0 1 -.7285157-.730469.72881355.72881355 0 0 1 .7285157-.728516zm-2.9140626.728516a.72881355.72881355 0 0 1 .7285156.730469.72881355.72881355 0 0 1 -.7285156.728515.72881355.72881355 0 0 1 -.7285156-.728515.72881355.72881355 0 0 1 .7285156-.730469z" fill="#fc9c9c" fill-opacity=".996078"/><path d="m7.5 5v3.5h2.5" fill="none" stroke="#fc9c9c" stroke-opacity=".996078"/></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

+34
View File
@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/lod_cpu_particles.svg-b3ece84e0440c5d32851b9105345db21.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/lod/lod_cpu_particles.svg"
dest_files=[ "res://.import/lod_cpu_particles.svg-b3ece84e0440c5d32851b9105345db21.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
+92
View File
@@ -0,0 +1,92 @@
# Copyright © 2020 Hugo Locurcio and contributors - MIT License
# See `LICENSE.md` included in the source distribution for details.
extends OmniLight
class_name LODOmniLight, "lod_omni_light.svg"
# 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(float, 0.0, 1000.0, 0.1) var shadow_max_distance := 25
# 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(float, 0.0, 1.0, 0.1) var shadow_fade_start := 0.8
# The maximum shadow distance in units. Past this distance, the light will be hidden.
export(float, 0.0, 1000.0, 0.1) var light_max_distance := 50
# 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(float, 0.0, 1.0, 0.1) var light_fade_start := 0.8
# 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_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_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 += 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: float) -> void:
if not enable_lod:
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) + lod_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
var shadow_fade_start_distance := shadow_max_distance * shadow_fade_start
var shadow_value: float
if distance > shadow_fade_start_distance:
shadow_value = min(1, (distance - shadow_fade_start_distance) / (shadow_max_distance - shadow_fade_start_distance))
else:
# We're close enough to the light to show its shadow at full darkness.
shadow_value = 0.0
shadow_color = Color(shadow_value, shadow_value, shadow_value)
+1
View File
@@ -0,0 +1 @@
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a5 5 0 0 0 -5 5 5 5 0 0 0 3 4.5762v2.4238h4v-2.4199a5 5 0 0 0 3-4.5801 5 5 0 0 0 -5-5zm0 2a3 3 0 0 1 3 3 3 3 0 0 1 -3 3 3 3 0 0 1 -3-3 3 3 0 0 1 3-3zm-1 11v1h2v-1z" fill="#fc9c9c" fill-opacity=".99608"/><path d="m7.5 4v3.5h2.4999996" fill="none" stroke="#fc9c9c" stroke-opacity=".996078"/></svg>

After

Width:  |  Height:  |  Size: 392 B

+34
View File
@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/lod_omni_light.svg-72b7ec907b4f0e08e3154232a03aab77.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/lod/lod_omni_light.svg"
dest_files=[ "res://.import/lod_omni_light.svg-72b7ec907b4f0e08e3154232a03aab77.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
+59
View File
@@ -0,0 +1,59 @@
# Copyright © 2020 Hugo Locurcio and contributors - MIT License
# See `LICENSE.md` included in the source distribution for details.
extends Particles
class_name LODParticles, "lod_particles.svg"
# If `false`, LOD won't update anymore. This can be used for performance comparison
# purposes.
export var enable_lod := true
# The maximum particle emitting distance in units. Past this distance, particles will no longer emit.
export(float, 0.0, 1000.0, 0.1) var max_emit_distance := 50
# 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_bias := 0.0
# The internal refresh timer.
var timer := 0.0
func _ready() -> void:
if ProjectSettings.has_setting("lod/particle_bias"):
lod_bias = ProjectSettings.get_setting("lod/particle_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 += 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: float) -> void:
if not enable_lod:
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) + lod_bias
emitting = distance < max_emit_distance
+1
View File
@@ -0,0 +1 @@
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 1a4.5 5 0 0 0 -4.4140625 4.03125 3 3 0 0 0 -2.5859375 2.96875 3 3 0 0 0 3 3h8a3 3 0 0 0 3-3 3 3 0 0 0 -2.589844-2.9667969 4.5 5 0 0 0 -4.410156-4.0332031zm-1 3h1v3h2v1h-3zm-3 8a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm8 0a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1zm-4 1a1 1 0 0 0 -1 1 1 1 0 0 0 1 1 1 1 0 0 0 1-1 1 1 0 0 0 -1-1z" fill="#fc9c9c" fill-opacity=".99608"/></svg>

After

Width:  |  Height:  |  Size: 504 B

+34
View File
@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/lod_particles.svg-86d5ee48cd8c5d9e3cfcd6fa66432a55.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/lod/lod_particles.svg"
dest_files=[ "res://.import/lod_particles.svg-86d5ee48cd8c5d9e3cfcd6fa66432a55.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
+87
View File
@@ -0,0 +1,87 @@
# Copyright © 2020 Hugo Locurcio and contributors - MIT License
# See `LICENSE.md` included in the source distribution for details.
extends Spatial
class_name LODSpatial, "lod_spatial.svg"
# 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(float, 0.0, 1000.0, 0.1) var lod_0_max_distance := 10
# The maximum LOD 1 (medium quality) distance in units.
export(float, 0.0, 1000.0, 0.1) var lod_1_max_distance := 25
# The maximum LOD 2 (low quality) distance in units.
# Past this distance, all LOD variants are hidden.
export(float, 0.0, 1000.0, 0.1) var lod_2_max_distance := 100
# 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_bias := 0.0
# The internal refresh timer.
var timer := 0.0
func _ready() -> void:
if ProjectSettings.has_setting("lod/spatial_bias"):
lod_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 += 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: float) -> void:
if not enable_lod:
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) + lod_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
+1
View File
@@ -0,0 +1 @@
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m8 2a6 6 0 0 0 -6 6 6 6 0 0 0 6 6 6 6 0 0 0 6-6 6 6 0 0 0 -6-6zm0 2a4 4 0 0 1 4 4 4 4 0 0 1 -4 4 4 4 0 0 1 -4-4 4 4 0 0 1 4-4z" fill="#fc9c9c" fill-opacity=".99608"/><path d="m7.5000004 6v3.5h2.4999996" fill="none" stroke="#fc9c9c" stroke-opacity=".996078"/></svg>

After

Width:  |  Height:  |  Size: 357 B

+34
View File
@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/lod_spatial.svg-0f291da571b0a5b87fdce289c6370d71.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/lod/lod_spatial.svg"
dest_files=[ "res://.import/lod_spatial.svg-0f291da571b0a5b87fdce289c6370d71.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
+92
View File
@@ -0,0 +1,92 @@
# Copyright © 2020 Hugo Locurcio and contributors - MIT License
# See `LICENSE.md` included in the source distribution for details.
extends SpotLight
class_name LODSpotLight, "lod_spot_light.svg"
# 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(float, 0.0, 1000.0, 0.1) var shadow_max_distance := 25
# 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(float, 0.0, 1.0, 0.1) var shadow_fade_start := 0.8
# The maximum shadow distance in units. Past this distance, the light will be hidden.
export(float, 0.0, 1000.0, 0.1) var light_max_distance := 50
# 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(float, 0.0, 1.0, 0.1) var light_fade_start := 0.8
# 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_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_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 += 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: float) -> void:
if not enable_lod:
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) + lod_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
var shadow_fade_start_distance := shadow_max_distance * shadow_fade_start
var shadow_value: float
if distance > shadow_fade_start_distance:
shadow_value = min(1, (distance - shadow_fade_start_distance) / (shadow_max_distance - shadow_fade_start_distance))
else:
# We're close enough to the light to show its shadow at full darkness.
shadow_value = 0.0
shadow_color = Color(shadow_value, shadow_value, shadow_value)
+1
View File
@@ -0,0 +1 @@
<svg height="16" viewBox="0 0 16 16" width="16" xmlns="http://www.w3.org/2000/svg"><path d="m6 1a1 1 0 0 0 -1 1v3.6933594c-1.7861.86608-3 2.4605406-3 4.3066406h4a2 2 0 0 0 2 2 2 2 0 0 0 2-2h4c0-1.8462-1.2139-3.4406406-3-4.3066406v-3.6933594a1 1 0 0 0 -1-1zm1 3h1v3h2v1h-3zm-2.0976562 6.634766-1.7324219 1 1 1.730468 1.7324219-1zm6.1953122 0-1 1.730468 1.732422 1 1-1.730468zm-4.097656 2.365234v2h2v-2z" fill="#fc9c9c" fill-opacity=".996078"/></svg>

After

Width:  |  Height:  |  Size: 449 B

+34
View File
@@ -0,0 +1,34 @@
[remap]
importer="texture"
type="StreamTexture"
path="res://.import/lod_spot_light.svg-22de3bf1089e94662394255ca8159db9.stex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://addons/lod/lod_spot_light.svg"
dest_files=[ "res://.import/lod_spot_light.svg-22de3bf1089e94662394255ca8159db9.stex" ]
[params]
compress/mode=0
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=0
flags/filter=true
flags/mipmaps=false
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=true
svg/scale=1.0
+7
View File
@@ -0,0 +1,7 @@
[plugin]
name="Level of Detail (LOD)"
description="Level of Detail implementation for meshes, lights and particles."
author="Calinou"
version="1.0.0"
script="plugin.gd"
+7
View File
@@ -0,0 +1,7 @@
# Copyright © 2020 Hugo Locurcio and contributors - MIT License
# See `LICENSE.md` included in the source distribution for details.
#
# This script is needed to make the `class_name` script visible in the Create New Node dialog
# once the plugin is enabled.
tool
extends EditorPlugin
+41
View File
@@ -0,0 +1,41 @@
[gd_resource type="ShaderMaterial" load_steps=3 format=2]
[sub_resource type="VisualShaderNodeColorUniform" id=1]
uniform_name = "BaseColor"
[sub_resource type="VisualShader" id=2]
code = "shader_type spatial;
render_mode specular_schlick_ggx;
uniform vec4 BaseColor : hint_color;
void vertex() {
// Output:0
}
void fragment() {
// ColorUniform:5
vec3 n_out5p0 = BaseColor.rgb;
float n_out5p1 = BaseColor.a;
// Output:0
ALBEDO = n_out5p0;
}
void light() {
// Output:0
}
"
graph_offset = Vector2( -278, -353.75 )
nodes/fragment/5/node = SubResource( 1 )
nodes/fragment/5/position = Vector2( 180, 140 )
nodes/fragment/connections = PoolIntArray( 5, 0, 0, 0 )
[resource]
shader = SubResource( 2 )
shader_param/BaseColor = Color( 0.313726, 1, 0, 1 )
+41
View File
@@ -0,0 +1,41 @@
[gd_resource type="ShaderMaterial" load_steps=3 format=2]
[sub_resource type="VisualShaderNodeColorUniform" id=1]
uniform_name = "BaseColor"
[sub_resource type="VisualShader" id=2]
code = "shader_type spatial;
render_mode specular_schlick_ggx;
uniform vec4 BaseColor : hint_color;
void vertex() {
// Output:0
}
void fragment() {
// ColorUniform:5
vec3 n_out5p0 = BaseColor.rgb;
float n_out5p1 = BaseColor.a;
// Output:0
ALBEDO = n_out5p0;
}
void light() {
// Output:0
}
"
graph_offset = Vector2( -278, -353.75 )
nodes/fragment/5/node = SubResource( 1 )
nodes/fragment/5/position = Vector2( 180, 140 )
nodes/fragment/connections = PoolIntArray( 5, 0, 0, 0 )
[resource]
shader = SubResource( 2 )
shader_param/BaseColor = Color( 1, 0, 0, 1 )
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -2,32 +2,32 @@
importer="scene"
type="PackedScene"
path="res://.import/book.gltf-fe5302e03c41545a5fd2726fcd33aa33.scn"
path="res://.import/book_lod0.gltf-abd21622432f58e5ae53528a798e9611.scn"
[deps]
source_file="res://assets/props/book/book.gltf"
dest_files=[ "res://.import/book.gltf-fe5302e03c41545a5fd2726fcd33aa33.scn" ]
source_file="res://assets/props/book/book_lod0.gltf"
dest_files=[ "res://.import/book_lod0.gltf-abd21622432f58e5ae53528a798e9611.scn" ]
[params]
nodes/root_type="Spatial"
nodes/root_type="ArrayMesh"
nodes/root_name="Scene Root"
nodes/root_scale=1.0
nodes/custom_script=""
nodes/storage=0
nodes/use_legacy_names=true
nodes/use_legacy_names=false
materials/location=1
materials/storage=0
materials/keep_on_reimport=false
meshes/compress=true
meshes/ensure_tangents=true
meshes/storage=1
meshes/light_baking=0
meshes/light_baking=1
meshes/lightmap_texel_size=0.1
skins/use_named_skins=true
skins/use_named_skins=false
external_files/store_in_subdir=false
animation/import=true
animation/import=false
animation/fps=15
animation/filter_script=""
animation/storage=false
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
+119
View File
@@ -0,0 +1,119 @@
[gd_scene load_steps=5 format=2]
[ext_resource path="res://assets/props/book/sm_book_lod0.mesh" type="ArrayMesh" id=1]
[ext_resource path="res://assets/props/book/sm_book_lod1.mesh" type="ArrayMesh" id=2]
[ext_resource path="res://assets/props/book/sm_book_lod2.mesh" type="ArrayMesh" id=3]
[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
class_name LODSpatial, \"res://addons/lod/lod_spatial.svg\"
# 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(float, 0.0, 1000.0, 0.1) var lod_0_max_distance := 10
# The maximum LOD 1 (medium quality) distance in units.
export(float, 0.0, 1000.0, 0.1) var lod_1_max_distance := 25
# The maximum LOD 2 (low quality) distance in units.
# Past this distance, all LOD variants are hidden.
export(float, 0.0, 1000.0, 0.1) var lod_2_max_distance := 100
# 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_bias := 0.0
# The internal refresh timer.
var timer := 0.0
func _ready() -> void:
if ProjectSettings.has_setting(\"lod/spatial_bias\"):
lod_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 += 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: float) -> void:
if not enable_lod:
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) + lod_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
"
[node name="sm_book" type="Spatial"]
script = SubResource( 1 )
lod_0_max_distance = 1.0
lod_1_max_distance = 5.0
lod_2_max_distance = 10.0
[node name="sm_book-lod0" type="MeshInstance" parent="."]
use_in_baked_light = true
mesh = ExtResource( 1 )
material/0 = null
[node name="sm_book-lod1" type="MeshInstance" parent="."]
transform = Transform( 1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00205189, 0, -0.0098635 )
visible = false
use_in_baked_light = true
mesh = ExtResource( 2 )
material/0 = null
[node name="sm_book-lod2" type="MeshInstance" parent="."]
visible = false
use_in_baked_light = true
mesh = ExtResource( 3 )
material/0 = null
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="StreamTexture"
path.s3tc="res://.import/tx_Paper_BC.tga-9fb9e97b4fb771cff15e05495d90bcc1.s3tc.stex"
path.etc2="res://.import/tx_Paper_BC.tga-9fb9e97b4fb771cff15e05495d90bcc1.etc2.stex"
path.etc="res://.import/tx_Paper_BC.tga-9fb9e97b4fb771cff15e05495d90bcc1.etc.stex"
metadata={
"imported_formats": [ "s3tc", "etc2", "etc" ],
"vram_texture": true
}
[deps]
source_file="res://assets/props/book/textures/tx_Paper_BC.tga"
dest_files=[ "res://.import/tx_Paper_BC.tga-9fb9e97b4fb771cff15e05495d90bcc1.s3tc.stex", "res://.import/tx_Paper_BC.tga-9fb9e97b4fb771cff15e05495d90bcc1.etc2.stex", "res://.import/tx_Paper_BC.tga-9fb9e97b4fb771cff15e05495d90bcc1.etc.stex" ]
[params]
compress/mode=2
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=true
flags/filter=true
flags/mipmaps=true
flags/anisotropic=false
flags/srgb=1
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0
Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="StreamTexture"
path.s3tc="res://.import/tx_Paper_NM.tga-7aae76ce0f4f9f4c3299047ca15922dc.s3tc.stex"
path.etc2="res://.import/tx_Paper_NM.tga-7aae76ce0f4f9f4c3299047ca15922dc.etc2.stex"
path.etc="res://.import/tx_Paper_NM.tga-7aae76ce0f4f9f4c3299047ca15922dc.etc.stex"
metadata={
"imported_formats": [ "s3tc", "etc2", "etc" ],
"vram_texture": true
}
[deps]
source_file="res://assets/props/book/textures/tx_Paper_NM.tga"
dest_files=[ "res://.import/tx_Paper_NM.tga-7aae76ce0f4f9f4c3299047ca15922dc.s3tc.stex", "res://.import/tx_Paper_NM.tga-7aae76ce0f4f9f4c3299047ca15922dc.etc2.stex", "res://.import/tx_Paper_NM.tga-7aae76ce0f4f9f4c3299047ca15922dc.etc.stex" ]
[params]
compress/mode=2
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=1
flags/repeat=true
flags/filter=true
flags/mipmaps=true
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0
Binary file not shown.

After

Width:  |  Height:  |  Size: 192 KiB

@@ -0,0 +1,37 @@
[remap]
importer="texture"
type="StreamTexture"
path.s3tc="res://.import/tx_Paper_ORM.tga-a4c3a5f60558aeb291283587e6bb15df.s3tc.stex"
path.etc2="res://.import/tx_Paper_ORM.tga-a4c3a5f60558aeb291283587e6bb15df.etc2.stex"
path.etc="res://.import/tx_Paper_ORM.tga-a4c3a5f60558aeb291283587e6bb15df.etc.stex"
metadata={
"imported_formats": [ "s3tc", "etc2", "etc" ],
"vram_texture": true
}
[deps]
source_file="res://assets/props/book/textures/tx_Paper_ORM.tga"
dest_files=[ "res://.import/tx_Paper_ORM.tga-a4c3a5f60558aeb291283587e6bb15df.s3tc.stex", "res://.import/tx_Paper_ORM.tga-a4c3a5f60558aeb291283587e6bb15df.etc2.stex", "res://.import/tx_Paper_ORM.tga-a4c3a5f60558aeb291283587e6bb15df.etc.stex" ]
[params]
compress/mode=2
compress/lossy_quality=0.7
compress/hdr_mode=0
compress/bptc_ldr=0
compress/normal_map=0
flags/repeat=true
flags/filter=true
flags/mipmaps=true
flags/anisotropic=false
flags/srgb=2
process/fix_alpha_border=true
process/premult_alpha=false
process/HDR_as_SRGB=false
process/invert_color=false
stream=false
size_limit=0
detect_3d=false
svg/scale=1.0
Binary file not shown.

Before

Width:  |  Height:  |  Size: 768 KiB

After

Width:  |  Height:  |  Size: 768 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 768 KiB

After

Width:  |  Height:  |  Size: 768 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 768 KiB

After

Width:  |  Height:  |  Size: 768 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
+32 -2
View File
@@ -138,6 +138,31 @@ _global_script_classes=[ {
"class": "GDDatabase",
"language": "GDScript",
"path": "res://addons/godot_db_manager/core/database.gd"
}, {
"base": "CPUParticles",
"class": "LODCPUParticles",
"language": "GDScript",
"path": "res://addons/lod/lod_cpu_particles.gd"
}, {
"base": "OmniLight",
"class": "LODOmniLight",
"language": "GDScript",
"path": "res://addons/lod/lod_omni_light.gd"
}, {
"base": "Particles",
"class": "LODParticles",
"language": "GDScript",
"path": "res://addons/lod/lod_particles.gd"
}, {
"base": "Spatial",
"class": "LODSpatial",
"language": "GDScript",
"path": "res://addons/lod/lod_spatial.gd"
}, {
"base": "SpotLight",
"class": "LODSpotLight",
"language": "GDScript",
"path": "res://addons/lod/lod_spot_light.gd"
} ]
_global_script_class_icons={
"GDDBConstants": "",
@@ -165,7 +190,12 @@ _global_script_class_icons={
"GDDBTablesHeader": "",
"GDDBTablesList": "",
"GDDBTypes": "",
"GDDatabase": ""
"GDDatabase": "",
"LODCPUParticles": "res://addons/lod/lod_cpu_particles.svg",
"LODOmniLight": "res://addons/lod/lod_omni_light.svg",
"LODParticles": "res://addons/lod/lod_particles.svg",
"LODSpatial": "res://addons/lod/lod_spatial.svg",
"LODSpotLight": "res://addons/lod/lod_spot_light.svg"
}
[application]
@@ -197,7 +227,7 @@ window/stretch/mode="2d"
[editor_plugins]
enabled=PoolStringArray( "res://addons/godot_db_manager/plugin.cfg" )
enabled=PoolStringArray( "res://addons/godot_db_manager/plugin.cfg", "res://addons/lod/plugin.cfg" )
[importer_defaults]
Binary file not shown.
+1 -1
View File
@@ -21,4 +21,4 @@ flags/filter=true
flags/mipmaps=false
flags/srgb=false
slices/horizontal=1
slices/vertical=4
slices/vertical=2
Binary file not shown.
+20 -36
View File
@@ -17,7 +17,6 @@
[ext_resource path="res://assets/props/rock floor/ground_library.tres" type="MeshLibrary" id=15]
[ext_resource path="res://scenes/levels/warcraft/WarCraft.lmbake" type="BakedLightmapData" id=16]
[ext_resource path="res://assets/props/candle/sm_candle_d.mesh" type="ArrayMesh" id=17]
[ext_resource path="res://assets/props/book/sm_book.mesh" type="ArrayMesh" id=18]
[ext_resource path="res://assets/props/dagger/materials/MA_dagger.material" type="Material" id=19]
[ext_resource path="res://assets/props/misc/sm_gabarit_male.mesh" type="ArrayMesh" id=20]
[ext_resource path="res://assets/props/weapon gun/sm_weapon_gun.mesh" type="ArrayMesh" id=21]
@@ -45,6 +44,7 @@
[ext_resource path="res://assets/props/spyglass/materials/MA_spyglass.material" type="Material" id=43]
[ext_resource path="res://scenes/UI/list_ho/UI_list_ho.tscn" type="PackedScene" id=44]
[ext_resource path="res://scenes/UI/UI_back.tscn" type="PackedScene" id=45]
[ext_resource path="res://assets/props/book/sm_book.tscn" type="PackedScene" id=46]
[sub_resource type="PanoramaSky" id=1]
panorama = ExtResource( 11 )
@@ -183,6 +183,7 @@ __meta__ = {
[node name="Red Color Left" type="SpotLight" parent="Lighting"]
transform = Transform( 0.949107, 0.151161, -0.276307, 0, 0.877297, 0.479948, 0.314953, -0.455522, 0.832649, -4.0515, 2.45338, 4.26157 )
light_color = Color( 0.643137, 0.109804, 0.152941, 1 )
light_energy = 11.3
light_specular = 1.0
light_bake_mode = 2
shadow_enabled = true
@@ -191,11 +192,12 @@ shadow_contact = 1.0
editor_only = true
spot_range = 5.43268
spot_attenuation = 1.41421
spot_angle = 31.2
[node name="Red Color Left2" type="SpotLight" parent="Lighting"]
transform = Transform( 0.80562, 0.042778, 0.590886, -0.18969, 0.963507, 0.18887, -0.561244, -0.264243, 0.784335, 0.631187, 2.3448, 4.15934 )
light_color = Color( 0.643137, 0.109804, 0.152941, 1 )
light_energy = 0.7
light_energy = 0.4
light_bake_mode = 2
shadow_enabled = true
shadow_bias = 0.1
@@ -374,37 +376,28 @@ material/0 = null
[node name="Main Scene Props" type="Spatial" parent="."]
[node name="Book" type="MeshInstance" parent="Main Scene Props"]
transform = Transform( 0.259561, 0, 0.965727, 0.0582327, 0.99818, -0.0156514, -0.963969, 0.0602995, 0.259089, 0.13025, 0.92072, -0.458817 )
use_in_baked_light = true
mesh = ExtResource( 18 )
material/0 = null
[node name="sm_book" parent="Main Scene Props" instance=ExtResource( 46 )]
transform = Transform( 0.259561, 0, 0.965727, 0.0582327, 0.99818, -0.0156514, -0.963969, 0.0602995, 0.259089, 0.13025, 0.960907, -0.456389 )
[node name="Book" type="MeshInstance" parent="Main Scene Props/Book"]
[node name="sm_book2" parent="Main Scene Props/sm_book" instance=ExtResource( 46 )]
transform = Transform( 0.0229641, -0.00339183, -0.999731, 0.0393653, 0.999223, -0.00248598, 0.998961, -0.0392976, 0.0230803, 0.00279957, 0.066205, -0.000443451 )
use_in_baked_light = true
mesh = ExtResource( 18 )
material/0 = null
[node name="Book2" type="MeshInstance" parent="Main Scene Props/Book/Book"]
transform = Transform( 0.86032, -0.0497817, -0.507318, 0.0471006, 0.998725, -0.0181282, 0.507573, -0.00829895, 0.861568, 0.00110056, 0.070618, -0.00503534 )
use_in_baked_light = true
mesh = ExtResource( 18 )
material/0 = null
[node name="sm_book3" parent="Main Scene Props/sm_book/sm_book2" instance=ExtResource( 46 )]
transform = Transform( 0.86032, -0.0497817, -0.507318, 0.0471006, 0.998725, -0.0181282, 0.507573, -0.00829895, 0.861568, 0.00110056, 0.070618, -0.00503528 )
[node name="sm_candlestick2" type="MeshInstance" parent="Main Scene Props/Book/Book/Book2"]
transform = Transform( 1.0543, -0.0109484, 1.03432, -0.0329634, 1.4758, 0.0492217, -1.03385, -0.0582193, 1.05321, 0.0299356, 0.0326171, -0.0690778 )
[node name="sm_candlestick2" type="MeshInstance" parent="Main Scene Props/sm_book/sm_book2/sm_book3"]
transform = Transform( 1.0543, -0.0109484, 1.03432, -0.0329634, 1.4758, 0.0492217, -1.03385, -0.0582193, 1.05321, 0.0299356, 0.0326169, -0.0690778 )
use_in_baked_light = true
mesh = ExtResource( 4 )
material/0 = null
[node name="sm_candle_top2" type="MeshInstance" parent="Main Scene Props/Book/Book/Book2/sm_candlestick2"]
[node name="sm_candle_top2" type="MeshInstance" parent="Main Scene Props/sm_book/sm_book2/sm_book3/sm_candlestick2"]
transform = Transform( 1.16981, 7.45037e-09, -2.27374e-13, 7.45058e-09, 1.63542, -1.42109e-14, 3.55271e-15, -2.84217e-14, 1.16981, 0.00268283, 0.168278, -5.96046e-08 )
use_in_baked_light = true
mesh = ExtResource( 1 )
material/0 = null
[node name="OmniLight" type="OmniLight" parent="Main Scene Props/Book/Book/Book2/sm_candlestick2/sm_candle_top2"]
[node name="OmniLight" type="OmniLight" parent="Main Scene Props/sm_book/sm_book2/sm_book3/sm_candlestick2/sm_candle_top2"]
transform = Transform( 0.578774, -3.72536e-09, -3.47774e-07, -3.72529e-09, 0.413993, -3.75217e-08, -1.15463e-13, 7.10543e-15, 0.578773, -0.00229338, 0.0614615, 2.98023e-08 )
light_color = Color( 0.960784, 0.611765, 0.00784314, 1 )
light_energy = 12.0
@@ -456,23 +449,14 @@ use_in_baked_light = true
mesh = ExtResource( 6 )
material/0 = null
[node name="Book3" type="MeshInstance" parent="Main Scene Props"]
transform = Transform( 0.5, 0, 0.866025, 0, 1, 0, -0.866025, 0, 0.5, 0.0106606, 0.96499, 0.981535 )
use_in_baked_light = true
mesh = ExtResource( 18 )
material/0 = null
[node name="Book" type="MeshInstance" parent="Main Scene Props/Book3"]
transform = Transform( 0.992026, 0, 0.592682, 0, 1.15559, 0, -0.592682, 0, 0.992026, -0.000832438, 0.0791223, -0.012241 )
use_in_baked_light = true
mesh = ExtResource( 18 )
material/0 = null
[node name="Book2" type="MeshInstance" parent="Main Scene Props"]
[node name="sm_book2" parent="Main Scene Props" instance=ExtResource( 46 )]
transform = Transform( 0.122577, 0.0288089, -0.992041, -0.0361233, 0.999045, 0.0245489, 0.991801, 0.0328267, 0.1235, 0.493202, 0.942654, -0.0854386 )
use_in_baked_light = true
mesh = ExtResource( 18 )
material/0 = null
[node name="sm_book3" parent="Main Scene Props" instance=ExtResource( 46 )]
transform = Transform( 0.5, 0, 0.866025, 0, 1, 0, -0.866025, 0, 0.5, 0.0106606, 0.96499, 0.981535 )
[node name="sm_book" parent="Main Scene Props/sm_book3" instance=ExtResource( 46 )]
transform = Transform( 0.992026, 0, 0.592682, 0, 1.15559, 0, -0.592682, 0, 0.992026, -0.000832498, 0.0791223, -0.012241 )
[node name="sm_godet2" type="MeshInstance" parent="Main Scene Props"]
transform = Transform( 0.875311, 0.480987, 0.0498184, 0.0206958, 0.0656668, -0.997627, -0.483117, 0.874265, 0.0475244, -0.191043, 0.95253, 0.11484 )