306 lines
10 KiB
GDScript
306 lines
10 KiB
GDScript
extends Control
|
|
|
|
class_name UIController
|
|
|
|
@export_category("Toggles")
|
|
@export var enable_profiler : bool
|
|
@export var enable_music : bool
|
|
|
|
@export_category("Resources")
|
|
@export var settings: ScalabilitySettings
|
|
@export var lighting_scenarios: LightingScenarios
|
|
|
|
@export_category("")
|
|
@export var custom_res_text_box : LineEdit
|
|
@export var fps_text : Label
|
|
@export var custom_res: Array[Control]
|
|
@export var profiler: Array[Control]
|
|
@export var sun_light: DirectionalLight3D
|
|
@export var environment: WorldEnvironment
|
|
@export var night_lights: Array[Node3D]
|
|
@export var day_lights: Node3D
|
|
@export var lamp_mesh_containers: Array[Node3D]
|
|
@export var lamp_meshes: Array[MeshInstance3D]
|
|
@export var emissives: Array[StandardMaterial3D]
|
|
@export var scalable_night_lights: Node3D
|
|
@export var day_ambient_audio: AudioStreamPlayer
|
|
@export var night_ambient_audio: AudioStreamPlayer
|
|
@export var day_music: AudioStreamPlayer
|
|
@export var night_music: AudioStreamPlayer
|
|
|
|
const UPPER_RES_LIMIT = 8640.0
|
|
const LOWER_RES_LIMIT = 96.0
|
|
const TIME_CHANGE_DURATION = 4.0
|
|
const NIGHT_SHADOW_RES = 512
|
|
|
|
var renderTargetVertical = 1080.0
|
|
var is_time_changing = false
|
|
var is_ui_hidden = false
|
|
var ui_cooldown = false
|
|
|
|
var fps
|
|
var frametime
|
|
var draw_calls
|
|
var memory
|
|
var vram
|
|
|
|
@onready var sun_orig_res = ProjectSettings.get_setting("rendering/lights_and_shadows/directional_shadow/size")
|
|
@onready var sun_shadow_bits = ProjectSettings.get_setting("rendering/lights_and_shadows/directional_shadow/16_bits")
|
|
|
|
func _ready():
|
|
refresh_performance()
|
|
|
|
_on_res_selected(2)
|
|
_on_quality_selected(1)
|
|
_on_time_selected(2)
|
|
|
|
get_viewport().connect("size_changed", _on_viewport_resize)
|
|
|
|
if !enable_profiler:
|
|
for control in profiler:
|
|
control.visible = false
|
|
|
|
func _process(delta):
|
|
pass
|
|
|
|
func _on_viewport_resize():
|
|
if renderTargetVertical == 0.0:
|
|
RenderingServer.viewport_set_scaling_3d_scale(get_viewport().get_viewport_rid(), 1)
|
|
return
|
|
|
|
RenderingServer.viewport_set_scaling_3d_scale(get_viewport().get_viewport_rid(), renderTargetVertical/float(get_resolution_actual()))
|
|
|
|
func get_resolution_actual():
|
|
var yToUse
|
|
var project_width = float(ProjectSettings.get_setting("display/window/size/viewport_width"))
|
|
var project_height = float(ProjectSettings.get_setting("display/window/size/viewport_height"))
|
|
var viewport_width = float(get_viewport().size.x)
|
|
var viewport_height = float(get_viewport().size.y)
|
|
if viewport_width/viewport_height < project_width/project_height:
|
|
yToUse = (viewport_width/project_width) * project_height
|
|
else:
|
|
yToUse = viewport_height
|
|
return int(yToUse)
|
|
|
|
func refresh_performance():
|
|
fps = "FPS: " + str(Performance.get_monitor(Performance.TIME_FPS))
|
|
frametime = "Frame time: " + str(snapped(Performance.get_monitor(Performance.TIME_PROCESS) * 1000.0, 0.01)) + " ms"
|
|
draw_calls = "Draw calls: " + str(Performance.get_monitor(Performance.RENDER_TOTAL_DRAW_CALLS_IN_FRAME))
|
|
memory = "RAM: " + str(snapped(Performance.get_monitor(Performance.MEMORY_STATIC) * 0.000001, 0.01)) + " MB"
|
|
vram = "VRAM: " + str(snapped(Performance.get_monitor(Performance.RENDER_VIDEO_MEM_USED) * 0.000001, 0.01)) + " MB"
|
|
|
|
fps_text.text = fps + "\n" + frametime + "\n" + draw_calls + "\n" + memory + "\n" + vram
|
|
|
|
await get_tree().create_timer(0.75).timeout
|
|
|
|
refresh_performance()
|
|
|
|
func _on_res_selected(index):
|
|
if index == 6:
|
|
if renderTargetVertical == 0.0:
|
|
custom_res_text_box.text = str(get_resolution_actual())
|
|
else:
|
|
custom_res_text_box.text = str(int(renderTargetVertical))
|
|
for control in custom_res:
|
|
control.visible = true
|
|
else:
|
|
match index:
|
|
0:
|
|
renderTargetVertical = 0.0
|
|
1:
|
|
renderTargetVertical = 480.0
|
|
2:
|
|
renderTargetVertical = 720.0
|
|
3:
|
|
renderTargetVertical = 1080.0
|
|
4:
|
|
renderTargetVertical = 1440.0
|
|
5:
|
|
renderTargetVertical = 2160.0
|
|
_on_viewport_resize()
|
|
for control in custom_res:
|
|
control.visible = false
|
|
|
|
func _on_custom_res_input(input_string):
|
|
custom_res_text_box.release_focus()
|
|
renderTargetVertical = clamp(float(input_string), LOWER_RES_LIMIT, UPPER_RES_LIMIT)
|
|
custom_res_text_box.text = str(int(renderTargetVertical))
|
|
_on_viewport_resize()
|
|
|
|
func _on_quality_selected(index):
|
|
match index:
|
|
0:
|
|
apply_settings(settings.low)
|
|
1:
|
|
apply_settings(settings.normal)
|
|
2:
|
|
apply_settings(settings.high)
|
|
|
|
func _on_time_selected(index):
|
|
match index:
|
|
0:
|
|
apply_time(lighting_scenarios.dusk)
|
|
1:
|
|
apply_time(lighting_scenarios.noon)
|
|
2:
|
|
apply_time(lighting_scenarios.afternoon)
|
|
3:
|
|
apply_time(lighting_scenarios.night)
|
|
|
|
func _on_quit_selected():
|
|
get_tree().quit()
|
|
|
|
func apply_settings(settings):
|
|
sun_light.light_angular_distance = settings.sun_angle
|
|
environment.environment.ssr_enabled = settings.ssr
|
|
environment.environment.ssao_enabled = settings.ssao
|
|
environment.environment.ssil_enabled = settings.ssil
|
|
environment.environment.sdfgi_enabled = settings.sdfgi
|
|
RenderingServer.viewport_set_msaa_3d(get_viewport().get_viewport_rid(), settings.msaa)
|
|
RenderingServer.viewport_set_screen_space_aa(get_viewport().get_viewport_rid(), settings.fxaa)
|
|
RenderingServer.viewport_set_scaling_3d_mode(get_viewport().get_viewport_rid(), settings.scaling)
|
|
for light in scalable_night_lights.get_children():
|
|
if light is Light3D:
|
|
light.shadow_enabled = settings.night_shadows
|
|
|
|
func apply_time(lighting):
|
|
is_time_changing = false
|
|
|
|
await get_tree().process_frame
|
|
|
|
var time = Time.get_ticks_msec() / 1000.0
|
|
var orig_lux = sun_light.light_intensity_lux
|
|
var orig_light = sun_light.light_temperature
|
|
var orig_rot = sun_light.quaternion
|
|
var orig_sky = environment.environment.background_intensity
|
|
var orig_exp_mult = environment.camera_attributes.exposure_sensitivity
|
|
var orig_min_sens = environment.camera_attributes.auto_exposure_min_sensitivity
|
|
var orig_day_volume = day_ambient_audio.volume_db
|
|
var orig_night_volume = night_ambient_audio.volume_db
|
|
var orig_day_music_volume = day_music.volume_db
|
|
var orig_night_music_volume = night_music.volume_db
|
|
|
|
var target_music_audio
|
|
if enable_music:
|
|
target_music_audio = 0.0
|
|
else:
|
|
target_music_audio = -80.0
|
|
|
|
if lighting.night_lights:
|
|
if day_music.playing:
|
|
night_music.stop()
|
|
else:
|
|
for node in night_lights:
|
|
node.visible = false
|
|
change_shadow_casters(true)
|
|
RenderingServer.directional_shadow_atlas_set_size(sun_orig_res, sun_shadow_bits)
|
|
for mat in emissives:
|
|
mat.emission_enabled = false
|
|
if night_music.playing:
|
|
day_music.stop()
|
|
|
|
is_time_changing = true
|
|
|
|
while is_time_changing:
|
|
var current_time = Time.get_ticks_msec() / 1000.0
|
|
var lerp = (current_time - time)/TIME_CHANGE_DURATION
|
|
|
|
if lerp > 1:
|
|
sun_light.light_intensity_lux = lighting.lux
|
|
sun_light.light_temperature = lighting.temp
|
|
sun_light.quaternion = lighting.rotation
|
|
environment.environment.background_intensity = lighting.sky_nits
|
|
environment.camera_attributes.exposure_sensitivity = lighting.exposure_mult
|
|
environment.camera_attributes.auto_exposure_min_sensitivity = lighting.exposure_min_sens
|
|
|
|
if lighting.night_lights:
|
|
for node in night_lights:
|
|
node.visible = true
|
|
change_shadow_casters(false)
|
|
RenderingServer.directional_shadow_atlas_set_size(NIGHT_SHADOW_RES, sun_shadow_bits)
|
|
for mat in emissives:
|
|
mat.emission_enabled = true
|
|
|
|
day_ambient_audio.volume_db = -80.0
|
|
night_ambient_audio.volume_db = 0.0
|
|
day_music.volume_db = -80.0
|
|
night_music.volume_db = target_music_audio
|
|
if day_music.playing:
|
|
day_music.stop()
|
|
night_music.play()
|
|
else:
|
|
day_ambient_audio.volume_db = 0.0
|
|
night_ambient_audio.volume_db = -80.0
|
|
day_music.volume_db = target_music_audio
|
|
night_music.volume_db = -80.0
|
|
if night_music.playing:
|
|
night_music.stop()
|
|
day_music.play()
|
|
|
|
is_time_changing = false
|
|
break
|
|
|
|
sun_light.light_intensity_lux = lerp(orig_lux, lighting.lux, easeInOutSine(lerp))
|
|
sun_light.light_temperature = lerp(orig_light, lighting.temp, easeInOutSine(lerp))
|
|
sun_light.quaternion = orig_rot.slerp(lighting.rotation, easeInOutSine(lerp))
|
|
environment.environment.background_intensity = lerp(orig_sky, lighting.sky_nits, easeInOutSine(lerp))
|
|
|
|
if orig_exp_mult < lighting.exposure_mult:
|
|
environment.camera_attributes.exposure_sensitivity = lerp(orig_exp_mult, lighting.exposure_mult, easeInExp(lerp, 150))
|
|
environment.camera_attributes.auto_exposure_min_sensitivity = lerp(orig_min_sens, lighting.exposure_min_sens, easeInExp(lerp, 150))
|
|
else:
|
|
environment.camera_attributes.exposure_sensitivity = lerp(orig_exp_mult, lighting.exposure_mult, easeOutExp(lerp, 150))
|
|
environment.camera_attributes.auto_exposure_min_sensitivity = lerp(orig_min_sens, lighting.exposure_min_sens, easeOutExp(lerp, 150))
|
|
|
|
var music_lerp_exp = 5
|
|
|
|
if lighting.night_lights:
|
|
day_ambient_audio.volume_db = lerp(orig_day_volume, -80.0, easeInExp(lerp, 4))
|
|
night_ambient_audio.volume_db = lerp(orig_night_volume, 0.0, easeOutExp(lerp, 4))
|
|
day_music.volume_db = lerp(orig_day_music_volume, -80.0, easeInExp(lerp, music_lerp_exp))
|
|
night_music.volume_db = lerp(orig_night_music_volume, target_music_audio, easeOutExp(lerp, music_lerp_exp))
|
|
else:
|
|
day_ambient_audio.volume_db = lerp(orig_day_volume, 0.0, easeOutExp(lerp, 4))
|
|
night_ambient_audio.volume_db = lerp(orig_night_volume, -80.0, easeInExp(lerp, 4))
|
|
day_music.volume_db = lerp(orig_day_music_volume, target_music_audio, easeOutExp(lerp, music_lerp_exp))
|
|
night_music.volume_db = lerp(orig_night_music_volume, -80.0, easeInExp(lerp, music_lerp_exp))
|
|
|
|
await get_tree().process_frame
|
|
|
|
func change_shadow_casters(is_cast_on):
|
|
var shadow_mode
|
|
|
|
if is_cast_on:
|
|
shadow_mode = GeometryInstance3D.SHADOW_CASTING_SETTING_ON
|
|
else:
|
|
shadow_mode = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
|
|
|
|
for node in lamp_mesh_containers:
|
|
for mesh in node.get_children():
|
|
if mesh is MeshInstance3D:
|
|
mesh.cast_shadow = shadow_mode
|
|
for mesh in lamp_meshes:
|
|
mesh.cast_shadow = shadow_mode
|
|
|
|
func switch_visibility():
|
|
ui_cooldown = true
|
|
visible = !is_ui_hidden
|
|
await get_tree().create_timer(0.5).timeout
|
|
ui_cooldown = false
|
|
|
|
func _unhandled_input(event):
|
|
if event is InputEventKey:
|
|
match event.keycode:
|
|
KEY_H:
|
|
if !ui_cooldown:
|
|
is_ui_hidden = !is_ui_hidden
|
|
switch_visibility()
|
|
|
|
func easeInOutSine(lerp: float) -> float:
|
|
return clamp(-(cos(PI * lerp) - 1.0) / 2.0, 0.0, 1.0)
|
|
|
|
func easeInExp(x: float, exp: int) -> float:
|
|
return clamp(pow(x, exp), 0.0, 1.0)
|
|
|
|
func easeOutExp(x: float, exp: int) -> float:
|
|
return clamp(1.0 - pow(1.0 - x, exp), 0.0, 1.0)
|