Skip to content

feat: a flat-graphic screensaver family — minimal vector patterns in the Book of Shapes register #307

Description

@BernardJen

Owner request: more screensavers like https://bookofshapes.com.

Book of Shapes is Nikolaj Sokolowski's curated gallery of "minimal, generative and
customizable" SVG patterns, sorted by generative technique — Grid (22), Radial (18),
Noise (18), Flow (17), Isometric (13), Organic (9), Distortion (8), Physics (5). The
landing grid shows things like Chevron Blocks, Interference Mesh, Node Garden, Flow
Dots / Lines / Poles, Iso Cube Wireframe, Iso Sphere, Scattered Cube Grid, Triangular
Mosaic, Spiral Morph, Broken Ring and Wave Field. (Only part of the ~110 is visible
without scrolling the lazy-loaded grid, so treat that list as a sample, not the index.)

What is actually being asked for, and why it is a real gap

The ask reads as "more screensavers", but the interesting part is the register, not
the count. We have 29 savers and they are almost all in one visual register: HDR
simulation with glow. grep bloom src/renderer/screensavers/*.js returns 20 of them,
and the ones that don't configure a bloom block mostly get the gl-base default rather
than deliberately opting out. Everything on the wall is emissive.

Book of Shapes is the opposite register: flat, vector, high-contrast, graphic-design
line work with no light in it at all.
Two or three colours, hard edges, no bloom, no
tonemap glow, often no motion beyond a slow drift. That is a genuinely absent mode in
our set, not a variation on an existing one.

Three reasons it suits this wall specifically:

And the art-direction lesson from #201 (bicycle) and #189 (aquarium) — that attempted
realism reads fake and stylisation doesn't — costs nothing here. This genre is
natively stylised. There is no realism to fall short of.

Scope: pick ~6, not 110

Proposing a shortlist, chosen for "not already covered, and reads at 6000x1200":

Working name Category Why this one
Iso Cube Wireframe Isometric Nothing in the set is isometric. Pure line work, tiles infinitely, unmistakably graphic
Chevron Blocks Grid The clearest example of the flat register. Two-tone, hard-edged, slow phase drift
Interference Mesh Radial Two radial line families beating against each other. Cheap, and the beat pattern is huge-scale — good on a long wall
Node Garden Noise Points with proximity-linked edges. The classic; distinct from boids because it is static structure, not motion
Triangular Mosaic Organic Flat-shaded irregular triangulation. Adjacent to voronoi but reads completely differently
Wave Field Distortion A line grid displaced by a wave. The one with real motion, so the family isn't entirely still

Deliberately excluded as already covered, and worth writing down so nobody adds a
near-duplicate later:

Six is a guess at the right size, not a requirement. If one of the six turns out flat
in review, drop it rather than replacing it — the point is establishing the register,
and four good ones do that as well as six.

Implementation notes

SVG in, WebGL2 out. The source pieces are SVG; ours must be fragment shaders on the
existing gl-base.js runtime. Every pattern in the shortlist is analytic per-pixel
(cube lattice, chevron parity, two radial phase fields, nearest-point distance,
barycentric triangulation, displaced grid), so this is a re-derivation, not a port. No
SVG parsing, no new dependency.

One file each, registered in SCREENSAVERS. Not a single book-of-shapes.js with a
mode switch. registry.js picks and rotates per saver, so a mega-file would show one of
its six modes per 10-minute slot with no way to select a specific one, and the preview
harness selector would only reach the wrapper. Six files means npm run screensaver -- iso-cube-wireframe works and the stepping keys behave.

Bloom should be near-zero or absent, and that needs saying explicitly in each
postFX block rather than left to the default. A flat pattern with our usual
intensity: 0.3 is a flat pattern with a haze over it — it stops being the thing the
owner asked for. Reviewers should check these with bloom at the saver's own settings
(0 in the harness), not at whatever they were last iterating with.

Randomness per the existing contract. Pure-shader savers get uniform vec4 iSeed
from FRAGMENT_HEADER — use it for lattice phase, palette rotation and orientation, and
perturb rather than randomise, since a wrong chevron angle or mesh spacing is the
difference between a pattern and a mess. A test asserts every shader saver actually uses
iSeed, so this is enforced, not advisory.

structure-baselines.js needs one hand-written line per saver. Flat line art will
sit at a low edge density — large uniform areas with sparse hard edges — plausibly near
the bottom of the current range, which is exactly where the file's own comment says the
relative band is narrower than measurement noise. Expect to tune these individually.
Do not run npm run baselines: it rewrites all 30 entries from one measurement and
would bury six intended additions in 29 lines of run-to-run noise. Add the lines by hand
in descending value order (a test enforces the ordering).

Art-Net (#59) probably benefits. Large flat areas of a single colour are a much
better signal for observeFrames()'s sparse tile grid than a glow gradient is, since the
tiles land on genuinely representative colour instead of on bloom falloff. Not a reason
to build this, but worth checking once #274 is settled.

Attribution. We are taking the genre — minimal generative pattern work — and these
motifs are long-standing generative-art classics (Truchet tiles, Voronoi/Delaunay
mosaics, node gardens, isometric lattices) that predate the site by decades. We should
not reproduce a specific piece from the gallery pixel-for-pixel or carry its exact
palette across, and the working names above are descriptive placeholders that should be
renamed to our own before merge. Cheap to get right at the start, awkward to fix after a
release on a public repo.

Costs

  • npm run shadercheck grows from 29x5 to ~35x5 shader compiles.
  • Six new entries each in SCREENSAVERS, structure-baselines.js, and the docs that
    list the set.
  • The 10-minute rotation gets six more slots, so any given saver's share drops from 1/29
    to 1/35. Worth a moment's thought about whether the flat family should be all of a
    rotation cycle or interleaved with the emissive ones — interleaved is probably right,
    but a wall that alternates between glowing simulation and flat line art may read as two
    different products.

Acceptance

  • Each new saver renders at 6000x1200 (W) with the pattern reading as a field, not a centred subject
  • Each survives ambient washout at 12% (L) with its structure intact
  • Bloom explicitly set per saver, not inherited
  • Five different seeds (S) each produce a defensible look — no broken parameter regions
  • npm run shadercheck green; npm test green including the iSeed usage assertion
  • structure-baselines.js entries hand-written and in descending order
  • Working names replaced with our own

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions