cartoon explosion effect

https://www.shadertoy.com/view/X3dGz2

Shader code
shader_type canvas_item;

#define iTime TIME
#define iResolution 1.0/SCREEN_PIXEL_SIZE
#define fragColor COLOR

uniform vec3 boom_pal1 = vec3(.2, .15, .3);
uniform vec3 boom_pal2 = vec3(.9, .15, .05);
uniform vec3 boom_pal3 = vec3(.9, .5, .1);
uniform vec3 boom_pal4 = vec3(.95, .95, .35);

uniform vec3 smoke_pal1 = vec3(.2, .15, .3);
uniform vec3 smoke_pal2 = vec3(.35, .3, .45);
uniform vec3 smoke_pal3 = vec3(.5, .45, .6);

uniform float size : hint_range(0.1, 50.0, 0.1) = 5.;
uniform float disperse : hint_range(0.1, 10.0, 0.1) = 1.;
uniform float boom_repeat : hint_range(0.0, 10.0, 0.1) = 1.;
uniform float boom_shape : hint_range(0.1, 20.0, 0.1) = 12.;
uniform float boom_distortion : hint_range(0.0, 10.0, 0.1) = .5;
uniform float boom_bubbles : hint_range(0.0, 10.0, 0.1) = .5;
uniform float boom_bw : hint_range(0.0, 10.0, 0.1) = .5;

uniform float smoke_repeat : hint_range(0.0, 10.0, 0.1) = 1.0;
uniform float smoke_shape : hint_range(0.0, 30.0, 0.1) = 16.0;
uniform float smoke_distortion : hint_range(0.0, 10.0, 0.1) = 1.5;
uniform float smoke_bubbles : hint_range(0.0, 10.0, 0.1) = 0.5;
uniform float smoke_bw : hint_range(0.0, 10.0, 0.1) = .75;

uniform vec2 disp = vec2(0.0);

vec3 n_rand3(vec3 p) {
    vec3 r = 
        fract(
            sin(
                vec3(
                    dot(p, vec3(127.1,311.7,371.8)),
                    dot(p,vec3(269.5,183.3,456.1)),
                    dot(p,vec3(352.5,207.3,198.67))
                )
            ) * 43758.5453
        ) * 2.0 - 1.0;
    return normalize(vec3(r.x/cos(r.x), r.y/cos(r.y), r.z/cos(r.z)));
}

float noise(vec3 p) {

    vec3 fv = fract(p);
    vec3 nv = vec3(floor(p));
    
    vec3 u = fv*fv*fv*(fv*(fv*6.0-15.0)+10.0);
    
    return (
        mix(
            mix(
                mix(
                    dot( n_rand3( nv+vec3(0.0,0.0,0.0) ), fv-vec3(0.0,0.0,0.0)), 
                    dot( n_rand3( nv+vec3(1.0,0.0,0.0) ), fv-vec3(1.0,0.0,0.0)), 
                    u.x
                ), 
                mix(
                    dot( n_rand3( nv+vec3(0.0,1.0,0.0) ), fv-vec3(0.0,1.0,0.0)), 
                    dot( n_rand3( nv+vec3(1.0,1.0,0.0) ), fv-vec3(1.0,1.0,0.0)), 
                    u.x
                ), 
                u.y
            ),
            mix(
                mix(
                    dot( n_rand3( nv+vec3(0.0,0.0,1.0) ), fv-vec3(0.0,0.0,1.0)), 
                    dot( n_rand3( nv+vec3(1.0,0.0,1.0) ), fv-vec3(1.0,0.0,1.0)), 
                    u.x
                ), 
                mix(
                    dot( n_rand3( nv+vec3(0.0,1.0,1.0) ), fv-vec3(0.0,1.0,1.0)), 
                    dot( n_rand3( nv+vec3(1.0,1.0,1.0) ), fv-vec3(1.0,1.0,1.0)), 
                    u.x
                ), 
                u.y
            ),
            u.z
       )
  );
}

float worley(vec3 s)
{
    vec3 si = floor(s);
    vec3 sf = fract(s);

    float m_dist = 1.;  

    for (int y= -1; y <= 1; y++) {
        for (int x= -1; x <= 1; x++) {
            for (int z= -1; z <= 1; z++) {
                vec3 neighbor = vec3(float(x),float(y), float(z));

                vec3 point = fract(n_rand3(si + neighbor));
                point = 0.5 + 0.5*sin(disperse * iTime + 6.2831*point);

                vec3 diff = neighbor + point - sf;

                float dist = length(diff);

                m_dist = min(m_dist, dist);
            }
        }
    }

    return m_dist;
}

