Void Geode

GLSL shader by merrypranxter · created 2026-02-14 · 10s loop · 2 passes

KIFS folded fractal crystal — 7 iterations of dodecahedral symmetry folding produce recursive cavities and hard facets that read as organic solid matter. Neon blacklight palette bleeds from the cracks. Subsurface scatter trapped inside.

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));
}

Buffer A (iChannel0)

// ============================================================
//  VOID GEODE v1.0
//  KIFS folded crystal — hard edges, faceted form, crack glow
//  Blacklight palette
// ============================================================

const float PI  = 3.14159265359;
const float TAU = 6.28318530718;
const float speed      = 0.12;
const float brightness = 1.9;
const float foldScale  = 1.95;
const float crackGlow  = 3.5;

vec3 lfPalette(float t) {
    vec3 a = vec3(0.3, 0.0, 0.4);
    vec3 b = vec3(0.5, 0.0, 0.5);
    vec3 c = vec3(0.9, 2.0, 1.1);
    vec3 d = vec3(0.0, 0.5, 0.8);
    return a + b * cos(TAU * (c * t + d));
}
vec3 neonPalette(float t) {
    vec3 a = vec3(0.0, 0.3, 0.4);
    vec3 b = vec3(0.0, 0.5, 0.5);
    vec3 c = vec3(0.0, 1.8, 2.2);
    vec3 d = vec3(0.0, 0.2, 0.6);
    return a + b * cos(TAU * (c * t + d));
}
vec3 hotPalette(float t) {
    vec3 a = vec3(0.4, 0.0, 0.3);
    vec3 b = vec3(0.5, 0.0, 0.4);
    vec3 c = vec3(1.2, 0.0, 1.9);
    vec3 d = vec3(0.5, 0.0, 0.3);
    return a + b * cos(TAU * (c * t + d));
}

mat2 rot2(float a) {
    float ca = cos(a);
    float sa = sin(a);
    return mat2(ca, -sa, sa, ca);
}
mat3 rotY(float a) {
    float ca = cos(a);
    float sa = sin(a);
    return mat3(ca, 0.0, sa, 0.0, 1.0, 0.0, -sa, 0.0, ca);
}
mat3 rotX(float a) {
    float ca = cos(a);
    float sa = sin(a);
    return mat3(1.0, 0.0, 0.0, 0.0, ca, -sa, 0.0, sa, ca);
}

// ---- SDF primitives ----
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 sdOctahedron(vec3 p, float s) {
    p = abs(p);
    float m = p.x + p.y + p.z - s;
    vec3 q;
    if(3.0 * p.x < m) { q = p.xyz; }
    else if(3.0 * p.y < m) { q = p.yzx; }
    else if(3.0 * p.z < m) { q = p.zxy; }
    else { return m * 0.57735027; }
    float k = clamp(0.5 * (q.z - q.y + s), 0.0, s);
    return length(vec3(q.x, q.y - s + k, q.z - k));
}

// ---- KIFS fold ----
// Each iteration: mirror, rotate, scale — creates fractal crystal
vec3 kfold(vec3 p, float t) {
    // Dodecahedral fold directions
    vec3 n1 = normalize(vec3(1.0, 1.0, 0.0));
    vec3 n2 = normalize(vec3(1.0, 0.0, 1.0));
    vec3 n3 = normalize(vec3(0.0, 1.0, 1.0));
    vec3 n4 = normalize(vec3(1.0, 1.0, 1.0));

    float orbitTrap = 1e5;

    for(int i = 0; i < 7; i++) {
        // Mirror folds
        p = abs(p);

        // Plane fold 1
        float d1 = dot(p, n1) - 0.96;
        if(d1 > 0.0) { p -= 2.0 * d1 * n1; }

        // Plane fold 2
        float d2 = dot(p, n2) - 0.96;
        if(d2 > 0.0) { p -= 2.0 * d2 * n2; }

        // Plane fold 3
        float d3 = dot(p, n3) - 0.96;
        if(d3 > 0.0) { p -= 2.0 * d3 * n3; }

        // Plane fold 4
        float d4 = dot(p, n4) - 1.04;
        if(d4 > 0.0) { p -= 2.0 * d4 * n4; }

        // Scale and offset
        p = p * foldScale - vec3(foldScale - 1.0) * 0.5;

        // Slow rotation between folds — makes it animate
        float fi  = float(i);
        p.xy = rot2(t * 0.07 + fi * 0.15) * p.xy;
        p.yz = rot2(t * 0.05 - fi * 0.11) * p.yz;

        orbitTrap = min(orbitTrap, length(p));
    }
    return p;
}

// ---- Map: KIFS crystal ----
vec2 map(vec3 pos, float t) {
    vec3 p = kfold(pos, t);

    // Core shape: octahedron intersected with box = crystal
    float oct  = sdOctahedron(p, 0.85);
    float bx   = sdBox(p, vec3(0.6));
    float core = max(oct, bx);

    // Scale back by fold accumulation
    float scl  = pow(foldScale, -7.0);
    float dist = core * scl;

    // Orbit trap as material ID
    vec3  pt    = kfold(pos, t);
    float trap  = length(pt) * scl;

    return vec2(dist, trap);
}

