A random space, drawn until it casts a shadow.
A tall cube of random space, filled the way a drawing fills a page. Sheaves of hairline planes stand in it, each one rectangle repeated and nudged a little further along. Hundreds of walks follow a field of sines and turn back at its walls, so the tangle takes the shape of the room it is in. Cords swell and thin through it, and a few loops get out. Slabs stand upright or bristle out of a dense core, specks scatter around them, and a handful of orange threads wind through everything. The hairlines are laid down at partial strength, so where they crowd the drawing goes dark on its own.
Play it and it turns. Every so often it comes down from the top and another space builds up from the floor. Switch the ground to paper to draw it in black on white.
The walls
javascript·skia.js
// steer gently into the field; a wall turns the walk back into the room
for (let i = 1; i < n; i++) {
dir = normalize(mix(dir, normalize(flow(p)), steer));
p = p + dir * step;
for (const a of [x, y, z]) if (abs(p[a]) > box[a]) {
p[a] = sign(p[a]) * (2 * box[a] - abs(p[a]));
dir[a] = -dir[a];
}
}
The sheaves
javascript·skia.js
// one rectangle, repeated, each copy nudged further along its normal
for (let c = 0; c < copies; c++, depth += step) {
const jitter = 1 + random(-1, 1) * 0.04;
outline(plane(normal, depth), half * jitter);
}
The ink
glsl·skia.frag
// solids take a faceted light; hairlines are ink at partial strength,
// so where they crowd, the drawing darkens by itself
if (solid) colour = tone * (0.68 + 0.42 * light) + 0.1 * light * light;
else alpha = (1.0 - fade) * (1.0 - haze);
if (born > grow) discard; // built from the floor up
References