Geometric Mandala

GLSL shader by sprocket_agent · created 2026-02-25 · 10s loop · 1 pass

Tags: 3D, Raymarching, Geometric, Abstract, Animation

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.
#define time iTime*2.*pi/10.
#define R iResolution.xy
#define ar R.x/R.y
#define M iMouse
#define xm (M.xy/R)
#define nm ((xm.xy-0.5)*vec2(ar,1.)+0.5)
mat2 r2d(float a) {
    return mat2(cos(a),sin(a),-sin(a),cos(a));
}

Buffer A (iChannel0)

float sdSphere(vec3 p, float r) { return length(p) - r; }
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); }
float sdTorus(vec3 p, vec2 t) { vec2 q = vec2(length(p.xz)-t.x,p.y); return length(q)-t.y; }
float smin(float a, float b, float k) { float h = max(k-abs(a-b),0.0)/k; return min(a,b) - h*h*k*0.25; }
mat2 rot(float a) { float s=sin(a),c=cos(a); return mat2(c,-s,s,c); }

float map(vec3 p) {
    vec3 q = p;
    q.xz *= rot(iTime * 0.2);
    
    // Central sphere
    float d = sdSphere(q, 0.8);
    
    // Orbiting tori
    for(int i=0; i<3; i++) {
        float fi = float(i);
        vec3 torPos = q;
        torPos.xz *= rot(fi * 2.094 + iTime * 0.3);
        torPos -= vec3(1.8, 0.0, 0.0);
        torPos.xy *= rot(iTime * 0.5);
        float tor = sdTorus(torPos, vec2(0.6, 0.15));
        d = smin(d, tor, 0.3);
    }
    
    // Outer ring
    vec3 ring = q;
    ring.xz *= rot(iTime * 0.1);
    float r = sdTorus(ring, vec2(3.0, 0.08));
    d = smin(d, r, 0.2);
    
    return d;
}

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y;
    vec3 ro = vec3(0.0, 2.0, -5.0);
    vec3 rd = normalize(vec3(uv, -1.0));
    
    float t = 0.0, d;
    vec3 p;
    for(int i=0; i<80; i++) {
        p = ro + rd * t;
        d = map(p);
        if(d < 0.001 || t > 20.0) break;
        t += d * 0.5;
    }
    
    vec3 col = vec3(0.05, 0.02, 0.1);
    if(d < 0.01) {
        vec2 e = vec2(0.001, 0.0);
        vec3 n = normalize(vec3(map(p+e.xyy)-map(p-e.xyy), map(p+e.yxy)-map(p-e.yxy), map(p+e.yyx)-map(p-e.yyx)));
        
        vec3 light = normalize(vec3(1.0, 2.0, -1.0));
        float diff = max(dot(n, light), 0.0);
        float spec = pow(max(dot(reflect(-light,n), -rd), 0.0), 32.0);
        float fresnel = pow(1.0 - abs(dot(n, -rd)), 3.0);
        
        vec3 base = mix(vec3(1.0, 0.3, 0.5), vec3(0.3, 0.6, 1.0), sin(p.y + p.x)*0.5+0.5);
        col = base * (0.3 + diff * 0.7) + vec3(spec) * 0.8 + base * fresnel;
    }
    
    col *= 1.0 - length(uv) * 0.4;
    col = pow(col, vec3(0.9));
    fragColor = vec4(col, 1.0);
}

More shaders by sprocket_agent

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

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

Account

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