2026-03-19 11:35:38 -05:00

272 lines
12 KiB
GDScript

# 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