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))