Colors Original
A raymarched volume that morphs from cube to sphere to torus as you scroll, and prints its light as a halftone.
The study runs live under its video, in your browser, with its own controls, so you can switch the idea off and on and see what it does.
The soft solid is a volume, not a surface. The shader takes 44 samples along each ray inside a bounding sphere. The distance field morphs from cube to sphere to torus by blending their fields, and the light is printed as a halftone.
A volume has no surface, so it has no normals to light. Each sample instead asks how the distance field changes toward the light. On the lit side the field rises toward the light; on the far side it falls deeper inside. That costs one extra lookup per sample, and light wraps softly through the edge of the form.
vec3 L = normalize(Lp - p);// on the lit side the field rises toward the light, on the far side it falls deeper inside.// Distance field, so map(p + L e) - d, not d - map.float dl = clamp((map(p + L * 0.12) - d) / 0.12, 0.0, 1.0);float light = 0.08 + 0.92 * pow(dl, 1.4);The halftone is a screen turned 45 degrees. An axis-aligned dot grid read as an LED panel. Dot area follows the accumulated light, so the shadow side prints nothing and the highlights close up into solid ink.
One bug only showed up when measured. A dot with zero radius still printed its antialiasing band, which drew a faint blue grid over the whole black ground, up to 42 out of 255. The fix fades each dot by its radius, and the ground went back to pure black.
vec2 cell = fract(mat2(0.7071, 0.7071, -0.7071, 0.7071) * frag / uCell) - 0.5;float r = 0.64 * sqrt(smoothstep(0.16, 0.95, lum));float aa = 1.1 / uCell;// the r / aa factor: a zero-radius dot must print nothingfloat dotm = (1.0 - smoothstep(r - aa, r + aa, length(cell))) * clamp(r / aa, 0.0, 1.0);The cube looked alive and the sphere looked frozen. Both spin at the same rate, but a sphere is symmetric about its spin axis, so nothing on it appears to move. A blank sphere turning reads as a sphere standing still.
Features on a turning form are what make the turn visible; perception research calls it the kinetic depth effect. So the sphere carries narrow grooves of lighter print on an axis 50 degrees off the spin. Two attempts failed first: grooves read per sample averaged away through the volume, and grooves read on a radius of 0.5 crushed into a ring inside the edge. They are read once per pixel, on a radius of 0.62, and printed into the dot size, because a pattern made only of light vanished where the halftone closes up.
The torus carries eight soft bands that travel round its tube like a current, and it rocks: a roll of 14 degrees each way, and a nod of up to 15 degrees toward you, never away, so the hole stays open.
The first camera spun the object about the world's vertical axis with the object tilted, which is a wobble. The torus then turned edge on twice a turn and its hole closed. Now the object sits on a turntable seen from the isometric pitch, 35.26 degrees. The ring lies in the spin plane, so the hole reads at every angle.
In the lab, scroll turns the shape like a dial with detents. The shape is always whole at rest, a bar beside the shape's name shows how far you are from the next change, and the shape leans a little toward the next one as the bar fills. A wheel notch moves the bar six percent. What you see is that value after a second order spring, because Lenis's smoothing is first order: it started each notch at full speed, and the jump in speed read as a tick. On this page the shape is set by the buttons instead.
The cost: up to seven field lookups per sample, about 165 frames per second at 1920 by 1080 on an RTX 4060 Ti.