Project_2026-01-30_11-04-21

GLSL shader by scry · created 2026-01-30 · 30s 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.
#define time iTime*2.*pi/30.
#define R iResolution.xy
#define ar R.x/R.y
vec3 cs = vec3(1.,2.,3.);
mat2 r2d(float a) {
    return mat2(cos(a),sin(a),-sin(a),cos(a));
}
float smin(float a, float b, float k) {
    float h = clamp(0.5 + 0.5*(b-a)/k, 0.0, 1.0);
    return mix(b, a, h) - k*h*(1.0-h);
}

Buffer A (iChannel0)


float sp(vec2 uv, float t) {
    vec2 cv = vec2(length(uv),atan(uv.x,uv.y));
    //cv *= r2d(deg*90.);
    cv.y *= 4.;
    cv.y += t*-20.;
    float d = 0.;
    d += fract(cv.y/pi/2.+exp(1.-cv.x*10.)-cv.x)*0.1+cv.x;
    d *= exp(0.5-cv.x*0.3);
    return d;
}

vec4 map(vec3 p) {
    p.yz *= r2d(deg*+10.-0.15*-sin(time));
    p.z += 15.+sin(time)*10.;
    p.y -= -1.5-sin(time)*1.5;
    
    //p.z += 2.5+sin(time)*2.;
    //p.yz *= r2d(-sin(time)*0.);
    //p.y -=0.5;
    // Plane with height map from sp function
    //
    //p.yz *= r2d(deg*-30.+sin(time)*-0.5);
    //p.y -= 3.5+sin(time);
    //p.z += sin(time)*3.;
    //p.yz *= r2d(deg*60.+sin(time)*-0.5);
    //p.z += sin(time)*2.;
    p.xz *= r2d(-time);
    //p.z += sin(time/2.)*3.;
    //p.yz *= r2d(sin(time)*deg*-20.);
    //p.z += sin(time)*2.;
    vec2 uv = p.xz;
    //p.y -= 1.5;
    float height = sp(uv, time*2.);
    float planeDist = p.y - height*-1.;
    
    // Grid of cubes above the scene
    vec3 cubeP = p - vec3(0., -3., 0.);
    vec3 id = floor(cubeP / 1.5);
    vec3 q = mod(cubeP, 1.5) - 0.75;
    float cubeDist = length(max(abs(q) - vec3(0.3), 0.0));
    cubeDist = max(cubeDist,-p.y+5.);
    float d = min(planeDist, cubeDist);
    d = min(d, length(p)-0.1);
    d = smin(d,(length(p)-0.15)*0.2,0.2);
    return vec4(p, d);
}

vec2 RM(vec3 ro, vec3 rd) {
    float dO = 0.0;
    float ii = 0.0;
    for (int i=0; i<1200; i++) {
        vec3 p = ro + rd*dO;
        float dS = map(p).w;
        dO += dS*0.1;
        ii += 0.25; // Can be used for effects based on steps
        if (dO > 200.0 || dS < 0.001) break;
    }
    return vec2(dO, ii);
}

vec3 calcNormal(vec3 p) {
    vec2 e = vec2(0.005, 0.0);
    return normalize(vec3(
        map(p + e.xyy).w - map(p - e.xyy).w,
        map(p + e.yxy).w - map(p - e.yxy).w,
        map(p + e.yyx).w - map(p - e.yyx).w
    ));
}

void mainImage(out vec4 fragColor, in vec2 fragCoord) {
    vec2 uv = fragCoord.xy / iResolution.xy;
    vec2 tv = uv;
    uv -= 0.5;
    uv.x *= ar;
    vec3 col = vec3(0.);
    vec3 ro = vec3(0.0, 0.0, 0.0); // Ray Origin
    uv.y += sin(time-0.)*0.1+0.4;
    //ro.z += -sin(time)*10.;
    vec3 rd = normalize(vec3(uv, -5.+sin(time)*4.)); // Ray Direction

    int bounces = 3;
    float reflectivity = 0.5;
    vec3 accum = vec3(0.);
    float energy = 1.0;
    
    for (int bounce = 0; bounce < 3; bounce++) {
        if (bounce >= bounces) break;
        
        vec2 d = RM(ro, rd);
        float t = d.x;
        vec3 p = ro + rd * t;
        
        vec3 bounceCol = vec3(0.);
        bounceCol += 1.-d.x*0.15;
        bounceCol += sin(d.y*0.02-cs+time*3.)*0.4;
        bounceCol = clamp(bounceCol,0.,1.);
        bounceCol += sin(d.y*0.2+time*8.+cs)*0.1;
        
        accum += bounceCol * energy;
        
        vec3 n = calcNormal(p);
        rd = reflect(rd, n);
        ro = p + n * 0.01;
        energy *= reflectivity;
    }
    
    col = accum;
    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