xiandie/scene/shading/shading_layer.gd

221 lines
6.8 KiB
GDScript3
Raw Normal View History

@tool
class_name ShadingLayer extends CanvasLayer
@export_enum("vignette", "fog", "glitch", "palette", "chromatic_abberation")
var mode: Array[String] = ["vignette"] as Array[String]:
set(new_val):
mode = new_val
_setup_visibility()
@export_group("Vignette", "vignette_")
@export var vignette_rgb := Color8(0x3f, 0x26, 0x31):
set(new_val):
vignette_rgb = new_val
if is_node_ready():
%Vignette.material.set("shader_parameter/vignette_rgb", new_val)
@export_range(0, 5) var vignette_intensity := 0.3:
set(new_val):
vignette_intensity = new_val
if is_node_ready():
%Vignette.material.set("shader_parameter/vignette_intensity", new_val)
@export_group("Fog", "fog_")
const fog_frame_count = 24 # 0-23
@export var fog_offset := FOG_OFFSET_DEFAULT:
set(new_val):
fog_offset = new_val
if is_node_ready():
%Fog.offset = new_val
@export var fog_frame := FOG_FRAME_DEFAULT:
set(new_val):
fog_frame = new_val
if is_node_ready():
%Fog.frame = new_val
@export var fog_modulate := FOG_COLOR_DEFAULT:
set(new_val):
fog_modulate = new_val
if is_node_ready():
%Fog.self_modulate = new_val
# @export var fog_offset := Vector2(0.0, 0.0):
# set(new_val):
# fog_offset = new_val
# if not is_node_ready():
# return
# %Fog.texture.noise.set("offset", new_val)
# @export var fog_base_color := Color8(0xff, 0xff, 0xff, 0x3d):
# set(new_val):
# fog_base_color = new_val
# if not is_node_ready():
# return
# %Fog.material.set("shader_parameter/base_color", new_val)
@export_group("Glitch", "glitch_")
@export var glitch_power := 0.001:
set(new_val):
glitch_power = new_val
if is_node_ready():
%GlitchEffect.material.set("shader_parameter/shake_power", new_val)
# rate
@export var glitch_rate := 0.2:
set(new_val):
glitch_rate = new_val
if is_node_ready():
%GlitchEffect.material.set("shader_parameter/shake_rate", new_val)
# speed
@export var glitch_speed := 5.0:
set(new_val):
glitch_speed = new_val
if is_node_ready():
%GlitchEffect.material.set("shader_parameter/shake_speed", new_val)
# block_size
@export var glitch_block_size := 30.5:
set(new_val):
glitch_block_size = new_val
if not is_node_ready():
return
%GlitchEffect.material.set("shader_parameter/shake_block_size", new_val)
# color rate
@export var glitch_color_rate := 0.01:
set(new_val):
glitch_color_rate = new_val
if is_node_ready():
%GlitchEffect.material.set("shader_parameter/shake_color_rate", new_val)
@export_group("Palette", "palette_")
@export var palette_texture := preload("res://asset/shader/palette/bloodmoon21-1x.png"):
set(new_val):
palette_texture = new_val
if is_node_ready():
%Palette.material.set("shader_parameter/palette", new_val)
func _ready() -> void:
%Sprite2D.visible = false
layer = GlobalConfig.CANVAS_LAYER_SHADING
# set up other properties
%Vignette.material.set("shader_parameter/vignette_rgb", vignette_rgb)
%Vignette.material.set("shader_parameter/vignette_intensity", vignette_intensity)
%Fog.frame = fog_frame
%Fog.offset = fog_offset
%Fog.self_modulate = fog_modulate
# %Fog.texture.noise.set("offset", fog_offset)
# %Fog.material.set("shader_parameter/base_color", fog_base_color)
%GlitchEffect.material.set("shader_parameter/shake_power", glitch_power)
%GlitchEffect.material.set("shader_parameter/shake_rate", glitch_rate)
%GlitchEffect.material.set("shader_parameter/shake_speed", glitch_speed)
%GlitchEffect.material.set("shader_parameter/shake_block_size", glitch_block_size)
%GlitchEffect.material.set("shader_parameter/shake_color_rate", glitch_color_rate)
%Palette.material.set("shader_parameter/palette", palette_texture)
# set up visibility
_setup_visibility()
func _setup_visibility():
if not is_node_ready():
return
%Vignette.visible = mode.has("vignette")
%Fog.visible = mode.has("fog")
%GlitchEffect.visible = mode.has("glitch")
%Palette.visible = mode.has("palette")
%ChromaticAbberation.visible = mode.has("chromatic_abberation")
func erase_mode(mode_name: String) -> void:
if mode.has(mode_name):
mode.erase(mode_name)
_setup_visibility()
func add_mode(mode_name: String) -> void:
if not mode.has(mode_name):
mode.append(mode_name)
_setup_visibility()
#### Tween fog ####
const FOG_COLOR_DEFAULT = Color(0.8, 0.8, 0.8, 0.5)
const FOG_COLOR_WHITE = Color(1, 1, 1, 1)
const FOG_COLOR_BLACK = Color(0, 0, 0, 1)
const FOG_COLOR_GRAY = Color(0.5, 0.5, 0.5, 1)
const FOG_COLOR_DARK_GRAY = Color(0.2, 0.2, 0.2, 1)
const FOG_FRAME_MIN = 0
2025-01-31 10:25:47 +00:00
const FOG_FRAME_DEFAULT = 23 #原15
const FOG_FRAME_MAX = 23
const FOG_OFFSET_DEFAULT = Vector2(0, 50)
var _fog_tween: Tween
func show_default_fog(duration := 0.8):
if not mode.has("fog"):
add_mode("fog")
fog_modulate = Color.TRANSPARENT
tween_fog(FOG_FRAME_DEFAULT, FOG_COLOR_DEFAULT, FOG_OFFSET_DEFAULT, duration)
func close_fog(duration := 0.8):
if mode.has("fog"):
tween_fog(fog_frame, Color.TRANSPARENT, fog_offset, duration, true)
func tween_fog(
end_frame := fog_frame,
end_modulate := fog_modulate,
end_offset := fog_offset,
duration := 0.8,
close_at_end := false
) -> void:
if not is_node_ready():
return
if GlobalConfig.DEBUG:
print(
"Tween fog to frame: ", end_frame, " modulate: ", end_modulate, " offset: ", end_offset
)
if not mode.has("fog"):
# 如果没有开启 fog先开启并且设置为透明
add_mode("fog")
fog_modulate = Color.TRANSPARENT
if _fog_tween and _fog_tween.is_valid():
_fog_tween.kill()
_fog_tween = create_tween()
_fog_tween.tween_property(%Fog, "frame", end_frame, duration)
if end_modulate != fog_modulate:
_fog_tween.parallel().tween_property(%Fog, "self_modulate", end_modulate, duration)
if end_offset != fog_offset:
_fog_tween.parallel().tween_property(%Fog, "offset", end_offset, duration)
if close_at_end:
_fog_tween.tween_callback(erase_mode.bind("fog"))
2025-03-17 14:12:53 +00:00
# vignette 闪烁
func flash_vignette(color: Color) -> void:
if not is_node_ready():
return
if GlobalConfig.DEBUG:
print("Flash vignette with color: ", color)
var original_vignette_rgb = vignette_rgb
var original_vignette_intensity = vignette_intensity
var v = %Vignette
var display = v.visible
v.visible = true
var tween = create_tween()
tween.tween_property(self, "vignette_rgb", color, 0.2)
tween.parallel().tween_property(self, "vignette_intensity", 5.0, 0.2).from(0.0)
tween.tween_interval(0.4)
tween.tween_property(self, "vignette_rgb", original_vignette_rgb, 0.2)
tween.parallel().tween_property(self, "vignette_intensity", original_vignette_intensity, 0.2)
tween.tween_callback(v.set.bind("visible", display))
# palette 闪烁
func flash_palette(duration := 0.5) -> void:
if not is_node_ready():
return
add_mode("palette")
get_tree().create_timer(duration).timeout.connect(erase_mode.bind("palette"))
# glitch 闪烁
func flash_glitch(duration := 1.0) -> void:
if not is_node_ready():
return
add_mode("glitch")
get_tree().create_timer(duration).timeout.connect(erase_mode.bind("glitch"))