Crystal Cave

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

Stalactites, stalagmites, and glowing gem crystals with light shafts.

Tags: 2D, Cave, Crystals, 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)

// Crystal Cave - Geometric formations with internal glow
// Stalactites and gem clusters

float hash(vec2 p) { return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453); }

mat2 rot(float a) {
    float s = sin(a), c = cos(a);
    return mat2(c, -s, s, c);
}

// Crystal SDF
float sdCrystal(vec2 uv, vec2 pos, float size, float angle) {
    uv -= pos;
    uv = rot(angle) * uv;
    
    // Hexagon-ish crystal shape
    float x = abs(uv.x);
    float y = uv.y;
    
    float d = max(x * 0.866 + y * 0.5, -y); // 60 degree slopes
    return d - size * 0.5;
}

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = (fragCoord - 0.5 * iResolution.xy) / iResolution.y;
    float t = iTime * 0.3;
    
    // Cave darkness
    vec3 col = vec3(0.03, 0.02, 0.05);
    
    // Background rock texture
    float rock = hash(uv * 50.0);
    rock = pow(rock, 2.0) * 0.1;
    col += vec3(0.1, 0.08, 0.12) * rock;
    
    // Ceiling stalactites
    for(int i = 0; i < 6; i++) {
        float fi = float(i);
        vec2 tipPos = vec2((fi - 2.5) * 0.4 + sin(fi * 2.0) * 0.1, 0.5 - hash(vec2(fi, 0.0)) * 0.3);
        vec2 basePos = vec2(tipPos.x, 0.8);
        
        // Distance to stalactite
        vec2 toTip = tipPos - basePos;
        vec2 toPoint = uv - basePos;
        float proj = dot(toPoint, toTip) / dot(toTip, toTip);
        proj = clamp(proj, 0.0, 1.0);
        float d = length(toPoint - toTip * proj);
        
        // Tapering width
        float w = 0.15 * (1.0 - proj * 0.7);
        float stalactite = smoothstep(w, 0.0, d);
        
        col += vec3(0.2, 0.25, 0.3) * stalactite;
    }
    
    // Floor stalagmites
    for(int i = 0; i < 5; i++) {
        float fi = float(i) + 10.0;
        vec2 tipPos = vec2((fi - 12.0) * 0.5 + cos(fi) * 0.1, -0.5 + hash(vec2(fi, 0.0)) * 0.25);
        vec2 basePos = vec2(tipPos.x, -0.8);
        
        vec2 toTip = tipPos - basePos;
        vec2 toPoint = uv - basePos;
        float proj = dot(toPoint, toTip) / dot(toTip, toTip);
        proj = clamp(proj, 0.0, 1.0);
        float d = length(toPoint - toTip * proj);
        
        float w = 0.2 * (1.0 - proj * 0.6);
        float stalagmite = smoothstep(w, 0.0, d);
        
        col += vec3(0.25, 0.2, 0.3) * stalagmite;
    }
    
    // Glowing crystals
    for(int i = 0; i < 8; i++) {
        float fi = float(i);
        vec2 crystalPos = vec2(
            sin(fi * 1.5) * 0.6,
            cos(fi * 2.3) * 0.3
        );
        float size = 0.1 + hash(vec2(fi, 1.0)) * 0.1;
        float angle = fi + t * (0.5 + hash(vec2(fi, 2.0)));
        
        float d = sdCrystal(uv, crystalPos, size, angle);
        float crystal = smoothstep(0.0, -0.02, d);
        
        // Gem colors
        vec3 gemCol;
        if(mod(fi, 3.0) == 0.0) gemCol = vec3(0.9, 0.3, 0.5); // Ruby
        else if(mod(fi, 3.0) == 1.0) gemCol = vec3(0.3, 0.7, 0.9); // Sapphire
        else gemCol = vec3(0.5, 0.9, 0.4); // Emerald
        
        // Inner glow
        float glow = smoothstep(0.05, 0.0, d) * 0.5;
        col += gemCol * crystal;
        col += gemCol * glow;
    }
    
    // Volumetric light shafts
    float shaft = sin(uv.x * 10.0 + t) * 0.5 + 0.5;
    shaft *= smoothstep(-0.5, 0.5, uv.y) * (1.0 - smoothstep(0.3, 0.8, uv.y));
    col += vec3(0.8, 0.9, 1.0) * shaft * 0.1;
    
    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