Project_2026-05-09_02-07-27

GLSL shader by scry · created 2026-05-09 · updated 2026-05-12 · 10s loop · 2 passes

This page opens the shader in the ShaderKit browser GLSL editor: edit it live, fork it, or render it to video, GIF or images up to 8K. Also available as a full-screen view and an embeddable player.

Shader source (GLSL)

Common

#define pi acos(-1.)
#define deg pi/180.  //1 degree
#define time iTime*2.*pi/10. //sin(time) loops 10 seconds
#define R iResolution.xy //shorthand
#define ar R.x/R.y //aspect ratio
#define M iMouse //shorthand
#define xm (M.xy/R) //normalized mouse
#define nm ((xm.xy-0.5)*vec2(ar,1.)+0.5) //aspect ratio correction
vec3 cs = vec3(1.,2.,3.);
mat2 r2d(float a) {
    return mat2(cos(a),sin(a),-sin(a),cos(a));
}
// HSV to RGB
vec3 hsv2rgb(vec3 c) {
    vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
    vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
    return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}

// RGB to HSV
vec3 rgb2hsv(vec3 c) {
    vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
    vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
    vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
    float d = q.x - min(q.w, q.y);
    float e = 1.0e-10;
    return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}

// Mix colors in HSV space
vec3 mixHSV(vec3 c1, vec3 c2, float t) {
    vec3 hsv1 = rgb2hsv(c1);
    vec3 hsv2 = rgb2hsv(c2);
    return hsv2rgb(mix(hsv1, hsv2, t));
}

Buffer A (iChannel0)

float bm(vec2 uv, vec2 s) {
    return smoothstep(0.0001,0.,max(abs(uv.x)-s.x,abs(uv.y)-s.y));
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = fragCoord.xy / iResolution.xy;
    vec2 tv = uv;
    uv -= 0.5;
    uv.x *= ar;
    vec3 col = vec3(0.);
    vec2 vv = vec2(0.5);
    
    uv *= 5.;
    for (int i=0;i<14;i++) {
        vec2 ua = sin(vec2(0.,1.57)+time/2.+float(i))*1.5;
        uv -= ua;
        uv.y -= clamp(uv.y,0.,(sin(float(i)+time/2.)*0.5+0.5)*0.4);
        uv += ua;
        uv *= r2d(deg*45.+sin(time/2.+float(i))*deg*10.);
        //uv -= ua;
        
    }
    //uv *= r2d(sin(time)*2.);
    // rv accumulates the total rotation applied to uv during the loop.
    // We start with identity so we can later "undo" or "apply" the same
    // cumulative rotation to vv (the captured hit position).
    mat2 rv = mat2(1.,0.,0.,1.); // identity matrix
    float b = 0.;
    float bx = 0.;
    // accRot tracks the total rotation angle so we can invert it later
    float accRot = 0.;
    vec2 v2 = uv;
    for (int i=0;i<1230;i++) {
        vec2 s = vec2(0.2,0.04);
        float ii = float(i);
        float mb = bm(uv,s);
        float mb2 = bm(v2,s);
        float nb = b*(1.-mb)*(1.-mb2)+(mb+mb2)*(sin(ii*0.004+2.))*10.;
        float wm = nb - b;
        float angle = deg*0.+sin(ii*(0.012)+4.+time/2.+1.9)*deg*4.;
        //rv *= r2d(angle);
        if (mod(floor(ii)*0.1+3.,24.) == 0.) {
            //uv.y = abs(uv.y)-0.2;
        }
        //if (ii < 10.) {
        //    b += nb;
        //    bx += mb;
        //}
        //accRot += angle;
        if (b > 0.) {
            continue;
        }
        bx += mb+mb2;
        // When we hit (mb>0), capture uv in "rotated space".
        // vv stores the hit position, but it's still in the rotated frame.
        vv = uv*mb + vv*(1.-mb)*(1.-mb2) + v2*mb2;
        if (i == 0) {
            vv *= 0.5;
        }
        b = nb;
        
        // Each iteration applies a rotation to uv
        
        uv.y -= 0.015;
        uv *= r2d(angle);
        v2.y += 0.015;
        v2 *= r2d(angle);
        
        
    }
    //vv *= r2d(accRot);
    // vv was captured in the rotated frame at the point of the hit.
    // To bring it back to the "original" (unrotated) frame, we multiply
    // by the INVERSE of rv. For a rotation matrix, inverse = transpose.
    // This "unwinds" all the rotations that were applied before the hit.
    uv = vv;
    //uv = r2d(accRot)*vv;
    //uv = transpose(rv) * vv;
    // Alternatively: uv = r2d(-accRot) * vv; (same thing, using accumulated angle)
    //col.rg = vv;
    //col += b*0.05;
    col += smoothstep(0.105,0.,abs(uv.x)-0.15)*(cos(uv.x*24.*pi)*0.5+0.5)*(sin(vec3(1.,2.,4)*1.5+uv.y*20.+time*20.+b*4.)*0.5+0.5);
    //col += smoothstep(0.01,0.,abs(uv.x)-0.2)*(cos(uv.x*45.*pi))*0.2;
    if (step(bx,0.) > 0.) {
        tv = fract(tv-0.);
        tv = abs(tv);
        //tv = abs(tv-0.5);
        tv -= 0.5;
        //tv += sin(vec2(0.,1.57)+time)*0.01;
        //tv = fract(tv-0.5)-0.;
        //tv = abs(tv)-0.02;
        //tv *= r2d(deg*45.+sin(time)*deg*2.);
        
        tv += 0.5;
        if (max(tv.x,tv.y) < 0.99) {
                vec3 bak = texture(iChannel0,tv).rgb*0.98;
                bak = rgb2hsv(bak);
                bak.x += 0.1;
                //bak.z *= 0.96;
                bak = hsv2rgb(bak);
                col += bak;
            
        }        
    }
    fragColor = vec4(col, 1.0);
}

Image

Not used

More shaders by scry

Browse all public shaders · All shaders by scry · ShaderKit home

Vibe Mode BETA
💰 ~0 credits
Uniforms
FPS: 0
Time: 0
Resolution: 0 x 0

Account

FPS: -- Time: -- --×-- 1x