187 lines
5.7 KiB
GDScript
187 lines
5.7 KiB
GDScript
@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
|
||
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"))
|