Project_2026-01-13_09-55-14

GLSL shader by scry · created 2026-01-13 · 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/40. //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));
}

Buffer A (iChannel0)

vec2 getSurfaceUV(vec3 pc, float d) {
    // Returns surface UV for the mobius strip
    // pc.y is the local y on box cross-section
    // Uses xz when on top/bottom faces, xy when on side faces
    vec2 s = vec2(0.3,0.29);
    float sd = step(d,0.1);
    vec2 suv = pc.xz * step(-abs(pc.y), -s.x) + pc.xy * step(abs(pc.y), s.y);
    suv *= sd;
    return suv / 4.0;
}

float sdSegment(in vec2 p, in vec2 a, in vec2 b) {
    vec2 pa = p-a, ba = b-a;
    float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
    return length( pa - ba*h );
}

float getPattern(vec2 uv) {
    uv *= 0.5;
    uv = (fract(uv/pi-0.5)-0.5)*pi;
    vec2 ov = uv;
    vec2 av = uv;
    uv = fract(uv*4.)-0.5;
    uv *= 4.;
    for (int i=0;i<6;i++) {
        ov = abs(ov)-3.+av.y*0.5;
        uv.xy = abs(uv.xy)-0.05+ov.x*0.5;
        
        uv += sin(uv.yx*4.)*-0.25;
        uv *= r2d(deg*45.);
    }
    for (int i=0;i<4;i++) {
        uv.x = abs(uv.x)-0.01;
    }
    float pattern = 0.0;
    pattern += sin(uv.x*20.)*0.5;
    pattern += smoothstep(0.01,0.,sdSegment(uv,vec2(0.,-0.2),vec2(0.,0.2)))/2.;
    return pattern;
}

vec3 getPatternCol(vec2 uv) {
    return sin(uv.x*20.+cs)*0.5 + smoothstep(0.01,0.,sdSegment(uv,vec2(0.,-0.2),vec2(0.,0.2)))/2.;
}



vec3 lightPos = vec3(0.0, 0.0, 15.0);
float shadowSoftness = 16.0;
vec3 ambientCol = vec3(0.1, 0.12, 0.15);
vec3 lightCol = vec3(1.0, 0.95, 0.9);

float sdBox(vec3 p, vec3 b) {
    vec3 q = abs(p) - b;
    return length(max(q, 0.0)) + min(max(q.x, max(q.y, q.z)), 0.0);
}

vec4 map(vec3 p) {
    // Define your scene here using SDFs.
    // Example: a simple sphere.
    float a = 4.;
    p.xz *= r2d(time);
    for (int i=0;i<3;i++) {
        p.xz = abs(p.xz)-1.15*a;
        p.y = abs(p.y)-1.15*a*2.;
        a /= 2.;
        p.xz *= r2d(deg*45.);
        
    }
    p.y = abs(p.y)-1.15*a*2.;
    float pzr = 0.8;
    p.xy *= r2d(time);
    //p.z = (fract(p.z*pzr)-0.5)/pzr;
    vec3 pc = vec3(atan(p.x,p.y),length(p.xy),p.z);
    pc.y -= 1.5;
    float angle = pc.x; // Store angle before rotation for UV
    pc.zy *= r2d(pc.x/1.);
    float d = sdBox(vec3(pc),vec3(4.,0.3,0.3));
    
    vec2 pv = getSurfaceUV(pc,d);
    float pattern = getPattern(pv);
    d -= pattern * 0.05; // Emboss the pattern onto the surface
    //pc.yz *= r2d(deg*45.);
    pc.yz = abs(pc.yz)-0.3;
    float cylD = length(pc.yz)-0.06;
    if (cylD < d) {
        pattern = 24.0;
        d = cylD;
    }
    return vec4(pv, pattern, d);
}

vec3 calcNormal(vec3 p) {
    vec2 e = vec2(0.001, 0.0);
    return normalize(vec3(
        map(p + e.xyy).w - map(p - e.xyy).w,
        map(p + e.yxy).w - map(p - e.yxy).w,
        map(p + e.yyx).w - map(p - e.yyx).w
    ));
}

float softShadow(vec3 ro, vec3 rd, float mint, float maxt) {
    float res = 1.0;
    float t = mint;
    for (int i = 0; i < 32; i++) {
        float h = map(ro + rd * t).w;
        res = min(res, shadowSoftness * h / t);
        t += clamp(h, 0.02, 0.2);
        if (h < 0.001 || t > maxt) break;
    }
    return clamp(res, 0.0, 1.0);
}

vec2 RM(vec3 ro, vec3 rd) {
    float dO = 0.0;
    float ii = 0.0;
    for (int i=0; i<100; i++) {
        vec3 p = ro + rd*dO;
        float dS = map(p).w;
        dO += dS*0.6;
        ii += 1.0; // Can be used for effects based on steps
        if (dO > 30.0 || dS < 0.001) break;
    }
    return vec2(dO, ii);
}

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.);
    uv *= r2d(time);
    vec3 ro = vec3(0.0, 0.0, 15.0+sin(time)*8.); // Ray Origin
    vec3 rd = normalize(vec3(uv, -2.0+length(uv)*2.)); // Ray Direction
    //ro.xy += vec2(sin(time),cos(time))*0.8;
    //ro.z += -time;
    ro.yz *= r2d(deg*10.);rd.yz *= r2d(deg*10.);
    //ro.xz *= r2d(time/4.);rd.xz *= r2d(time/4.);
    
    vec3 lp = lightPos;
    //lp.xz *= r2d(time);
    
    vec2 d = RM(ro, rd);
    float t = d.x; // Distance to hit
    vec3 p = ro + rd * t; // Hit point in 3D space
    vec3 mp = map(p).xyz; // Note: map returns pc, not pv. See below for pv access.
    if (t < 20.0) {
        vec3 n = calcNormal(p);
        vec3 l = normalize(lp - p);
        float diff = max(dot(n, l), 0.0);
        float sha = softShadow(p + n * 0.01, l, 0.02, length(lp - p));
        col = ambientCol + lightCol * diff * sha;
    } else {
        col = vec3(0.02, 0.02, 0.04); // Background
    }
    //this gets the surface uv for painting the pattern on the surface of the mobius block thing
    
    //below THIS line - now using the pattern function
    vec2 patternUV = mp.xy;
    //patternUV = getSurfaceUV(mp);
    vec2 puv = getSurfaceUV(mp,d.x);
    
    //puv = fract(puv*4.)-0.5;
    //puv *= 4.;
    //col += getPatternCol(puv);
    col += sin(mp.z*10.+cs+p.y*0.3+p.z*-0.2+1.)*0.5;
    col += step(-d.x,-20.)*(d.y*0.02);
    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