vec3 calcNormal(vec3 p, float t) {
    vec2 e = vec2(0.0005, 0.0);
    float d0 = map(p, t).x;
    float nx = map(p + e.xyy, t).x - d0;
    float ny = map(p + e.yxy, t).x - d0;
    float nz = map(p + e.yyx, t).x - d0;
    return normalize(vec3(nx, ny, nz));
}

float calcAO(vec3 p, vec3 n, float t) {
    float ao = 0.0;
    float sc = 0.06;
    for(int i = 1; i <= 5; i++) {
        float fi  = float(i);
        float d   = map(p + n * sc * fi, t).x;
        ao += max(0.0, sc * fi - d) / (sc * fi);
    }
    return clamp(1.0 - ao * 0.5, 0.0, 1.0);
}

float softShadow(vec3 ro, vec3 rd, float mint, float maxt, float t) {
    float res = 1.0;
    float ph  = 1e10;
    float d   = mint;
    for(int i = 0; i < 20; i++) {
        float h = map(ro + rd * d, t).x;
        float y = h * h / (2.0 * ph);
        float dist2 = sqrt(h * h - y * y);
        res = min(res, 10.0 * dist2 / max(0.0, d - y));
        ph  = h;
        d  += clamp(h, 0.005, 0.1);
        if(res < 0.001 || d > maxt) { break; }
    }
    return clamp(res, 0.0, 1.0);
}

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2  uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y;
    float t  = iTime * speed;

    // Slow rotation of whole object
    mat3 objRot = rotY(t * 0.4) * rotX(t * 0.25);

    // Camera
    vec3 ro = vec3(0.0, 0.0, -3.5);
    vec3 rd = normalize(vec3(uv, 1.5));

    // Raymarch
    float d     = 0.0;
    float trap  = 0.0;
    float glow  = 0.0;
    bool  hit   = false;

    for(int i = 0; i < 128; i++) {
        vec3  p    = ro + rd * d;
        vec3  pr   = objRot * p;
        vec2  res  = map(pr, t);
        float ds   = res.x;
        trap = res.y;

        // Crack glow — tight neon bleed from near-surface
        float crackW = 1.0 / (1.0 + abs(ds) * abs(ds) * crackGlow * 60.0);
        glow += crackW * 0.008;

        d += ds * 0.55;
        if(ds < 0.0003) { hit = true; break; }
        if(d  > 8.0)    { break; }
    }

    vec3 col = vec3(0.0);

    if(hit) {
        vec3 p  = objRot * (ro + rd * d);
        vec3 n  = calcNormal(p, t);
        // Rotate normal back to world
        n = transpose(objRot) * n;
        vec3 pWorld = ro + rd * d;

        // Lights
        vec3 ldir1  = normalize(vec3(2.0, 3.0, -2.0));
        vec3 ldir2  = normalize(vec3(-2.0, -1.0, 1.0));

        float ao    = calcAO(p, n, t);
        float sha   = softShadow(pWorld + n * 0.002, ldir1, 0.01, 4.0, t);
        float diff1 = max(dot(n, ldir1), 0.0) * sha;
        float diff2 = max(dot(n, ldir2), 0.0) * 0.3;
        float spec  = pow(max(dot(reflect(-ldir1, n), -rd), 0.0), 64.0);
        float fres  = pow(1.0 - abs(dot(n, -rd)), 4.0);

        // Surface color from orbit trap + position
        float phase1 = trap * 2.0 + t * 0.08;
        float phase2 = trap * 1.3 + length(p) * 0.5 - t * 0.05;
        float phase3 = dot(n, vec3(1.0, 0.5, 0.7)) * 0.5 + t * 0.06;

        vec3 surfCol  = lfPalette(phase1) * (diff1 * 0.7 + diff2 + 0.1) * ao;
        vec3 specCol  = neonPalette(phase2) * spec * 3.0;
        vec3 fresCol  = hotPalette(phase3) * fres * 1.5;

        // Deep facet darkening — makes the crystal feel solid/cut
        float facet   = abs(dot(n, rd));
        float darkEdge = pow(facet, 0.4) * 0.6 + 0.4;

        col  = surfCol * darkEdge;
        col += specCol;
        col += fresCol;

        // Internal subsurface scatter — UV light trapped inside
        float sss = exp(-d * 0.3) * (1.0 - facet);
        col += neonPalette(trap + t * 0.1) * sss * 0.5;
    }

    // Crack and edge glow — neon bleeding from geometry
    col += lfPalette(glow * 4.0 + t * 0.1)   * glow * 3.0;
    col += neonPalette(trap + glow + t * 0.07) * glow * 2.0;
    col += hotPalette(glow * 2.0 - t * 0.05)  * glow * glow * 5.0;

    // Blacklight ambient — dark purple space
    col += vec3(0.03, 0.0, 0.06) * (1.0 - dot(uv, uv) * 0.5);

    // Outer UV halo
    float haloDist = length(uv);
    float halo     = exp(-haloDist * 3.5) * 0.12;
    col += vec3(0.3, 0.0, 0.7) * halo;

    col *= 1.0 - dot(uv, uv) * 0.4;
    col  = pow(clamp(col * brightness, 0.0, 1.0), vec3(0.78));
    col *= col * 1.3;

    fragColor = vec4(col, 1.0);
}

Image

Not used

More shaders by merrypranxter

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

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

Account

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