(Almost) Invisible Character

Given a sprite, this shader gives it the ability to become invisible and fade into the background. But the ability is not flawless and the background is slightly deformed by the invisibility cloaking.

The shader offers two uniforms:

  1. alpha, ranging from 0 (no cloaked) to 1 (fully cloaked).
  2. dist, specifying the offset of the background in pixels.
Shader code
shader_type canvas_item;

const float pi = 3.14156;

uniform float dist = 16.;
uniform float alpha : hint_range(0., 1.) = 1.;

void fragment() {
	vec2 backgroundUV = FRAGCOORD.xy * SCREEN_PIXEL_SIZE.xy;
	
	vec2 offsetR = vec2(dist * SCREEN_PIXEL_SIZE.x * cos(TIME * 2. * pi),        dist * SCREEN_PIXEL_SIZE.x * cos(TIME*0.7 * 2. * pi));
	vec2 offsetG = vec2(dist * SCREEN_PIXEL_SIZE.x * cos(1. + (TIME * 2. * pi)), dist * SCREEN_PIXEL_SIZE.x * cos(3. + (TIME*0.7 * 2. * pi)));
	vec2 offsetB = vec2(dist * SCREEN_PIXEL_SIZE.x * cos(TIME * 1.5 * pi),       dist * SCREEN_PIXEL_SIZE.x * cos(TIME*0.9 * 2. * pi));
	
	vec4 backColR = texture(SCREEN_TEXTURE, SCREEN_UV + offsetR);
	vec4 backColG = texture(SCREEN_TEXTURE, SCREEN_UV + offsetG);
	vec4 backColB = texture(SCREEN_TEXTURE, SCREEN_UV + offsetB);
	
	vec4 texCol = texture(TEXTURE, UV);
	
	COLOR = mix(texCol, texCol.a * vec4(backColR.r, backColG.g, backColB.b, 1.0), alpha);
}
Tags
2d, Invisibility, opacity
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from CasualGarageCoder

Ring of Power

Shield with impact waves

Chromatic Chaos Distortion

Subscribe
Notify of
guest

1 Comment
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
FranThe3rd
FranThe3rd
3 months ago

shader_type canvas_item;
uniform sampler2D SCREEN_TEXTURE : hint_screen_texture,filter_linear_mipmap;
const float pi = 3.14156;

uniform float dist = 16.;
uniform float alpha : hint_range(0., 1.) = 1.;

void fragment() {
vec2 backgroundUV = FRAGCOORD.xy * SCREEN_PIXEL_SIZE.xy;

vec2 offsetR = vec2(dist * SCREEN_PIXEL_SIZE.x * cos(TIME * 2. * pi),    dist * SCREEN_PIXEL_SIZE.x * cos(TIME*0.7 * 2. * pi));
vec2 offsetG = vec2(dist * SCREEN_PIXEL_SIZE.x * cos(1. + (TIME * 2. * pi)), dist * SCREEN_PIXEL_SIZE.x * cos(3. + (TIME*0.7 * 2. * pi)));
vec2 offsetB = vec2(dist * SCREEN_PIXEL_SIZE.x * cos(TIME * 1.5 * pi),    dist * SCREEN_PIXEL_SIZE.x * cos(TIME*0.9 * 2. * pi));

vec4 backColR = texture(SCREEN_TEXTURE, SCREEN_UV + offsetR);
vec4 backColG = texture(SCREEN_TEXTURE, SCREEN_UV + offsetG);
vec4 backColB = texture(SCREEN_TEXTURE, SCREEN_UV + offsetB);

vec4 texCol = texture(TEXTURE, UV);

COLOR = mix(texCol, texCol.a * vec4(backColR.r, backColG.g, backColB.b, 1.0), alpha);
}