Project_2026-01-15_21-58-34
GLSL shader by scry · created 2026-01-16 · 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/(40.+speed) //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)
vec2 getSurfaceUV(vec3 pc, float d) {
// Returns surface UV for the mobius strip
// pc.y is the local y on box cross-section
// Uses xz when on top/bottom faces, xy when on side faces
vec2 s = vec2(0.3,0.29);
float sd = step(d,0.1);
vec2 suv = pc.xz * step(-abs(pc.y), -s.x) + pc.xy * step(abs(pc.y), s.y);
suv *= sd;
return suv / 4.0;
}
float sdSegment(in vec2 p, in vec2 a, in vec2 b) {
vec2 pa = p-a, ba = b-a;
float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );
return length( pa - ba*h );
}
float getPattern(vec2 uv) {
uv *= 0.5;
uv = (fract(uv/pi-0.5)-0.5)*pi;
vec2 ov = uv;
vec2 av = uv;
uv = fract(uv*4.)-0.5;
uv *= 4.;
for (int i=0;i<6;i++) {
ov = abs(ov)-3.+av.y*0.5;
uv.xy = abs(uv.xy)-0.05+ov.x*0.5;
uv += sin(uv.yx*4.)*-0.25;
uv *= r2d(deg*45.+time);
}
for (int i=0;i<4;i++) {
uv.x = abs(uv.x)-0.01;
}
float pattern = 0.0;
pattern += sin(uv.x*20.)*0.5;
pattern += smoothstep(0.01,0.,sdSegment(uv,vec2(0.,-0.2),vec2(0.,0.2)))/2.;
return pattern;
}
vec3 getPatternCol(vec2 uv) {
return sin(uv.x*20.+cs)*0.5 + smoothstep(0.01,0.,sdSegment(uv,vec2(0.,-0.2),vec2(0.,0.2)))/2.;
}
vec3 lightPos = vec3(0.0, 0.0, 29.0);
float shadowSoftness = 16.0;
vec3 ambientCol = vec3(0.1, 0.12, 0.15);
vec3 lightCol = vec3(1.0, 0.95, 0.9);
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);
}
vec4 map(vec3 p) {
// Define your scene here using SDFs.
// Example: a simple sphere.
float a = 4.;
p.xz *= r2d(time/4.);
for (int i=0;i<9;i++) {
p.xz = abs(p.xz)-1.9*a;
p.y = abs(p.y)-1.8*a*2.;
a /= 1.4;
p.xz *= r2d(deg*45.*-2.);
p.yz *= r2d(deg*-45.*2.);
}
p.y -=1.;
p.y = abs(p.y)-1.15*a*2.;
float pzr = 0.8;
p.xy *= r2d(time);
//p.z = (fract(p.z*pzr)-0.5)/pzr;
vec3 pc = vec3(atan(p.x,p.y),length(p.xy),p.z);
pc.y -= 1.5;
float angle = pc.x; // Store angle before rotation for UV
pc.zy *= r2d(pc.x/1.);
float d = sdBox(vec3(pc),vec3(4.,0.3,0.3));
vec2 pv = getSurfaceUV(pc,d);
float pattern = getPattern(pv);
d -= pattern * 0.05; // Emboss the pattern onto the surface
//pc.yz *= r2d(deg*45.);
pc.yz = abs(pc.yz)-0.3;
float cylD = length(pc.yz)-0.06;
if (cylD < d) {
pattern = 24.0;
d = cylD;
}
return vec4(pv, pattern, d);
}
vec3 calcNormal(vec3 p) {
vec2 e = vec2(0.001, 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
));
}
float softShadow(vec3 ro, vec3 rd, float mint, float maxt) {
float res = 1.0;
float t = mint;
for (int i = 0; i < 32; i++) {
float h = map(ro + rd * t).w;
res = min(res, shadowSoftness * h / t);
t += clamp(h, 0.02, 0.2);
if (h < 0.001 || t > maxt) break;
}
return clamp(res, 0.0, 1.0);
}
vec2 RM(vec3 ro, vec3 rd) {
float dO = 0.0;
float ii = 0.0;
for (int i=0; i<100; i++) {
vec3 p = ro + rd*dO;
float dS = map(p).w;
dO += dS*0.99;
ii += 0.6; // Can be used for effects based on steps
if (dO > 30.0 || dS < 0.001) break;
}
return vec2(dO, ii);
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec2 uv = fragCoord.xy / iResolution.xy;
vec2 tv = uv;
uv -= 0.5;
uv.x *= ar;
uv *= exp((0.-zoom*0.1));
vec3 col = vec3(0.);
vec3 ro = vec3(0.0, 0.0, 25.0); // Ray Origin
//ro += sin(uv.xyx*vec3(1.,2.,3.)*4.)*2.;
uv *= 0.1;
ro.z += sin(sin(uv.x*(4.+sin(time+1.)*3.+1.))*3.)*1.+sin(sin(uv.y*(4.+sin(time)*3.))*4.)*1.;
//uv = abs(uv);
vec3 rd = normalize(vec3(uv, -0.1)); // Ray Direction
rd.z += sin(sin(uv.x*(4.+sin(time+1.)*3.+1.))*3.)*0.3+sin(sin(uv.y*(4.+sin(time)*3.))*4.)*0.2;
//uv *= 2.;
//ro.xy += vec2(sin(time),cos(time))*0.8;
//ro.z += -time;
ro.yz *= r2d(deg*10.);rd.yz *= r2d(deg*10.);
//ro.xz *= r2d(time/4.);rd.xz *= r2d(time/4.);
vec3 lp = lightPos;
//lp.xz *= r2d(time);
vec2 d = RM(ro, rd);
float t = d.x; // Distance to hit
vec3 p = ro + rd * t; // Hit point in 3D space
vec3 mp = map(p).xyz; // Note: map returns pc, not pv. See below for pv access.
if (t < 20.0) {
vec3 n = calcNormal(p);
vec3 l = normalize(lp - p);
float diff = max(dot(n, l), 0.0);
float sha = softShadow(p + n * 0.01, l, 0.02, length(lp - p));
col = ambientCol + lightCol * diff * sha;
} else {
col = vec3(0.02, 0.02, 0.04); // Background
}
//this gets the surface uv for painting the pattern on the surface of the mobius block thing
//below THIS line - now using the pattern function
vec2 patternUV = mp.xy;
//patternUV = getSurfaceUV(mp);
vec2 puv = getSurfaceUV(mp,d.x);
//puv = fract(puv*4.)-0.5;
//puv *= 4.;
//col += getPatternCol(puv);
col += sin(mp.z*10.+cs+p.y*0.2)*0.5;
col += step(-d.x,-20.)*(d.y*0.02);
fragColor = vec4(col, 1.0);
}
Image
Not used
More shaders by scry
- Spiral Nebula Nocturne
- Iridescent Ground Ritual
- Project_2026-08-15_18-22-06
- Project_2026-08-14_16-45-00
- Project_2026-07-24_15-10-23
- Project_2026-07-15_03-18-26
- Glass of Orange Juice (raymarched)
- Project_2026-07-13_00-53-50
- Project_2026-07-10_16-39-54
- Popcorn ceiling
- Project_2026-06-20_15-32-19
- Project_2026-06-25_12-22-43
Browse all public shaders · All shaders by scry · ShaderKit home
Unread comments
×Projects with new comments. Click to open and read.