Customizable Pulse Effect

This shader is just https://godotshaders.com/shader/shock-wave-animation/ at its core, but I made some modifications and added some more customization to it.

I could not have done this without the base shader, go give it a try if you just want something simple (like a generic shockwave)!

I might clean up this shader and add some more customization sometime later, but you can also do that if you’d like.

Shader code
shader_type canvas_item;

// ----------------------------------------------------------------
//
// Based on this shader:
// https://godotshaders.com/shader/shock-wave-animation/
//
// I made some modifications and added some more customization,
// but the base came from the shader above!!
// 
// ----------------------------------------------------------------

uniform float time_scale = 1.0; // The scale of time (just speeds up or slows down everything)
uniform vec4 primary_color : source_color = vec4(1.0, 0.0, 0.0, 1.0); // The primary color used
uniform vec4 secondary_color : source_color = vec4(0.0, 1.0, 0.0, 1.0); // The secondary color used
uniform float turbulence = 0.2; // Essentially the size of the distortion pattern (higher number means more pattern shown)
uniform float distortion = 0.1; // How pronounced the distortion pattern will be
uniform float ring_count_influence = 10.0; // An influence as to how many rings there will be (higher number means more rings generally)
uniform bool go_backwards = false; // Whether or not the pulse will go inwards
uniform float alpha_blend: hint_range(-1.0, 10.0) = 0.1; // The alpha channel for the final color mixing
uniform vec3 color_mix : source_color = vec3(1.0); // The color to mix with for the final color mixing; use pure black to only use the primary and secondary colors
uniform float distortion_speed = 1.0; // The speed of the distortion's scrolling
uniform float ring_speed = 1.0; // The speed of the moving rings
uniform float final_alpha_multi : hint_range(0.1, 10.0, 0.01) = 1.0; // The multiplier of the final alpha value
uniform float opacity_smoothstep_1 : hint_range(-10.0, 25.0, 0.01) = -0.25; // The first value for smoothstepping the opacity
uniform float opacity_smoothstep_2 : hint_range(-10.0, 25.0, 0.01) = 1.5; // The second value for smoothstepping the opacity

void fragment() {
	float time = TIME * time_scale;
	
	vec2 uv = (UV - vec2(0.5)) * vec2(2.0); // The current UV coordinate, scaled to fit the current object
	float dist = length(uv); // Distance
	
	// Calculating the opacity of the current pixel
	float opacity;
	if (go_backwards) { opacity = sin(dist * ring_count_influence + time * ring_speed) * 0.5 + 0.5; }
	else { opacity = sin(dist * ring_count_influence - time * ring_speed) * 0.5 + 0.5; }
	
	// Making the opacity be greater towards the center with some bias
	// Tweak the first two values to your use case if you want, I had to as well
	opacity *= smoothstep(opacity_smoothstep_1, opacity_smoothstep_2, 1.0 - dist);
	
	// Mixing the two colors together, with a pattern from the sine of the time
	vec4 color = mix(primary_color, secondary_color, abs(sin(time))) * dist;
	
	// Honestly I didn't mess around with this enough to understand it, sorry about that
	uv += vec2(sin(uv.y * turbulence / dist), cos(uv.x * turbulence / dist)) * distortion;
	
	// I wanted rotation, so I made rotation. I'll maybe make this a boolean uniform at some point
	float angle = time * distortion_speed; // You can scale time here to speed up rotation
	mat2 rotation = mat2(vec2(cos(angle), -sin(angle)), vec2(sin(angle), cos(angle)));
	vec2 rotated_uv = rotation * uv; // If you don't want rotation to be applied, you can simply set the rotated_uv to just be uv, instead of rotation * uv
	
	// This is essentially just an offset to the uv
	vec2 distorted_uv = rotated_uv + vec2(sin(rotated_uv.y * turbulence + time), cos(rotated_uv.x * turbulence + time)) * distortion;
	
	
	// Get the final color by mixing the current color with the color mix and the alpha blend
	// The length being of the distorted UV is to give it some variety. You can replace it with the regular UV if you want
	vec4 final_color = mix(color, vec4(color_mix, alpha_blend), length(distorted_uv));
	
	final_color.a *= final_alpha_multi;
	
	// Prevent the final alpha from becoming negative and making overlaps look weird
	final_color.a = clamp(final_color.a, 0.0, 1.0);
	
	// Finally, set the dang color of the pixel
	COLOR = vec4(final_color.rgb, final_color.a * opacity);
}
Live Preview
Tags
circle, circular, customizable, customization, pulse, shockwave
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.

Related shaders

guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments