Project_2026-05-14_21-48-59

GLSL shader by scry · created 2026-05-15 · 20s 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));
}

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 mapFractal(vec3 p) {
    //p.z -= sin(time)*2.+2.;
    float iterCount = (-cos(time/2.) * 0.5 + 0.5) * 12.0;
    int maxIter = int(ceil(iterCount));
    float blend = fract(iterCount);
    
    float scale = 1.0;
    
    for (int i = 0; i < 12; i++) {
        if (i >= maxIter) break;
        
        vec3 prevP = p;
        float prevScale = scale;
        p = abs(p) - 2.0;
        p *= 1.5;
        scale *= 1.5;
        p.xy *= r2d(deg * 60.0);
        p.yz *= r2d(deg * -90.0);
        
        if (i == maxIter - 1) {
            p = mix(prevP, p, blend);
            scale = mix(prevScale, scale, blend);
        }
    }
    
    return vec4(p,sdBox(p, vec3(1.0)) / scale);
}

float mapScene(vec3 p) {
    return mapFractal(p).w-0.01;
}

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

float ambientOcclusion(vec3 p, vec3 n) {
    float occ = 0.0;
    float sca = 1.0;
    for (int i = 0; i < 5; i++) {
        float h = 0.01 + 0.12 * float(i);
        float d = mapScene(p + n * h);
        occ += (h - d) * sca;
        sca *= 0.95;
        if (occ > 1.5) break;
    }
    return clamp(1.0 - 3.0 * occ, 0.0, 1.0)*0.25+0.75;
}

vec2 raymarch(vec3 ro, vec3 rd) {
    float t = 0.0;
    float ii = 0.;
    for (int i = 0; i < 80; i++) {
        float d = mapScene(ro + rd * t);
        if (d < 0.001 || t > 50.0) break;
        t += d;
        ii += 0.01;
    }
    return vec2(t,ii);
}

Buffer A (iChannel0)

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = fragCoord.xy / iResolution.xy;
    vec2 suv = (uv - 0.5) * vec2(ar, 1.0);
    
    // Camera setup - orbit around origin
    float camAngle = time/4.+3.;
    float camDist = 9.0-cos(time/2.)*4.;
    float camHeight = 3.0 + sin(time * 0.5) * 1.5;
    vec3 ro = vec3(cos(camAngle) * camDist, camHeight, sin(camAngle) * camDist);
    ro *= 1.5+cos(time/2.)*0.5;
    vec3 target = vec3(0.0);
    
    // Mouse camera control
    if (M.z > 0.0) {
        float mx = xm.x * pi * 2.0;
        float my = xm.y * pi - pi * 0.5;
        ro = vec3(cos(mx) * cos(my), sin(my), sin(mx) * cos(my)) * camDist;
    }
    
    vec3 forward = normalize(target - ro);
    vec3 right = normalize(cross(forward, vec3(0.0, 1.0, 0.0)));
    vec3 up = cross(right, forward);
    vec3 rd = normalize(forward + right * suv.x + up * suv.y);
    
    // Background gradient
    vec3 col = mix(vec3(0.02, 0.02, 0.05), vec3(0.1, 0.05, 0.15), uv.y);
    
    // Raymarching with reflections
    vec3 rayOrig = ro;
    vec3 rayDir = rd;
    float reflectWeight = 1.0;
    
    for (int bounce = 0; bounce < 4; bounce++) {
        float t = raymarch(rayOrig, rayDir).x;
        
        if (t > 50.0) {
            // Sky contribution
            vec3 sky = mix(vec3(0.02, 0.02, 0.05), vec3(0.1, 0.05, 0.15), rayDir.y * 0.5 + 0.5);
            col += sky * reflectWeight * 0.3;
            break;
        }
        
        vec3 p = rayOrig + rayDir * t;
        vec3 n = calcNormal(p);
        vec3 mp = mapFractal(p).xyz;
        
        // Material color from fractal position
        //vec3 matCol = sin(p * 0.5 +sin(mp*8.+time*4.)*0.25+mp/2.+ cs * 1.5) * 0.4 + 0.5;
        //matCol += sin(mp+time*4.-cs*2.)*0.35;
        vec3 matCol = sin((mp.x+mp.y+mp.z)/2.+p/4.+cs+time)*0.6+0.4;
        // Lighting
        vec3 lightDir = normalize(vec3(1.0, 1.5, -0.5));
        vec3 viewDir = -rayDir;
        vec2  d = raymarch(p + n * 0.01, lightDir);
        float diff = max(dot(n, lightDir), 0.0);
        vec3 halfDir = normalize(lightDir + viewDir);
        float spec = pow(max(dot(n, halfDir), 0.0), 64.0);
        //matCol -= d.y*1.;
        // Soft shadow
        float sha = 1.0;
        
        float st = d.x;
        if (st < 50.0) sha = 0.2;
        
        // Ambient occlusion
        float ao = ambientOcclusion(p, n);
        
        vec3 ambient = matCol * 0.08;
        vec3 lighting = ambient + matCol * diff * sha * 0.8 + vec3(1.0) * spec * sha * 0.5;
        lighting *= ao;
        
        col += lighting * reflectWeight;
        //col -= d.y*0.1;
        // Setup reflection bounce
        reflectWeight *= 0.35;
        if (reflectWeight < 0.01) break;
        
        rayOrig = p + n * 0.01;
        rayDir = reflect(rayDir, n);
    }
    
    // Tone mapping & gamma
    col = col / (1.0 + col);
    col = pow(col, vec3(1.0 / 2.2));
    
    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