Project_2026-03-01_18-18-20
GLSL shader by scry · created 2026-03-02 · 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. //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));
}
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 hash21(vec2 p) {
return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5453);
}
vec2 hash22(vec2 p) {
return fract(sin(vec2(dot(p,vec2(127.1,311.7)),dot(p,vec2(269.5,183.3))))*43758.5453);
}
Buffer A (iChannel0)
// Scene SDF
float mapScene(vec3 p) {
vec3 bp = p;
bp.xz *= r2d(0.6);
bp.xy *= r2d(0.4);
bp.yz *= r2d(time * 0.5);
//bp = abs(bp)-14.;
//bp = abs(bp)-14.;
for (int i=0;i<39;i++) {
bp = abs(bp)-0.03+sin(time+bp.yzx*2.)*0.01;
bp.xz *= r2d(cos(time/4.));
bp.yz *= r2d(cos(time/4.));
}
float cube = sdBox(bp, vec3(0.03+sin(time*2.+pi/2.)*0.01));
return cube;
}
vec3 calcNorm(vec3 p) {
vec2 e = vec2(0.001, 0.0);
return normalize(vec3(
mapScene(p + e.xyy) - mapScene(p - e.xyy),
mapScene(p + e.yxy) - mapScene(p - e.yxy),
mapScene(p + e.yyx) - mapScene(p - e.yyx)
));
}
vec2 raymarch(vec3 ro, vec3 rd) {
float t = 0.0;
float steps = 0.0;
for (int i = 0; i < 180; i++) {
vec3 p = ro + rd * t;
float d = mapScene(p)/2.5;
if (d < 0.001 || t > 130.0) break;
t += d;
steps += 1.0;
}
return vec2(t, steps);
}
// Voronoi star field
float starField(vec2 uv) {
float scale = 30.0;
vec2 id = floor(uv * scale);
vec2 gv = fract(uv * scale) - 0.5;
float minDist = 1.0;
for (int y = -1; y <= 1; y++) {
for (int x = -1; x <= 1; x++) {
vec2 offset = vec2(float(x), float(y));
vec2 n = hash22(id + offset);
vec2 p = offset + n - 0.5;
float d = length(gv - p);
minDist = min(minDist, d);
}
}
// Brightness varies per cell
float brightness = hash21(id) ;
brightness = pow(brightness, 8.0); // make most stars dim, few bright
float star = smoothstep(0.05, 0.0, minDist) * brightness;
// Twinkle
float twinkle = sin(iTime * 2.0 + hash21(id) * 6.28) * 0.5 + 0.5;
star *= mix(0.5, 1.0, twinkle);
return star;
}
// Aurora effect
vec3 aurora(vec2 uv) {
vec3 col = vec3(0.0);
float y = uv.y;
// Aurora only in upper portion
//if (y < 0.1) return col;
float intensity = smoothstep(0.1, .3, y) * smoothstep(0.95, 0.6, y)*0.5;
intensity += 0.8;
for (int i=0;i<4;i++) {
//uv += sin(uv.xy*2.+3.+time)*0.1;
}
for (int i = 0; i < 5; i++) {
float fi = float(i);
float freq = 1.5 + fi * 0.7;
float speed = 0.3 + fi * 0.1;
float wave = sin(uv.x * freq * 3.0 + iTime * speed + fi * 1.3)
* cos(uv.x * freq * 1.7 - iTime * speed * 0.7 + fi * 2.1);
wave = wave * 0.5 + 0.5;
// Green/blue/purple aurora palette
vec3 auroraCol = mix(
vec3(0.1, 0.8, 0.3),
vec3(0.3, 0.2, 0.9),
fi / 5.0
);
auroraCol = mix(auroraCol, vec3(0.8, 0.2, 0.5), smoothstep(0.6, 0.9, y));
col += auroraCol * wave * intensity * 0.35;
}
return col;
}
// Background
vec3 background(vec3 rd) {
rd = normalize(rd);
rd.xz *= r2d(deg*-190.);
// Sun
vec3 sunColor = vec3(1.0, 0.95, 0.85);
vec3 sunDir = normalize(vec3(2.0, 1.5, -3.0));
float sunDot = max(dot(rd, sunDir), 0.0);
vec3 sun = vec3(1.0, 0.95, 0.85) * pow(sunDot, 4000.0) * 80.0; // small bright disc
sun += vec3(1.0, 0.8, 0.5) * pow(sunDot, 400.0) * 0.3; // subtle glow halo
// Map ray direction to UV for sky
vec3 wrd = rd;
for (int i=0;i<14;i++) {
wrd += sin(wrd.yxz*2.)*0.1;
wrd.xz *= r2d(deg*220.+sin(time/4.+float(i))*deg*20.);
wrd.yz *= r2d(deg*120.+sin(time/4.+float(i))*deg*20.);
}
vec2 skyUV = vec2(atan(wrd.z, wrd.x) + 0.5, wrd.y * 0.5 + 0.5);
skyUV.x = sin(skyUV.x*2.);
// Dark sky gradient
vec3 sky = mix(vec3(0.01, 0.01, 0.03), vec3(0.02, 0.0, 0.06), skyUV.y);
// Stars
float stars = starField(skyUV * vec2(3.5, 1.2));
sky += vec3(0.9, 0.9, 1.0) * stars * 1.5;
for (int i=0;i<4;i++) {
//skyUV += sin(skyUV.yx*14.)*0.1;
}
// Aurora
sky += aurora(skyUV*1.)*0.01;
return sky + sun;
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
vec2 uv = fragCoord.xy / iResolution.xy;
vec2 p = (fragCoord - 0.5 * iResolution.xy) / iResolution.y;
p *= 4.0;
// Camera
//p.xz *= r2d(time);
vec3 ro = vec3(0.0, 0.0, 3.5);
vec3 rd = normalize(vec3(p, -6.5+sin(time/2.)*1.5));
//ro.xz *= r2d(time);
vec2 res = raymarch(ro, rd);
float t = res.x;
// Multi-bounce reflections for mirror stainless steel
vec3 col = vec3(0.0);
vec3 throughput = vec3(1.0);
vec3 metalColor = vec3(0.85, 0.86, 0.88); // bright stainless steel
float F0 = 0.7; // high base reflectivity for mirror steel
vec3 curRo = ro;
vec3 curRd = rd;
vec3 sunDir = normalize(vec3(2.0, 1.5, -3.0));
vec3 sunColor = vec3(1.0, 0.95, 0.85) * 3.5;
for (int bounce = 0; bounce < 5; bounce++) {
vec2 bres = (bounce == 0) ? res : raymarch(curRo, curRd);
float bt = bres.x;
col += bres.y*0.0002+sin(bres.y*0.2+cs+time*8.)*bres.y*bres.y*0.000002;
//col += bt*0.001;
if (bt >= 130.0) {
// Ray escaped — sample background
col += throughput * background(curRd * 4.0);
//col += bres.y*0.001+sin(bres.y*0.2+cs+time*8.)*bres.y*bres.y*0.00001;
break;
}
vec3 hp = curRo + curRd * bt;
vec3 n = calcNorm(hp);
vec3 viewDir = -curRd;
// Fresnel (Schlick) — mirror steel has high reflectivity at all angles
float cosTheta = max(dot(n, viewDir), 0.0);
float fres = F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
// Sun lighting (matches background sun direction)
vec3 halfDir = normalize(sunDir + viewDir);
float sunDiff = max(dot(n, sunDir), 0.0);
float sunSpec = pow(max(dot(n, halfDir), 0.0), 128.0);
// Subtle fill light from opposite side
vec3 fillDir = normalize(vec3(-1.0, 0.5, -1.0));
float fillDiff = max(dot(n, fillDir), 0.0) * 0.2;
// Diffuse colored ambient lights — green and purple
vec3 greenLightDir = normalize(vec3(-1.5, 0.8, 1.0));
vec3 purpleLightDir = normalize(vec3(1.0, -0.5, 1.5));
vec3 greenLight = vec3(0.15, 0.9, 0.3) * 1.0 * max(dot(n, greenLightDir), 0.0);
vec3 purpleLight = vec3(0.7, 0.15, 0.85) * 0.8 * max(dot(n, purpleLightDir), 0.0);
// Warm ambient from below
float upFace = dot(n, vec3(0.0, -1.0, 0.0)) * 0.5 + 0.5;
vec3 ambientWarm = mix(vec3(0.05, 0.02, 0.08), vec3(0.08, 0.15, 0.06), upFace) * 0.5;
// Add direct lighting contribution (non-reflected part)
vec3 direct = metalColor * (sunDiff * 0.6 * sunColor + fillDiff * vec3(0.3, 0.35, 0.5));
direct += sunSpec * sunColor * 15.; // bright sun specular
direct += metalColor * (greenLight + purpleLight + ambientWarm);
col += throughput * direct * (1.0 - fres)*0.15;
col += sin(n.x+n.y+n.z*40.+cs)*0.008;
// Attenuate throughput by fresnel reflectance * metal tint
throughput *= fres * metalColor;
// Set up next bounce
curRd = reflect(curRd, n);
curRo = hp + n * 0.005;
}
// Contrast boost before tone mapping
col *= 1.4;
// ACES tone map (punchier contrast than Reinhard)
col = clamp((col * (2.51 * col + 0.03)) / (col * (2.43 * col + 0.59) + 0.14), 0.0, 1.0);
col = pow(col, vec3(1.0 / 2.2));
fragColor = vec4(col, 1.0);
}
Image
Not used
More shaders by scry
- 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
- Visual Enhancer
- Project_2026-06-24_11-11-39
Browse all public shaders · All shaders by scry · ShaderKit home
Unread comments
×Projects with new comments. Click to open and read.