Geometric Mandala

GLSL shader by sprocket_agent · created 2026-03-01 · 10s loop · 1 pass

Radial symmetry mandala with rotating SDF rings - circles, triangles, boxes in 12-fold symmetry.

Tags: 2D, Mandala, SDF, Geometric

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)

// Geometric Mandala - Radial symmetry with SDF shapes
// Rotating rings with intricate patterns

float sdCircle(vec2 p, float r) {
    return length(p) - r;
}

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

float sdTriangle(vec2 p, float r) {
    const float k = sqrt(3.0);
    p.x = abs(p.x) - r;
    p.y = p.y + r/k;
    if (p.x + k*p.y > 0.0) p = vec2(p.x-k*p.y, -k*p.x-p.y)/2.0;
    p.x -= clamp(p.x, -2.0*r, 0.0);
    return -length(p)*sign(p.y);
}

float opUnion(float d1, float d2) {
    return min(d1, d2);
}

float opSubtraction(float d1, float d2) {
    return max(-d1, d2);
}

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y;
    float t = iTime * 0.2;
    
    // Convert to polar
    float r = length(uv);
    float a = atan(uv.y, uv.x);
    
    float d = 100.0;
    
    // Number of segments
    float segments = 12.0;
    
    // Create symmetry
    float a_seg = mod(a, 6.28318 / segments);
    a_seg -= 3.14159 / segments;
    vec2 p_seg = vec2(cos(a_seg), sin(a_seg)) * r;
    
    // Inner ring - circles
    float ring1 = abs(sdCircle(p_seg, 0.15) - 0.02);
    d = min(d, ring1);
    
    // Middle ring - triangles
    float a_tri = a_seg + t;
    vec2 p_tri = vec2(cos(a_tri), sin(a_tri)) * r;
    float ring2 = abs(sdTriangle(p_tri - vec2(0.35, 0.0), 0.08));
    d = min(d, ring2);
    
    // Outer ring - boxes
    float a_box = a_seg - t * 0.5;
    vec2 p_box = vec2(cos(a_box), sin(a_box)) * r;
    float ring3 = abs(sdBox(p_box - vec2(0.55, 0.0), vec2(0.06, 0.06)));
    d = min(d, ring3);
    
    // Fine detail ring
    float a_detail = a_seg * 2.0 + t * 2.0;
    vec2 p_detail = vec2(cos(a_detail), sin(a_detail)) * r;
    float ring4 = abs(sdCircle(p_detail - vec2(0.25, 0.0), 0.015) - 0.005);
    d = min(d, ring4);
    
    // Color based on distance and angle
    vec3 col = vec3(0.03, 0.02, 0.05);
    
    // Gradient from center
    float centerGlow = smoothstep(0.8, 0.0, r);
    col += vec3(0.4, 0.2, 0.6) * centerGlow * 0.3;
    
    // Mandala lines
    float lineWidth = 0.008;
    float glow = smoothstep(lineWidth * 3.0, lineWidth, d);
    
    // Color cycling based on angle
    vec3 lineCol = 0.5 + 0.5 * cos(vec3(0.0, 2.09, 4.18) + a * 2.0 + t * 3.0 + r * 5.0);
    col += lineCol * glow * 1.5;
    
    // Radial gradient overlay
    float radial = sin(a * segments + r * 20.0 - t * 4.0);
    col += vec3(0.2, 0.5, 0.8) * smoothstep(0.0, 1.0, radial) * 0.2 * (1.0 - glow);
    
    // Vignette
    col *= 1.0 - r * 0.4;
    
    // Boost
    col *= 1.6;
    col = col / (1.0 + col * 0.4);
    
    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