# singleton.gd # This file is part of: SimpleGrassTextured # Copyright (c) 2023 IcterusGames # # 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. @tool extends Node3D var wind_direction := Vector3(1, 0, 0) : set = set_wind_direction var wind_strength := 0.15 : set = set_wind_strength var wind_turbulence := 1.0 : set = set_wind_turbulence var player_position := Vector3.ZERO : set = set_player_position var interactive := false : set = set_interactive var _RESOLUTION := 512.0 var _PIXEL_STEEP := Vector3(50.0 / _RESOLUTION, 50.0 / _RESOLUTION, 50.0 / _RESOLUTION) var _CAM_DIST := Vector3(0, 25, 0) var _wind_movement := Vector3.ZERO var _time_wind := 0.0 var _player_pos_snapped := Vector3.ZERO var _player_prev_pos := Vector3.ZERO var _player_mov := Vector3.ZERO var _gui_debug : VBoxContainer = null var _label_names_debug : Label = null var _label_datas_debug : Label = null var _timer_debug : Timer = null @onready var _height_view := $HeightMapView as SubViewport @onready var _height_cam := $HeightMapView/Camera as Camera3D @onready var _dist_view := $DistanceView as SubViewport @onready var _dist_cam := $DistanceView/Camera as Camera3D @onready var _dist_mesh := $DistanceView/Camera/Mesh as MeshInstance3D @onready var _motion1_view := $Motion1 as SubViewport @onready var _motion1_rect := $Motion1/Motion1Rect as ColorRect @onready var _motion2_view := $Motion2 as SubViewport @onready var _motion2_rect := $Motion2/Motion2Rect as ColorRect @onready var _normal_view := $Normal as SubViewport @onready var _normal_rect := $Normal/NormalRect as ColorRect @onready var _blur1_view := $Blur1 as SubViewport @onready var _blur1_rect := $Blur1/Blur1Rect as ColorRect @onready var _blur2_view := $Blur2 as SubViewport @onready var _blur2_rect := $Blur2/Blur2Rect as ColorRect func _ready() -> void: if ProjectSettings.has_setting("SimpleGrassTextured/General/interactive_resolution"): _RESOLUTION = ProjectSettings.get_setting_with_override("SimpleGrassTextured/General/interactive_resolution") elif OS.get_name() == "Android" or OS.get_name() == "iOS": _RESOLUTION = 256.0 _PIXEL_STEEP = Vector3(50.0 / _RESOLUTION, 50.0 / _RESOLUTION, 50.0 / _RESOLUTION) var using_legacy_renderer = ProjectSettings.get_setting_with_override("rendering/renderer/rendering_method") == "gl_compatibility" RenderingServer.global_shader_parameter_set(&"sgt_legacy_renderer", 1 if using_legacy_renderer else 0) wind_direction = ProjectSettings.get_setting("shader_globals/sgt_wind_direction", {"value":wind_direction}).value wind_strength = ProjectSettings.get_setting("shader_globals/sgt_wind_strength", {"value":wind_strength}).value wind_turbulence = ProjectSettings.get_setting("shader_globals/sgt_wind_turbulence", {"value":wind_turbulence}).value RenderingServer.global_shader_parameter_set(&"sgt_wind_direction", wind_direction) RenderingServer.global_shader_parameter_set(&"sgt_wind_strength", wind_strength) RenderingServer.global_shader_parameter_set(&"sgt_wind_turbulence", wind_turbulence) _height_cam.size = 50.0 _dist_cam.size = 50.0 _dist_mesh.mesh.size = Vector2(50.0, 50.0) _dist_view.size = Vector2i(int(_RESOLUTION), int(_RESOLUTION)) _dist_view.size_2d_override = _dist_view.size _dist_cam.physics_interpolation_mode = Node.PHYSICS_INTERPOLATION_MODE_OFF _height_cam.physics_interpolation_mode = Node.PHYSICS_INTERPOLATION_MODE_OFF _motion1_view.size = _dist_view.size _motion1_view.size_2d_override = _dist_view.size _motion2_view.size = _dist_view.size _motion2_view.size_2d_override = _dist_view.size _normal_view.size = _dist_view.size _normal_view.size_2d_override = _dist_view.size _blur1_view.size = _dist_view.size _blur1_view.size_2d_override = _dist_view.size _blur2_view.size = _dist_view.size _blur2_view.size_2d_override = _dist_view.size if Engine.is_editor_hint(): if not get_tree().has_user_signal(&"sgt_globals_params_changed"): get_tree().add_user_signal(&"sgt_globals_params_changed") get_tree().connect(&"sgt_globals_params_changed", _on_globals_params_changed) else: set_interactive(false) func _process(delta : float) -> void: if interactive: _player_pos_snapped = player_position.snapped(_PIXEL_STEEP) / 50.0 _player_mov = _player_prev_pos - _player_pos_snapped RenderingServer.global_shader_parameter_set(&"sgt_player_mov", _player_mov) _motion1_rect.material.set_shader_parameter(&"delta", delta) _player_prev_pos = _player_pos_snapped _dist_cam.global_position = player_position.snapped(_PIXEL_STEEP) - _CAM_DIST _height_cam.global_position = player_position + _CAM_DIST * 2 RenderingServer.global_shader_parameter_set(&"sgt_player_position", _player_pos_snapped) _time_wind += delta * wind_turbulence _wind_movement += wind_direction * delta * 0.1 * wind_strength _wind_movement.y = _time_wind RenderingServer.global_shader_parameter_set(&"sgt_wind_movement", _wind_movement) func set_player_position(global_pos : Vector3) -> void: player_position = global_pos func set_wind_direction(direction : Vector3) -> void: wind_direction = direction RenderingServer.global_shader_parameter_set(&"sgt_wind_direction", wind_direction) func set_wind_strength(strength : float) -> void: wind_strength = strength RenderingServer.global_shader_parameter_set(&"sgt_wind_strength", wind_strength) func set_wind_turbulence(turbulence : float) -> void: wind_turbulence = turbulence RenderingServer.global_shader_parameter_set(&"sgt_wind_turbulence", wind_turbulence) func set_wind_pattern(pattern : Texture) -> void: RenderingServer.global_shader_parameter_set(&"sgt_wind_pattern", pattern) func set_interactive(enable : bool) -> void: var mode := SubViewport.UPDATE_ALWAYS interactive = enable _dist_mesh.visible = interactive if not interactive: mode = SubViewport.UPDATE_ONCE _dist_mesh.material_override.set_shader_parameter(&"heightmap_texture", _height_view.get_texture()) _motion2_rect.material.set_shader_parameter(&"prev_depth", load("res://addons/simplegrasstextured/images/motion.png")) _motion1_rect.material.set_shader_parameter(&"prev_depth", load("res://addons/simplegrasstextured/images/motion.png")) _motion1_rect.material.set_shader_parameter(&"cur_depth", load("res://addons/simplegrasstextured/images/motion.png")) _normal_rect.material.set_shader_parameter(&"depth_texture", _motion1_view.get_texture()) _blur1_rect.material.set_shader_parameter(&"normal_texture", load("res://addons/simplegrasstextured/images/normal.png")) _blur2_rect.material.set_shader_parameter(&"normal_texture", load("res://addons/simplegrasstextured/images/normal.png")) RenderingServer.global_shader_parameter_set(&"sgt_normal_displacement", _blur2_view.get_texture()) RenderingServer.global_shader_parameter_set(&"sgt_motion_texture", _motion1_view.get_texture()) else: _dist_mesh.material_override.set_shader_parameter(&"heightmap_texture", _height_view.get_texture()) _motion2_rect.material.set_shader_parameter(&"prev_depth", _motion1_view.get_texture()) _motion1_rect.material.set_shader_parameter(&"prev_depth", _motion2_view.get_texture()) _motion1_rect.material.set_shader_parameter(&"cur_depth", _dist_view.get_texture()) _normal_rect.material.set_shader_parameter(&"depth_texture", _motion1_view.get_texture()) _blur1_rect.material.set_shader_parameter(&"normal_texture", _normal_view.get_texture()) _blur2_rect.material.set_shader_parameter(&"normal_texture", _blur1_view.get_texture()) RenderingServer.global_shader_parameter_set(&"sgt_normal_displacement", _blur2_view.get_texture()) RenderingServer.global_shader_parameter_set(&"sgt_motion_texture", _motion1_view.get_texture()) _height_view.render_target_update_mode = mode _dist_view.render_target_update_mode = mode _normal_view.render_target_update_mode = mode _blur1_view.render_target_update_mode = mode _blur2_view.render_target_update_mode = mode _motion1_view.render_target_update_mode = mode _motion2_view.render_target_update_mode = mode func is_interactive() -> bool: return interactive func set_debugger_visible(show_debugger : bool) -> void: if show_debugger: if _gui_debug == null: _gui_debug = VBoxContainer.new() _gui_debug.position = Vector2(10, 10) var hbox := HBoxContainer.new() hbox.custom_minimum_size.y = 155 _gui_debug.add_child(hbox) hbox.add_child(_new_debug_trect(_height_view.get_texture(), "Height map")) hbox.add_child(_new_debug_trect(_dist_view.get_texture(), "Distance")) hbox.add_child(_new_debug_trect(_motion1_view.get_texture(), "Motion #1")) hbox.add_child(_new_debug_trect(_motion2_view.get_texture(), "Motion #2")) hbox.add_child(_new_debug_trect(_normal_view.get_texture(), "Normal")) hbox.add_child(_new_debug_trect(_blur1_view.get_texture(), "Blur #1")) hbox.add_child(_new_debug_trect(_blur2_view.get_texture(), "Blur #2")) _label_names_debug = Label.new() _label_names_debug.label_settings = LabelSettings.new() _label_names_debug.label_settings.outline_color = Color.BLACK _label_names_debug.label_settings.font_size = 12 _label_names_debug.label_settings.outline_size = 2 _label_datas_debug = Label.new() _label_datas_debug.label_settings = _label_names_debug.label_settings var grid := GridContainer.new() grid.columns = 2 grid.add_child(_label_names_debug) grid.add_child(_label_datas_debug) _gui_debug.add_child(grid) add_child(_gui_debug) _timer_debug = Timer.new() _timer_debug.timeout.connect(_on_timer_debug) add_child(_timer_debug) _timer_debug.start(0.03) else: if _gui_debug != null: _gui_debug.queue_free() _gui_debug = null _timer_debug.queue_free() _timer_debug = null func is_debugger_visible() -> bool: return _gui_debug != null func _on_globals_params_changed() -> void: wind_direction = ProjectSettings.get_setting("shader_globals/sgt_wind_direction", {"value":wind_direction}).value wind_strength = ProjectSettings.get_setting("shader_globals/sgt_wind_strength", {"value":wind_strength}).value wind_turbulence = ProjectSettings.get_setting("shader_globals/sgt_wind_turbulence", {"value":wind_turbulence}).value func _new_debug_trect(texture : ViewportTexture, title : String) -> TextureRect: var trect := TextureRect.new() var label := Label.new() trect.expand_mode = TextureRect.EXPAND_FIT_WIDTH trect.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT trect.texture = texture label.text = title label.label_settings = LabelSettings.new() label.label_settings.outline_color = Color.BLACK label.label_settings.font_size = 12 label.label_settings.outline_size = 2 label.position.y = 155 trect.add_child(label) return trect func _on_timer_debug() -> void: var text1 := "" var text2 := "" text1 += "\nInteractive:" text2 += "\n" + str(interactive) text1 += "\nPlayer position:" text2 += "\n" + str(player_position) text1 += "\nPlayer movement:" text2 += "\n" + str(_player_mov) text1 += "\nWind direction:" text2 += "\n" + str(wind_direction) text1 += "\nWind strength:" text2 += "\n" + str(wind_strength) text1 += "\nWind turbulence:" text2 += "\n" + str(wind_turbulence) text1 += "\nWind movement:" text2 += "\n" + str(_wind_movement) text1 += "\nResolution:" text2 += "\n" + str(_RESOLUTION) text1 += "\nPixel steep:" text2 += "\n" + str(_PIXEL_STEEP) text1 += "\nCamera distance:" text2 += "\n" + str(_CAM_DIST) _label_names_debug.text = text1 _label_datas_debug.text = text2