Positioned Shockwave

Based on the shockwave shader tutorial by Nolkaloid: https://www.youtube.com/watch?v=SCHdglr35pk

The shader itself is the same, but now you can pass the [global position of the object – global position of the camera] to the global_position uniform of the shader to make the shockwave emit from the object.

Shader code
shader_type canvas_item;

uniform vec2 global_position;
uniform vec2 screen_size;
uniform float force;
uniform float size;
uniform float thickness;

void fragment(){
	vec2 center = global_position;
	float ratio = SCREEN_PIXEL_SIZE.x / SCREEN_PIXEL_SIZE.y;
	center.x = center.x / screen_size.x;
	center.x = (center.x - 0.5) / ratio + 0.5;
	center.y = (screen_size.y - center.y) / screen_size.y;
	vec2 scaledUV = (SCREEN_UV - vec2(0.5, 0.0) ) / vec2(ratio, 1.0) + vec2(0.5, 0.0);
	float mask = (1.0 - smoothstep(size-0.1, size, length(scaledUV - center))) * smoothstep(size-thickness-0.1, size-thickness, length(scaledUV - center));
	vec2 disp = normalize(SCREEN_UV - center) * force * mask;
	COLOR = texture(SCREEN_TEXTURE, SCREEN_UV - disp);
}
Tags
explosion, shockwave
The shader code and all code snippets in this post are under MIT license and can be used freely. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

Related shaders

Distortion/Shockwave Shader

Subscribe
Notify of
guest

8 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
snesmocha
3 years ago

um, we posted the same shader………

snesmocha
3 years ago
Reply to  pekopekorhino

huh didn’t realize that

Pandemic
2 years ago

Will this shader work in a 3D scene? I would like the shockwave appear to emanate from a 3D node.

eerbin13
eerbin13
10 months ago

This does not appear to work well in Godot 4.

nd123
nd123
6 months ago
Reply to  eerbin13

yes! cause it was made for godot 3

kotapi
kotapi
6 months ago

Anyone had luck using this for Godot 4?

falkri
falkri
4 months ago
Reply to  kotapi

I managed to get it working by calculating the scaled center position for the original shader script. Using the get_screen_center_position() will make sure the visible global position is taken even when the camera limits are hit and the camera zoom’s effect on the viewport.

var target = get_tree().get_first_node_in_group(‘Enemies’)
var viewport_size := get_viewport_rect().size
var zoomed_view := viewport_size / cam.zoom

var cam_relative_pos = (target.global_position – cam.get_screen_center_position()) \
+ zoomed_view / 2.0
var ratio = zoomed_view.x / zoomed_view.y

var x = cam_relative_pos.x / zoomed_view.x
var y = cam_relative_pos.y / zoomed_view.y
x = (x – 0.5) * ratio + 0.5 # reversing the effect of scaling in shader

shock_material.set_shader_parameter(‘center’, Vector2(x,y))

Last edited 4 months ago by falkri