Vortex overlay
A colorRect that causes the elipse of pixels behind it to rotate.
Uniforms:
rotation_offset – rotates the entire elipse by this amount
intensity – pixels will rotate in proportion to its distance from the edge of the elipse. Up to *intensity* full rotations
invert – if true, pixels will instead rotate in proportion to its distance from the center of the elipse.
rel_rect_size – The size of the colorRect relative to the viewport. Must be set in the node script
max_blend – The color of the colorRect will be mixed into the effect at most this amount, at the center of the vortex.
The effect will not work in the editor, as it uses the screenUV
extends ColorRect
func _ready():
material.duplicate()
adjustRect():
func adjustRect():
material.set_shader_param("rel_rect_size", get_canvas_transform().get_scale()*rect_size)
func _process(_delta):
adjustRect()
Shader code
shader_type canvas_item;
uniform float max_blend : hint_range(0,1) = 0.5;
uniform float rotation_offset = 0;
uniform float intensity : hint_range(0, 10);
uniform bool invert = false;
uniform vec2 rel_rect_size = vec2(1024, 600);
float distFromCen(vec2 p) {
return distance(p, vec2(0.5));
}
//rotates by angle radians
vec2 rotate(vec2 p, float angle){
return vec2(cos(angle)*p.x-sin(angle)*p.y, sin(angle)*p.x + cos(angle)*p.y);
}
void fragment() {
vec4 c = COLOR;
float distMod = invert ? distFromCen(UV) : 0.5 - distFromCen(UV);
float angle = intensity * distMod * 6.28318 + rotation_offset;
vec2 newp = rotate(UV-vec2(0.5), angle) + vec2(0.5);
vec2 disp = (newp - UV) * rel_rect_size * SCREEN_PIXEL_SIZE;
disp.y = -disp.y; // for some reason UV and SCEEN_UV are inveresed
COLOR = mix(texture(SCREEN_TEXTURE, SCREEN_UV + disp), c, max_blend * 2.0 * (0.5-distFromCen(UV)));
//COLOR = c;
//Doesn'[t apply effect outside of circle]
if (distFromCen(UV) > 0.5) {
COLOR = texture(SCREEN_TEXTURE, SCREEN_UV);
}
}