JFA_driven_motion_blur_demo/Scripts/UIController.gd
2024-07-06 21:22:05 +03:00

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)