float oct_noise(vec3 pos, float o)
{

    float ns = 0.0;
    float d = 0.0;
    
    int io = int(o);
    float fo = fract(o);
    
    for(int i=0;i<=io;++i)
    {
        float v = pow(2.0,float(i));
        d += 1.0/v;
        ns += noise(pos*v)*(1.0/v);
    }
    
    
    float v = pow(2.0,float(io+1));
    d+= 1.0*fo/v;
    ns += noise(pos*v)*(1.0*fo/v);
    
    return ns/d;
}

float boom (vec2 p)
{
    float repeat = mod(iTime * boom_repeat, 2.);
    float shape = 1.-pow(distance(vec3(p, 0.), vec3(0.)),2.) / (repeat*boom_shape) - repeat*2.;
    
    float distortion = noise(vec3(p*boom_distortion, iTime*.5));
    float bubbles = boom_bubbles-pow(worley(vec3(p*1.2,iTime*2.)), 3.);
    float bw = boom_bw;
    float effects = (bw * bubbles + (1.-bw) * distortion);

    return shape + effects;
}

float smoke (vec2 p)
{
    float repeat = mod(iTime * smoke_repeat, 2.);
    float shape = 1.-pow(distance(vec3(p - vec2(0, 2) * pow(repeat/1.45,2.)*1.5, 0.), vec3(0.)),2.) / (repeat* smoke_shape) - pow(repeat*1.5,.5);
    
    float distortion = noise(vec3(p*smoke_distortion - vec2(0, 2) * pow(repeat/1.45,2.)*1.5, iTime*.1));
    float bubbles = smoke_bubbles-pow(worley(vec3((p/pow(repeat,.35)) - vec2(0, 2) * pow(repeat/1.65,2.)*1.5, iTime*.1)), 2.);
    float bw = smoke_bw;
    float effects = (bw * bubbles + (1.-bw) * distortion);

    return shape + effects;
}

float f (vec2 p){
    float b = boom(p);
    float s = smoke(p);
    return b > s ? b : s;
}

vec2 grad( vec2 x )
{
    vec2 h = vec2( 0.01, 0.0 );
    return vec2( f(x+h.xy) - f(x-h.xy),
                 f(x+h.yx) - f(x-h.yx) )/(2.0*h.x);
}

float border (vec2 uv)
{

    float b = f( uv );
    vec2  g = grad( uv );
    float de = abs(b)/length(g);
    float eps = .01;
    
    return smoothstep( 1.0*eps, 2.0*eps, de );
}

float posterize(float v, int n)
{
    float fn = float(n);
    return floor(v*fn)/(fn-1.);
}

void fragment()
{
	vec3 boom_pal[4] = {
	 boom_pal1,
    boom_pal2,
    boom_pal3,
    boom_pal4
	};

vec3 smoke_pal[] = 
    {smoke_pal1,
    smoke_pal2,
    smoke_pal3};

    vec2 uv = SCREEN_UV;
	uv.y = 1.0 -uv.y;
    vec2 pos = uv - vec2(.5, .4);
    pos.x /= SCREEN_PIXEL_SIZE.x / SCREEN_PIXEL_SIZE.y;
    pos *= 1. * size;
    pos = pos - disp;
	
    int bpl = boom_pal.length();
    int spl = smoke_pal.length();


    float boom_val = boom(pos);
    float boom_a = step(0., boom_val);
    vec3 boom_col = boom_pal[int(posterize(boom_val, bpl)*float(bpl))] - vec3(1.-boom_a);
    
    float smoke_val = smoke(pos);
    float smoke_a = step(0., smoke_val);
    vec3 smoke_col = smoke_pal[int(posterize(smoke_val, spl)*float(spl))] - vec3(1.-smoke_a);
    
    float b = step(1.,border(pos));
    
    float bw = step(smoke_val*1.25, boom_val);
    
    vec3 color = bw * boom_col + (1.-bw) * smoke_col;
    float alpha = bw * boom_a + (1.-bw) * smoke_a;
    
    vec4 result = vec4(alpha == 1. ? color : vec3(0.5), alpha) - vec4(vec3(1.-b), 1.);

    fragColor = vec4(result.rgb, alpha);
}
This shader is a port from an existing Shadertoy project. Shadertoy shaders are by default protected under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0) license unless anything else has been stated by the author. For more info, see our License terms.

More from RayL019

Rainier mood

20151110_VHS

water with primitive caustics

Related shaders

Pixel Explosion

Starfield with Parallax Scrolling Effect

Post-Processing, Grain PP effect and Palette Color

Subscribe
Notify of
guest

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

This is sick!