43 lines
1.6 KiB
GDScript3
43 lines
1.6 KiB
GDScript3
|
|
extends ColorRect
|
||
|
|
|
||
|
|
# #125: drives breach.gdshader.
|
||
|
|
#
|
||
|
|
# Lives in the UI layer because it works in SCREEN space - it bends the
|
||
|
|
# rendered frame, so it has to be the last thing drawn and it has to cover
|
||
|
|
# the whole viewport. The world-space half of the breach (the horizon, the
|
||
|
|
# accretion disc, the infalling matter) is DimensionalBreach, a Node2D out
|
||
|
|
# in the world; this is only the lens over the top of it.
|
||
|
|
#
|
||
|
|
# Inert unless something calls set_breach(): the shader is a no-op at zero
|
||
|
|
# strength, but a full-screen quad that is never needed is still a full
|
||
|
|
# screen of fragment work, so it hides itself instead.
|
||
|
|
|
||
|
|
const SHADER_PATH: String = "res://shaders/breach.gdshader"
|
||
|
|
|
||
|
|
|
||
|
|
func _ready() -> void:
|
||
|
|
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
||
|
|
visible = false
|
||
|
|
if material == null:
|
||
|
|
var shader_material := ShaderMaterial.new()
|
||
|
|
shader_material.shader = load(SHADER_PATH)
|
||
|
|
material = shader_material
|
||
|
|
|
||
|
|
|
||
|
|
func clear_breach() -> void:
|
||
|
|
visible = false
|
||
|
|
if material != null:
|
||
|
|
material.set_shader_parameter("strength", 0.0)
|
||
|
|
|
||
|
|
|
||
|
|
# `at` is in SCREEN pixels; the director projects the world point through the
|
||
|
|
# camera before calling, because only it knows where the camera is.
|
||
|
|
func set_breach(at: Vector2, horizon: float, lens: float, breach_strength: float) -> void:
|
||
|
|
if material == null:
|
||
|
|
return
|
||
|
|
visible = breach_strength > 0.001
|
||
|
|
material.set_shader_parameter("breach_center", at)
|
||
|
|
material.set_shader_parameter("viewport_size", size)
|
||
|
|
material.set_shader_parameter("horizon_radius", horizon)
|
||
|
|
material.set_shader_parameter("lens_radius", maxf(lens, horizon + 1.0))
|
||
|
|
material.set_shader_parameter("strength", clampf(breach_strength, 0.0, 1.0))
|