Iridescent Ground Ritual

GLSL shader by scry · created 2026-10-11 · updated 2026-10-12 · 10s 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));
}

// SDF Functions
float sdSphere(vec3 p, float s) {
    return length(p) - s;
}

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 sdPlane(vec3 p, vec3 n, float h) {
    return dot(p, n) + h;
}

// Scene SDF
float map(vec3 p) {
    // Plane height displacement based on fractal pattern
    float planeHeight = 0.0;
    if (p.y < 0.5) {
        vec2 q = p.xz * 0.8;
        float v = 0.0;
        float a = 1.0;
        for (int i = 0; i < 6; i++) {
            float fi = float(i);
            q = r2d(0.9 + fi * 0.37) * q * 1.55;
            q += sin(q.yx * 1.3 + time + fi) * 0.45;
            v += a * sin(q.x + sin(q.y * 1.7 - time + fi));
            a *= 0.55;
        }
        planeHeight = (v * 0.25 + 0.5) * 0.3;
    }
    float sphere = sdSphere(p - vec3(0., 0., 0.), 0.5);
    float box = sdBox(p - vec3(2., 0., 0.), vec3(0.4));
    float plane = sdPlane(p - vec3(0., planeHeight, 0.), vec3(0., 1., 0.), 1.0);
    return min(min(sphere, box), plane);
}

// Normal calculation
vec3 calcNormal(vec3 p) {
    vec2 e = vec2(0.001, 0.0);
    return 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)
    ));
}

// Raymarching
vec2 raymarch(vec3 ro, vec3 rd) {
    float t = 0.0, steps = 0.0;
    for (int i = 0; i < 64; i++) {
        float d = map(ro + rd * t);
        if (d < 0.001 || t > 20.0) break;
        t += d * 0.8;
        steps += 1.0;
    }
    return vec2(t, steps);
}

// Blinn-Phong lighting
vec3 blinnPhongLighting(vec3 normal, vec3 viewDir, vec3 lightDir, vec3 lightColor, vec3 ambientColor, float shininess) {
    vec3 halfDir = normalize(lightDir + viewDir);
    float diff = max(dot(normal, lightDir), 0.0);
    float spec = pow(max(dot(normal, halfDir), 0.0), shininess);
    
    vec3 ambient = ambientColor;
    vec3 diffuse = diff * lightColor;
    vec3 specular = spec * lightColor;
    
    return ambient + diffuse + specular;
}

// Soft shadows
float softShadow(vec3 ro, vec3 rd, float mint, float tmax, float k) {
    float res = 1.0;
    float t = mint;
    for (int i = 0; i < 16; i++) {
        float h = map(ro + rd * t);
        res = min(res, k * h / t);
        t += clamp(h, 0.02, 0.1);
        if (res < 0.001 || t > tmax) break;
    }
    return clamp(res, 0.0, 1.0);
}

// Camera ray from origin looking at target
vec3 getCameraRay(vec3 ro, vec3 target, vec2 uv) {
    vec3 forward = normalize(target - ro);
    vec3 right = normalize(cross(forward, vec3(0.0, 1.0, 0.0)));
    vec3 up = cross(right, forward);
    
    vec3 rayDir = normalize(
        forward +
        right * (uv.x - 0.5) * ar +
        up * (uv.y - 0.5)
    );
    return rayDir;
}

Buffer A (iChannel0)

// Fractal stacked-sine texture for the ground plane
vec3 planeTexture(vec2 p) {
    vec2 q = p * 0.8;
    float v = 0.0;
    float a = 1.0;
    for (int i = 0; i < 6; i++) {
        float fi = float(i);
        q = r2d(0.9 + fi * 0.37) * q * 1.55;
        q += sin(q.yx * 1.3 + time + fi) * 0.45;
        v += a * sin(q.x + sin(q.y * 1.7 - time + fi));
        a *= 0.55;
    }
    v = v * 0.25 + 0.5;
    
    // Multi-layer color palette with depth
    vec3 c1 = 0.5 + 0.5 * cos(6.28318 * (v * 2.0 + vec3(0.1, 0.4, 0.7)));
    vec3 c2 = 0.5 + 0.5 * cos(6.28318 * (v * 3.5 + vec3(0.8, 0.2, 0.5)));
    vec3 baseColor = mix(c1, c2, smoothstep(0.3, 0.7, v));
    
    // Add iridescent shimmer
    float shimmer = sin(v * 12.0 + time * 0.5) * 0.5 + 0.5;
    baseColor += vec3(0.1, 0.15, 0.2) * shimmer;
    
    // Enhance with subtle lines and ridges
    float ridges = smoothstep(0.85, 1.0, abs(sin(v * 22.0))) * 0.4;
    return baseColor + ridges;
}

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = fragCoord.xy / iResolution.xy;
    
    // Camera setup
    // Mouse orbit around target
    vec3 target = vec3(0.0, 0.5, 0.0);
    float radius = 5.0;
    float angle = nm.x * 6.28318 + iTime * 0.3;
    float elevation = nm.y * 3.14159;
    vec3 ro = target + vec3(sin(elevation) * cos(angle), cos(elevation), sin(elevation) * sin(angle)) * radius;
    
    vec3 rd = getCameraRay(ro, vec3(0.0, 0.5, 0.0), uv);
    
    // Raymarch
    vec2 res = raymarch(ro, rd);
    float t = res.x;
    
    // Shading
    vec3 col = vec3(0.);
    if (t < 20.0) {
        vec3 pos = ro + rd * t;
        vec3 normal = calcNormal(pos);
        
        vec3 viewDir = -rd;
        vec3 ambientColor = vec3(0.2, 0.22, 0.25);
        
        // Multiple light sources
        vec3 lighting = ambientColor;
        
        // Green light from left
        vec3 lightPos1 = vec3(-5.0, 2.0, 0.0);
        vec3 lightDir1 = normalize(lightPos1 - pos);
        vec3 lightColor1 = vec3(0.133, 0.545, 0.133);
        float shadow1 = softShadow(pos + normal * 0.01, lightDir1, 0.1, 10.0, 16.0);
        lighting += blinnPhongLighting(normal, viewDir, lightDir1, lightColor1, vec3(0.0), 32.0) * shadow1;
        
        // Red/pink light from right
        vec3 lightPos2 = vec3(5.0, 2.0, 0.0);
        vec3 lightDir2 = normalize(lightPos2 - pos);
        vec3 lightColor2 = vec3(0.863, 0.078, 0.235);
        float shadow2 = softShadow(pos + normal * 0.01, lightDir2, 0.1, 10.0, 16.0);
        lighting += blinnPhongLighting(normal, viewDir, lightDir2, lightColor2, vec3(0.0), 32.0) * shadow2;
        
        // White light from top
        vec3 lightPos3 = vec3(0.0, 6.0, 0.0);
        vec3 lightDir3 = normalize(lightPos3 - pos);
        vec3 lightColor3 = vec3(0.000, 0.498, 1.000);
        float shadow3 = softShadow(pos + normal * 0.01, lightDir3, 0.1, 10.0, 16.0);
        lighting += blinnPhongLighting(normal, viewDir, lightDir3, lightColor3, vec3(0.0), 32.0) * shadow3;
        
        col = lighting;
        // Fractal texture on the plane only (plane at y = -1)
        if (pos.y < -0.95) {
            col *= planeTexture(pos.xz);
        }
    }
    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