Shaped marks — the particle silhouette
swarm and emitter both carry shape and points. They are the only two
scenes that do: the attractor’s marks are a chaos-game accumulation, and at the
densities that make a figure one mark is a point, so a silhouette there would be
invisible on principle rather than by tuning
(ADR-0084).
shape is a numeric selector, like kaleido_edge — the expression grammar
has no strings, so a star is shape = "3".
shape | mark | what it draws |
|---|---|---|
0 | disc | the default, and exactly what these scenes drew before the roster existed. On the swarm a round blob; on the emitter its elongated glint (see spin above) |
1 | ring | an annulus the same size as the disc: brightest at 0.7 of the mark’s radius, dark at the centre, with a hole reaching 0.4 of it |
2 | polygon | a regular points-sided polygon, one vertex pointing along +x |
3 | star | a points-pointed star, valleys at 0.45 of the tip radius |
4 | heart | a heart, point down |
points is the count for polygon and star, 3 to 12, default 5. It does
nothing on disc, ring or heart. Past a dozen the marks these are for — a
few pixels across — are a disc with a rough edge.
The star arm’s three shape params
The star was one welded silhouette until a batch of six reference images turned
out to be five requests for parameters this arm did not have. It has them
now, and they reach swarm, emitter and shape_field alike — one chunk,
one roster, so a shape a particle wears and a figure a field draws cannot drift.
| param | range | default | does |
|---|---|---|---|
star_valley | 0.05..0.95 | 0.45 | the valley radius as a fraction of the tip’s. Low is a sharp, thin-spiked star; high is a bumpy polygon |
star_curve | -0.9..0.9 | 0 | bows the edge between tip and valley. Positive bows it inward — the concave sparkle, which a straight-edged star cannot make at any valley radius. Negative bulges it out |
star_jitter | 0..1 | 0 | per-spike variation in tip length, for the hand-drawn / irregular “bang” look |
Every default is an exact identity, and that is an obligation rather than
taste: the shared chunk means these knobs reach the particle path, so anything
but the old welded constants would move every shipped shape = "3" preset. All
30 golden baselines re-bless byte-identical.
[params]shape = "3"points = "4"star_valley = "0.18" # a long, sharp four-point sparklestar_curve = "0.55" # ...with concave edgesThree things worth knowing before you tune them:
star_jitteris seeded, not random. The per-spike lengths come from an integer hash of the spike index, so the same preset draws the same figure in every run and on every machine. There is no separate lever to re-scatter the pattern while keeping the amount — if a look needs one, that is engine feedback.star_curveis where the field’s precision goes. A bowed edge has no closed-form distance, so it is sampled; the contoursshape_fielddraws are 0.0032 off true, which is invisible.star_jittercosts much more — up to 0.54 at seven points, because the angular fold measures against a point’s own spike and a longer neighbour can be nearer. On a particle mark none of this is visible (the sprite reads only the interior); on a big banded field, a heavily jittered star’s outer rings are approximate.- They are inert on the other four shapes, and nothing warns — the name is known, so no unknown-parameter warning fires. This paragraph is the warning.
These three MORPH the figure with the music, and that needs no engine work
All three are clamp-only — no rounding — so a binding drives them continuously and the silhouette
genuinely deforms. That is worth stating because the two params beside them, shape and points,
are rounded and therefore step. Verified by rendering: star_valley on bass and star_curve on
treble over a 120 BPM click visibly thickens and thins the arms and changes the spike proportions.
[params]star_valley = "0.20 + clamp(bass * 0.2941, 0, 0.25)" # spikes lengthen on the low endstar_curve = "0.55 - clamp(treb * 0.5000, 0, 0.30)" # edges straighten on the top end
[smoothing]star_valley = 0.25star_curve = 0.30Three things to know before binding them:
- On
shape_field, an easedstar_valleysilently changes the RING COUNT as well as the shape. The scene normalizes by the arm’s inradius, and the inradius is a function of the valley radius — so morphing the valley changes whatcolor_spanmeans, and the contour structure breathes along with the figure. On a particle mark this does not arise; on a banded field it is a continuous wobble in the background structure that you did not ask for. - A binding that sweeps
star_curvethrough 0 crosses a small discontinuity. At exactly zero the arm takes a closed-form straight-edge branch; either side of it takes a sampled one, and the two disagree by about0.0032(the polyline’s sagitta). Small, but it sits in the middle of the range you are most likely to animate through — bias the range to one side if it shows. - A curved or jittered star’s interior normalizes differently from a straight-edged one, and so
does its contour spacing. That branch divides by the figure’s own deepest-point distance rather
than by the straight edge plane’s perpendicular, so a
color_spancarried over from a straight-edged star is out by the ratio of the two references — roughly 1.1x at a shallow curve and 1.9x atstar_valley = 0.18.
Not in the roster and not a parameter: a star with eyes. Composing two discs onto a silhouette is multi-shape composition, which is neither a knob nor a name in the closed roster, and it is the one thing in that reference batch this engine still cannot reach.
polygon has far less range than star, and the reason is geometry rather
than tuning. A polygon’s corners sit at radius 1 and its edges at
cos(pi / points) of that, so by seven sides the figure is within 10 % of a
circle everywhere and reads as one: rendered side by side, a 7-gon field and a
disc field are the same picture. Reach for points = 3 or 4 — a field of
triangles is unmistakable — or reach for star, whose valleys sit at 0.45 of its
tips at every count.
points is a stepped parameter: it is rounded to a whole number, so an eased
points snaps at each half-integer rather than morphing. Both silhouettes fold
the angle by the count, and that fold only absorbs atan2’s branch cut when the
count divides the circle evenly — at a fractional count the mark tears along one
ray. This is kaleido_order’s rule for kaleido_order’s reason, and it is worth
stating because the surrounding vocabulary teaches the opposite: variant
interpolates (ADR-0060)
and the attractor’s IFS morphs
(ADR-0075). A
star’s angle fold is periodic in the count, so a fractional count is a
discontinuity and not an intermediate figure. shape is stepped for the stricter
version of the same reason — its values are names, and there is nothing halfway
between a ring and a polygon.
Two consequences worth planning around:
hash(beat_index)onpointsis the trick. The count flipping on each onset detection is what already worked onparametric_curve’sradial_offsetlobes, and it carries over:points = "7 + floor(hash(beat_index) * 2.999)"gives a field that re-cuts itself every beat, and the stepping is a feature there rather than a cost.- Small marks are where a silhouette earns its keep and also where it
disappears. A seven-pointed star three pixels across is mostly its own
anti-aliasing. If the shape is not reading, raise
sizebefore anything else — and note that on the swarm the population is fixed, so a mark large enough to have a legible figure fills the frame. The engine’s own shaped fixture reaches forzoomto thin the field rather than for a smaller mark.
A shaped mark drawn straight into the chain is a silhouette in additive light — there is no fill and no outline. The compositor adds, so black adds nothing and a dark edge cannot exist there: a
heartdrawn this way is a heart-shaped glow, brightest in its middle and fading to nothing at its outline, not a red body with a black rim. That is the scene’s deliberate scope.It is not the whole story, though, and the route out is not a workaround. Put the same scene in a
[layer]withblend = "multiply"and its marks subtract light instead — dark figures on a light ground, measured to display luma 0.9. See Dark on light. What stays true is the sentence’s other half: nothing in this engine decides what is in front of what, so a mark that occludes another figure is still unbuilt, and that is engine feedback.
The roster is closed: a shape that is not in the table is architect + dev
work, not a preset. That is the same trade
ADR-0061
made for fold edges.
Built from a8ce055 at version 0.115.0. This site tracks main and is not versioned per release.