Blur with Clearing Over a Node
This shader is designed for a scenario like a tutorial or intro where you want to highlight a particular thing on the screen but blur everything else. It should be used in concert with gdscript where you tell it what node you want to highlight (ie keep clear). For the calculations to be right, this shader should be applied to a TextureRect that is the full size of your application dimensions. The node you want to highlight must be something that has “rect_size”. If you are using a sprite, put it inside a node type that has rect_size.
Note: If you just have the need to do this one time for something static, is it much easier to just put the highlighted object above the overlay.
Im this example, my textureRect is called ScreenOverlay and I want to highlight a node called Bomb, and used this gdscript:
extends Node
onready var bomb = $Bomb
onready var screen_overlay = $ScreenOverlay
func _ready():
pass
func _process(delta):
update_shader_exclude_area()
func update_shader_exclude_area():
var bomb_global_rect = bomb.rect_size
var bomb_center = bomb.rect_position + bomb.rect_size * 0.5
var bomb_size =bomb.rect_size
var screen_size = screen_overlay.rect_size
var normalized_center = bomb_center / screen_size
var normalized_size = bomb_size / screen_size
screen_overlay.material.set_shader_param("exclude_center", normalized_center)
screen_overlay.material.set_shader_param("exclude_size", normalized_size)
Shader code
shader_type canvas_item;
uniform vec2 exclude_center; // Center of the area to exclude from blur
uniform vec2 exclude_size; // Size of the area to exclude from blur
uniform float lod: hint_range(0.0, 5) = 0.0;
void fragment() {
vec2 uv = UV;
// Check if the current pixel is inside the excluded area
bool is_inside_exclude_area =
uv.x > exclude_center.x - exclude_size.x / 2.0 &&
uv.x < exclude_center.x + exclude_size.x / 2.0 &&
uv.y > exclude_center.y - exclude_size.y / 2.0 &&
uv.y < exclude_center.y + exclude_size.y / 2.0;
if (is_inside_exclude_area) {
// If inside the excluded area, just output the original texture
COLOR = vec4(0.0, 0.0, 0.0, 0.0);
} else
{
vec4 color = texture(SCREEN_TEXTURE, SCREEN_UV, lod);
COLOR = color;
}
}