open .fs {
"DESCRIPTION" : "Sculptural liquid chrome with chromatic dispersion, orbiting droplets, and bounded long-exposure flow." ,
"INPUTS" : [
{ "NAME" : "motion" , "TYPE" : "float" , "DEFAULT" : 1.05 , "MIN" : 0.0 , "MAX" : 2.5 } ,
{ "NAME" : "swirl" , "TYPE" : "float" , "DEFAULT" : 1.15 , "MIN" : 0.0 , "MAX" : 2.0 } ,
{ "NAME" : "warp" , "TYPE" : "float" , "DEFAULT" : 1.0 , "MIN" : 0.0 , "MAX" : 2.0 } ,
{ "NAME" : "trail" , "TYPE" : "float" , "DEFAULT" : 0.9980 , "MIN" : 0.97 , "MAX" : 0.9998 } ,
{ "NAME" : "sparkle" , "TYPE" : "float" , "DEFAULT" : 0.72 , "MIN" : 0.0 , "MAX" : 1.5 } ,
{ "NAME" : "hueShift" , "TYPE" : "float" , "DEFAULT" : 0.08 , "MIN" : 0.0 , "MAX" : 1.0 }
] ,
"PASSES" : [
{ "TARGET" : "paint" , "PERSISTENT" : true , "FLOAT" : true } ,
{ }
]
}
#define TAU 6.28318530718
vec3 palette (float t) {
return 0.5 + 0.5 * cos (TAU * (t + hueShift + vec3 (0.00 , 0.29 , 0.57 )));
}
vec2 vortex (vec2 p, vec2 center, float spin) {
vec2 d = p - center;
float influence = exp (-dot (d, d) * 13.0 );
return vec2 (-d.y, d.x) * influence * spin;
}
float droplet (vec2 p, vec2 center, float size) {
return 1.0 - smoothstep (0.0 , size, length (p - center));
}
void main () {
vec2 uv = isf_FragNormCoord ;
if (PASSINDEX == 0 ) {
float frameStep = min (TIMEDELTA * 60.0 , 2.0 );
float t = TIME * motion;
vec2 p = uv - 0.5 ;
p.x *= RENDERSIZE .x / RENDERSIZE .y;
vec2 a = vec2 (0.27 * cos (t * 0.39 ), 0.24 * sin (t * 0.51 ));
vec2 b = vec2 (0.25 * cos (t * 0.35 + 3.1 ), 0.28 * sin (t * 0.44 + 2.2 ));
vec2 c = vec2 (0.19 * sin (t * 0.63 + 0.4 ), 0.29 * cos (t * 0.31 - 0.7 ));
vec2 vel = vortex (p, a, 2.3 ) + vortex (p, b, -2.0 ) + vortex (p, c, 1.35 );
vel += vec2 (
sin (TAU * uv.y * 2.0 + t * 0.42 ),
cos (TAU * uv.x * 2.0 - t * 0.33 )
) * (0.052 + 0.025 * warp);
vel += 0.026 * warp * vec2 (sin (p.y * 19.0 + t), cos (p.x * 17.0 - t * 0.8 ));
vel *= swirl;
vel.x /= RENDERSIZE .x / RENDERSIZE .y;
vec2 back = uv - vel * (0.0145 * frameStep * motion);
vec2 px = 1.0 / RENDERSIZE ;
vec3 old = IMG_NORM_PIXEL (paint, back).rgb * 0.64 ;
old += IMG_NORM_PIXEL (paint, back + vec2 (px.x, 0.0 )).rgb * 0.09 ;
old += IMG_NORM_PIXEL (paint, back - vec2 (px.x, 0.0 )).rgb * 0.09 ;
old += IMG_NORM_PIXEL (paint, back + vec2 (0.0 , px.y)).rgb * 0.09 ;
old += IMG_NORM_PIXEL (paint, back - vec2 (0.0 , px.y)).rgb * 0.09 ;
old *= pow (trail, frameStep);
old.r = max (old.r, IMG_NORM_PIXEL (paint, back + px * 1.35 ).r * 0.11 );
old.b = max (old.b, IMG_NORM_PIXEL (paint, back - px * 1.35 ).b * 0.11 );
float injectA = droplet (p, a, 0.047 );
float injectB = droplet (p, b, 0.041 );
float injectC = droplet (p, c, 0.033 );
float satellite = droplet (p, 0.56 * a - 0.30 * b, 0.018 );
vec3 fresh = palette (t * 0.032 + length (a) + 0.10 ) * injectA;
fresh += palette (t * 0.032 + length (b) + 0.62 ) * injectB;
fresh += palette (t * 0.032 + length (c) + 0.36 ) * injectC;
fresh += palette (t * 0.08 + 0.91 ) * satellite * (0.45 + 0.35 * sin (t * 3.0 ));
float ringA = 1.0 - smoothstep (0.0 , 0.018 , abs (length (p - a) - 0.075 ));
float ringB = 1.0 - smoothstep (0.0 , 0.014 , abs (length (p - b) - 0.061 ));
fresh += palette (t * 0.04 + 0.24 ) * (ringA * 0.23 + ringB * 0.18 );
float boundary = smoothstep (0.0 , 0.03 , uv.x)
* smoothstep (0.0 , 0.03 , 1.0 - uv.x)
* smoothstep (0.0 , 0.03 , uv.y)
* smoothstep (0.0 , 0.03 , 1.0 - uv.y);
vec3 next = max (old, fresh * (0.40 + 0.10 * sparkle)) * boundary;
vec3 hot = max (next - vec3 (0.70 ), vec3 (0.0 ));
next = min (next, vec3 (0.70 )) + hot / (1.0 + 0.82 * hot);
gl_FragColor = vec4 (clamp (next, 0.0 , 1.45 ), 1.0 );
} else {
vec2 px = 1.0 / RENDERSIZE ;
vec2 q = isf_FragNormCoord ;
vec3 c0 = IMG_THIS_PIXEL (paint).rgb;
vec3 cR = IMG_NORM_PIXEL (paint, q + vec2 (px.x * 1.7 , 0.0 )).rgb;
vec3 cL = IMG_NORM_PIXEL (paint, q - vec2 (px.x * 1.7 , 0.0 )).rgb;
vec3 cU = IMG_NORM_PIXEL (paint, q + vec2 (0.0 , px.y * 1.7 )).rgb;
float l = dot (c0, vec3 (0.3333 ));
float lx = dot (cR, vec3 (0.3333 ));
float ly = dot (cU, vec3 (0.3333 ));
vec2 grad = vec2 (lx - l, ly - l);
float rim = clamp (length (grad) * 31.0 , 0.0 , 1.0 );
float reflection = 0.5 + 0.5 * sin (18.0 * q.x + 12.0 * q.y + TIME * 0.48 );
float glint = pow (max (0.0 , reflection * rim), 3.0 ) * sparkle;
vec3 dispersed = vec3 (cR.r, c0.g, cL.b);
vec3 chrome = mix (c0, dispersed, 0.42 );
chrome *= 0.30 + 1.38 * l;
chrome += rim * palette (0.16 + l * 0.22 ) * (0.58 + 0.30 * sparkle);
chrome += glint * vec3 (0.95 , 0.98 , 1.0 );
chrome += pow (max (l, 0.0 ), 3.0 ) * vec3 (0.75 , 0.88 , 1.0 );
chrome = chrome / (1.0 + 0.60 * chrome);
gl_FragColor = vec4 (max (chrome, 0.0 ), 1.0 );
}
}