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

Protean clouds

Raymarching

Flame

Related shaders

Pixel Explosion

Glitch Effect Shader

Unmoving Plaid Effect

Subscribe
Notify of
guest

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

This is sick!