Files
Digital Artifex c8f3f1e981 Added shader packs
2025-08-19 09:33:45 -04:00

281 lines
8.1 KiB
GLSL

const float epsilon = 0.02;
const float pi = 3.14159265359;
const float speed = 3.0;
const vec3 wallsColor = vec3(0.05, 0.025, 0.025);
const vec3 lightColor = vec3(0.3, 0.6, 1.0);
const vec3 lightColor2 = vec3(0.5, 0.35, 0.35);
const vec3 fogColor = vec3(0.05, 0.05, 0.2);
const float curvAmout = 0.075;
const float reflAmout = 0.8;
//Distance Field functions by iq :
//https://iquilezles.org/articles/distfunctions
float sdCylinder( vec3 p, vec3 c )
{
return length(c.xy - p.xz) - c.z;
}
float sdCappedCylinder( vec3 p, vec2 h )
{
vec2 d = abs(vec2(length(p.xz),p.y)) - h;
return min(max(d.x,d.y),0.0) + length(max(d,0.0));
}
float sdSphere( vec3 p, float s )
{
return length(p)-s;
}
float sdBox( vec3 p, vec3 b )
{
vec3 d = abs(p) - b;
return min(max(d.x,max(d.y,d.z)),0.0) + length(max(d,0.0));
}
vec3 opRep( vec3 p, vec3 c )
{
return mod(p,c)-0.5*c;
}
vec2 linearStep2(vec2 mi, vec2 ma, vec2 v)
{
return clamp((v - mi) / (ma - mi), 0.0 ,1.0);
}
float tunnel( vec3 p, vec3 c )
{
return -length(c.xy - p.xz) + c.z;
}
vec4 distfunc(vec3 pos)
{
vec3 repPos = opRep(pos, vec3(4.0, 1.0, 4.0));
vec2 sinPos = sin((pos.z * pi / 8.0) + vec2(0.0, pi)) * 1.75;
vec3 repPosSin = opRep(pos.xxz + vec3(sinPos.x, sinPos.y, 0.0), vec3(4.0, 4.0, 0.0));
float cylinders = sdCylinder(vec3(repPos.x, pos.y, repPos.z), vec3(0.0, 0.0, 0.5));
float s = sin(iTime*3.0 + floor(pos.z*0.25));
float cutCylinders1 = sdBox(vec3(pos.x, pos.y, repPos.z), vec3(100.0, clamp(s, 0.025, 0.75), 1.0));
float cutCylinders2 = sdBox(vec3(repPos.x, pos.y, repPos.z), vec3(0.035, 100.0, 10.0));
float cuttedCylinders = max(-cutCylinders2, max(-cutCylinders1, cylinders));
float innerCylinders = sdCylinder(vec3(repPos.x, pos.y, repPos.z), vec3(0.0, 0.0, 0.15));
float tubes1 = sdCylinder(vec3(repPosSin.x, 0.0, pos.y - 0.85), vec3(0.0, 0.0, 0.025));
float tubes2 = sdCylinder(vec3(repPosSin.y, 0.0, pos.y + 0.85), vec3(0.0, 0.0, 0.025));
float tubes = min(tubes1, tubes2);
float lightsGeom = min(tubes, innerCylinders);
float resultCylinders = min(cuttedCylinders, lightsGeom);
float spheres = sdSphere(vec3(repPos.x, pos.y, repPos.z), (s*0.5+0.5)*1.5);
float light = min(tubes, spheres);
vec2 planeMod = abs(fract(pos.xx * vec2(0.25, 4.0) + 0.5) * 4.0 - 2.0) - 1.0;
float planeMod2 = clamp(planeMod.y, -0.02, 0.02) * min(0.0, planeMod.x);
float cylindersCutPlane = sdCylinder(vec3(repPos.x, pos.y, repPos.z), vec3(0.0, 0.0, 0.6));
float spheresCutPlane = sdSphere(vec3(repPos.x, pos.y, repPos.z), 1.3);
float plane = 1.0 - abs(pos.y + clamp(planeMod.x, -0.04, 0.04) + planeMod2);
float t = tunnel(pos.xzy * vec3(1.0, 1.0, 3.0), vec3(0.0, 0.0, 8.5));
float cutTunnel = sdBox(vec3(pos.x, pos.y, repPos.z), vec3(100.0, 100.0, 0.1));
plane = min(max(-cutTunnel, t), max(-spheresCutPlane, max(-cylindersCutPlane, plane)));
float dist = min(resultCylinders, plane);
float occ = min(cuttedCylinders, plane);
float id = 0.0;
if(lightsGeom < epsilon)
{
id = 1.0;
}
return vec4(dist, id, light, occ);
}
vec3 rayMarch(vec3 rayDir, vec3 cameraOrigin)
{
const int maxItter = 100;
const float maxDist = 30.0;
float totalDist = 0.0;
vec3 pos = cameraOrigin;
vec4 dist = vec4(epsilon);
for(int i = 0; i < maxItter; i++)
{
dist = distfunc(pos);
totalDist += dist.x;
pos += dist.x * rayDir;
if(dist.x < epsilon || totalDist > maxDist)
{
break;
}
}
return vec3(dist.x, totalDist, dist.y);
}
vec3 rayMarchReflection(vec3 rayDir, vec3 cameraOrigin)
{
const int maxItter = 30;
const float maxDist = 20.0;
float totalDist = 0.0;
vec3 pos = cameraOrigin;
vec4 dist = vec4(epsilon);
for(int i = 0; i < maxItter; i++)
{
dist = distfunc(pos);
totalDist += dist.x;
pos += dist.x * rayDir;
if(dist.x < epsilon || totalDist > maxDist)
{
break;
}
}
return vec3(dist.x, totalDist, dist.y);
}
//Inpired From iq's ao :
//https://www.shadertoy.com/view/Xds3zN
vec2 AOandFakeAreaLights(vec3 pos, vec3 n)
{
vec4 res = vec4(0.0);
for( int i=0; i<3; i++ )
{
vec3 aopos = pos + n*0.3*float(i);
vec4 d = distfunc(aopos);
res += d;
}
float ao = clamp(res.w, 0.0, 1.0);
float light = 1.0 - clamp(res.z*0.3, 0.0, 1.0);
return vec2(ao, light * ao);
}
//Camera Function by iq :
//https://www.shadertoy.com/view/Xds3zN
mat3 setCamera( in vec3 ro, in vec3 ta, float cr )
{
vec3 cw = normalize(ta-ro);
vec3 cp = vec3(sin(cr), cos(cr),0.0);
vec3 cu = normalize( cross(cw,cp) );
vec3 cv = normalize( cross(cu,cw) );
return mat3( cu, cv, cw );
}
//Normal and Curvature Function by Nimitz;
//https://www.shadertoy.com/view/Xts3WM
vec4 norcurv(in vec3 p)
{
vec2 e = vec2(-epsilon, epsilon);
float t1 = distfunc(p + e.yxx).x, t2 = distfunc(p + e.xxy).x;
float t3 = distfunc(p + e.xyx).x, t4 = distfunc(p + e.yyy).x;
float curv = .25/e.y*(t1 + t2 + t3 + t4 - 4.0 * distfunc(p).x);
return vec4(normalize(e.yxx*t1 + e.xxy*t2 + e.xyx*t3 + e.yyy*t4), curv);
}
vec4 lighting(vec3 n, vec3 rayDir, vec3 reflectDir, vec3 pos)
{
vec3 light = vec3(0.0, 0.0, 2.0 + iTime * speed);
vec3 lightVec = light - pos;
vec3 lightDir = normalize(lightVec);
float atten = clamp(1.0 - length(lightVec)*0.1, 0.0, 1.0);
float spec = pow(max(0.0, dot(reflectDir, lightDir)), 10.0);
float rim = (1.0 - max(0.0, dot(-n, rayDir)));
return vec4(spec*atten*lightColor2 + rim*0.2, rim);
}
vec3 color(float id, vec3 pos)
{
vec2 fp = vec2(1.0) - linearStep2(vec2(0.0), vec2(0.01), abs(fract(pos.xz * vec2(0.25, 1.0) + vec2(0.0, 0.5)) - 0.5));
float s = fp.y + fp.x;
return mix(wallsColor + s*lightColor*0.5, lightColor, id);
}
vec4 finalColor(vec3 rayDir, vec3 reflectDir, vec3 pos, vec3 normal, float ao, float id)
{
vec4 l = lighting(normal, rayDir, reflectDir, pos);
vec3 col = color(id, pos);
float ao1 = 0.5 * ao + 0.5;
float ao2 = 0.25 * ao + 0.75;
vec3 res = (mix(col * ao1, col, id) + l.xyz) * ao2;
return vec4(res, l.w);
}
void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
vec2 uv = fragCoord.xy/iResolution.xy;
float move = iTime * speed;
vec2 sinMove = sin((move * pi) / 16.0 + vec2(1.0, -1.0)) * vec2(5.0, 0.35);
float camX = sinMove.x;
float camY = 0.0;
float camZ = -5.0 + move;
vec3 cameraOrigin = vec3(camX, camY, camZ);
vec3 cameraTarget = vec3(0.0, 0.0, cameraOrigin.z + 10.0);
vec2 screenPos = uv * 2.0 - 1.0;
screenPos.x *= iResolution.x/iResolution.y;
mat3 cam = setCamera(cameraOrigin, cameraTarget, sinMove.y);
vec3 rayDir = cam*normalize(vec3(screenPos.xy,1.0));
vec3 dist = rayMarch(rayDir, cameraOrigin);
vec3 res;
vec2 fog;
if(dist.x < epsilon)
{
vec3 pos = cameraOrigin + dist.y*rayDir;
vec4 n = norcurv(pos);
vec2 ao = AOandFakeAreaLights(pos, n.xyz);
vec3 r = reflect(rayDir, n.xyz);
vec3 rpos = pos + n.xyz*0.02;
vec3 reflectDist = rayMarchReflection(r, rpos);
fog = clamp(1.0 / exp(vec2(dist.y, reflectDist.y)*vec2(0.15, 0.2)), 0.0, 1.0);
vec4 direct = finalColor(rayDir, r, pos, n.xyz, ao.x, dist.z) + n.w*curvAmout;
vec4 reflN;
vec2 reflAO;
vec3 reflFinal;
if(reflectDist.x < epsilon)
{
vec3 reflPos = rpos + reflectDist.y*r;
reflN = norcurv(reflPos);
reflAO = AOandFakeAreaLights(reflPos, reflN.xyz);
vec3 rr = reflect(r, reflN.xyz);
vec4 refl = finalColor(r, rr, reflPos, reflN.xyz, reflAO.x, reflectDist.z);
vec3 reflAreaLights = reflAO.y * lightColor * 0.5;
reflFinal = (refl.xyz + reflN.w*curvAmout + reflAreaLights) * fog.y * reflAmout * direct.w;
}
else
{
reflFinal = vec3(0.0, 0.0, 0.0);
}
vec3 areaLightsColor = ao.y * lightColor * 0.5;
res = mix(fogColor, direct.xyz + reflFinal + areaLightsColor, fog.x);
}
else
{
res = fogColor;
fog = vec2(0.0);
}
fragColor = vec4(res, (dist.z) * fog);
}