Blast Wall
This deformation fragment shader simulates a shockwave with (ridiculous) chromatic aberration. Use this shader as a material in a canvas object (Sprite, ColorRect, etc.) on top of a scene (using a CanvasLayer or a back buffer) to apply the effect on the whole screen. This may also work on sprite content (use TEXTURE and UV instead of SCREEN_TEXTURE and SCREEN_UV).
Parameters are:
- center : Center of the explosion in screen coordinate (be aware that you’ll need to scale the coordinate using (viewport_size / container_size) and revert the Y position using viewport_size.y – center.y)
- force : Explosion force. Determines the deformation strenght.
- size : Size of the blast wave.
- blast : Size of the blast.
- direction : 2D vector determining the direction of the blast.
- aperture : Opening angle of the blast (in radians).
- red_offset, green_offset, blue_offset : Chromatic aberration ratio. 1 = no aberration.
Of course, this shader is meant to be animated (see screenshot).
Update : Using FRAGCOORD instead to avoid deformation induced by container and/or screen ratio.
Shader code
shader_type canvas_item;
uniform vec2 center;
uniform float force;
uniform float size;
uniform float blast;
uniform vec2 direction;
uniform float aperture : hint_range(0.0, 3.141516, 0.001);
uniform float red_offset : hint_range(0.0, 2.0, 0.001);
uniform float green_offset : hint_range(0.0, 2.0, 0.001);
uniform float blue_offset : hint_range(0.0, 2.0, 0.001);
vec2 scale(vec2 coord, vec2 scale) {
return coord * scale;
}
void fragment() {
float dist = distance(FRAGCOORD.xy, center);
vec2 norm = normalize(FRAGCOORD.xy - center);
float angle = acos(dot(normalize(vec2(-direction.x, direction.y)), -norm));
float mask = cos((angle * 1.5707963268) / (aperture + .00001)) * step(angle, aperture) * force;
float blast_mask = smoothstep(blast - size/2., blast, dist);
float total_size = blast + (size / 2.);
vec3 offsets = vec3(red_offset, green_offset, blue_offset);
vec3 forces = offsets * mask * blast_mask;
vec3 raw_eases = total_size * offsets;
raw_eases = clamp(dist / raw_eases, vec3(0.), vec3(1.));
vec3 easings = pow(raw_eases, forces);
vec3 deforms = easings * dist;
COLOR = vec4(
texture(SCREEN_TEXTURE, scale(center + (deforms.r * norm), SCREEN_PIXEL_SIZE)).r,
texture(SCREEN_TEXTURE, scale(center + (deforms.g * norm), SCREEN_PIXEL_SIZE)).g,
texture(SCREEN_TEXTURE, scale(center + (deforms.b * norm), SCREEN_PIXEL_SIZE)).b,
1.0);
}
This is awesome looking. Is there any chance you could post what the code should look like for use on a SPRITE in GD4?
Hi ! Sorry for the late answer.
I’m currently working on porting my shaders to GD4. I hope to finish soon. Thanks !