sh = () => raymarch({
antiAliasing: 3,
eye: `vec3(-3, 0, 5)`,
background: `mix(vec3(0.4, 0., 0.35), vec3(0), (length((gl_FragCoord.xy - u_resolution / 2.) / u_resolution.x)) * 1.2)`,
sceneSDF: `
#define PI ${Math.PI}
#define TAU ${Math.PI * 2}
#define NUM_COLORS ${palette.length}.
uniform sampler2D u_texture;
${iqSDF.sdBox()}
${iqSDF.sdCappedCylinder()}
${iqSDF.opUnion()}
${iqSDF.opSubtraction()}
${iqSDF.opSymY()}
${iqSDF.opRepLim()}
${iqSDF.opIntersection()}
${glslSnippets.rotate3D()}
${motionToolkit.easeOutCubic()}
${motionToolkit.easeInCubic()}
${motionToolkit.linearstep()}
${motionToolkit.linearstepUpDown()}
${noise}
float glow = 0.;
float glow2 = 0.;
// from https://www.youtube.com/watch?v=-adHIyjIYgk&list=WL&index=44
float sdGyroid(vec3 p, float scale, float thickness, float bias) {
p *= scale;
float d = abs(dot(sin(p), cos(p.zxy)) - bias) / scale - thickness;
return d * .5; // to prevent overstepping artefacts from the uneven (non lipschitz) continuous distance function, dividing it gives smaller steps that are less likely to jump through the geometry
}
vec2 sceneSDF(vec3 p) {
float t = u_time * TAU;
float sinT = sin(t);
float cosT = cos(t);
vec2 d = vec2(sdGyroid(p * rotate3D(t, vec3(0, 1, 0)) - vec2(t, 0.).xxy, 2., .0001, .8), 2.);
d.x = opIntersection(d.x, sdCappedCylinder(p, 2., 1.4));
float boxes = sdBox(opRepLim(p, vec3(.3, 10., 10.), vec3(10, 0, 0)), vec3(0.0001, 5., 2.));
boxes = 10e5;
boxes = opUnion(boxes, sdBox(opRepLim(p, vec3(10., .1, 10.), vec3(0., 20., 0.)), vec3(2., 0.0001, 2.)));
//boxes = opUnion(boxes, sdBox(opRepLim(p, vec3(10., 10., .3), vec3(0, 0, 10)), vec3(2., 5., 0.0001)));
d = opIntersection(d, vec2(boxes, 1.));
glow += 0.001 / (0.01 + d.x * d.x * 50.) / (float(AA * AA) * 1.);
d = opUnion(d, vec2(sdCappedCylinder(opSymY(p) - vec3(0, 2.02, 0), .01, 1.5), 3.));
if(u_time >= .2 && u_time < .8) {
float gyro = opIntersection(sdGyroid(p * rotate3D(t, vec3(0, 1, 0)) - vec2(t, 0.).xxy, 2., (easeOutCubic(linearstep(.2, .4, u_time)) - easeInCubic(linearstep(.6, .8, u_time))) * .15, 1.5), sdCappedCylinder(p, 2., 1.4));
d = opUnion(d, vec2(gyro, 3.));
}
const float N = 128.;
float lines = 10e5;
for(float i = 0.; i < N; i ++) {
vec3 pp = p * rotate3D(TAU / N * i, vec3(0, 1, 0));
float n = snoise(p.xz * .4 + vec2(sinT, cosT)) * .3;
pp += vec3(1.7, 2. - n, 0.);
lines = opUnion(lines, sdBox(pp, vec3(.0001, n, .0001)));
}
glow2 += 0.002 / (0.01 + lines * lines * 10.) / (float(AA * AA) * 1.);
d = opUnion(d, vec2(lines, 1.));
return d;
}`,
computeColor: `
vec3 computeColor(vec3 ro, vec3 rd, vec3 pos, float d, float m) {
vec3 nor = calcNormal(pos);
//return nor;
vec3 ref = reflect(rd, nor); // reflected ray
// material
vec3 col = texture2D(u_texture, vec2(m / NUM_COLORS, .5)).rgb;
// lighting
float occ = calcAO(pos, nor); // ambient occlusion
vec3 lig = normalize(vec3(-0.4, 0.7, -0.6)); // sunlight
float amb = clamp(0.5 + 0.5 * nor.y, 0.0, 1.0); // ambient light
float dif = clamp(dot(nor, lig), 0.0, 1.0); // diffuse reflection from sunlight
// backlight
float bac = clamp(dot(nor, normalize(vec3(-lig.x, 0.0, -lig.z))), 0.0, 1.0) * clamp(1.0 - pos.y, 0.0, 1.0);
float dom = smoothstep(-0.1, 0.1, ref.y); // dome light
float fre = pow(clamp(1.0 + dot(nor, rd), 0.0, 1.0), 2.0); // fresnel
float spe = pow(clamp(dot(ref, lig), 0.0, 1.0), 16.0); // specular reflection
dif *= softshadow(pos, lig, 0.02, 2.5);
dom *= softshadow(pos, ref, 0.02, 2.5);
vec3 lin = vec3(0.0);
lin += 1.30 * dif * vec3(1.00, 0.80, 0.55);
lin += 2.00 * spe * vec3(1.00, 0.90, 0.70) * dif;
lin += 0.40 * amb * vec3(0.40, 0.60, 1.00) * occ;
lin += 0.50 * dom * vec3(0.40, 0.60, 1.00) * occ;
//lin += 0.50 * bac * vec3(0.25, 0.25, 0.25) * occ;
//lin += 0.25 * fre * vec3(1.00, 1.00, 1.00) * occ;
col = col * lin;
// mix in fog?
// col = mix(col, vec3(0.8, 0.9, 1.0), 1.0 - exp(-0.0002 * d * d * d));
col = mix(col, vec3(0.), 1.0 - exp(-0.03 * d * d * d));
// gamma
// col = pow(col, vec3(0.4545));
return col;
}`,
effect: `
vec3 effect(vec3 c) {
c += glow * texture2D(u_texture, vec2(1.5 / NUM_COLORS, .5)).rgb;
c += glow2 * vec3(1., .2, .2);
return c;
}
`,
logShader: true
})