Bloom — bloom_amount, bloom_threshold, bloom_radius
The last stage in the per-preset chain, after the fold, so it blooms the
finished composite. It picks out the parts of the frame that are brighter than
bloom_threshold, blurs them across a pyramid, and adds the result back —
so bright things spill light into the pixels around them.
bloom_amount = 0 (the default) switches the whole stage off, offscreens and
all: a preset that does not bind it pays nothing and renders exactly as before.
| Param | Default | Meaning |
|---|---|---|
bloom_amount | 0 | Strength of the halo added back. 0 = off. Around 0.5–1.5 is a glow; past 2 the frame is mostly halo (clamped at 4). Bindable — this is the one to put a beat on. |
bloom_threshold | 1.0 | Where “bright” starts, in linear light after exposure — so it means the same thing at any stop. At the default only light that is genuinely over range blooms — see below. Lower it to bloom mid-tones too; 0 blooms everything. |
bloom_radius | 1.0 | How far the halo scatters, 0..4. Low is a tight rim around the figure; high is a wide wash. It does not change how much light there is, only where it goes. |
bloom_threshold = 1.0 is a meaningful default, not a placeholder. Since Plan
0045 the composite carries light above 1.0 (see below), so a threshold of 1
means precisely: bloom the light the display could not have shown anyway. Turn
bloom on with nothing else and you get halos exactly where the frame used to
clip, and nowhere else. That is usually what you want; reach for a lower
threshold when you want the whole figure to glow rather than just its hot spots.
The comparison happens after exposure, which is what lets that sentence stay
true when you move the stop. The bright-pass scales the light it
samples by the frame’s exposure before comparing, so “over range” means over the
range the display is being asked to show, not over the scene’s own linear units.
At exposure = 1 — the default, and where most presets sit — nothing about this
is visible. It matters the moment a preset moves off it: comparing before the stop
instead, a preset at exposure = 0.03 would put its entire figure over every
threshold the engine allows (the ceiling is 8), so bloom_threshold would have
no discriminating range left and
authors ended up pinning it at the top and calling it capped. Whatever stop you
choose, pick bloom_threshold against the picture you see.
The consequence, and it is the thing that bites first: a preset authored to the
old additive-ceiling habit gets nothing from this stage. For years the
guidance on this page was to keep light under the ceiling so it would not clip.
Bloom’s default threshold selects the light that is over range — so a preset
that dutifully holds everything below 1.0 hands the bright-pass an empty frame,
and the stage does exactly nothing. This is measured, not theoretical: a draft
holding brightness under 1.0 with bloom switched on rendered pixel-identical
to the same file at bloom_amount = 0. Something in the frame must deliberately
cross 1.0. The cheapest fuel is glow, because it drives the stroke’s core
rather than its width — raising thickness instead spreads the same light over a
larger quad and can move the peak the wrong way. brightness works too, and on
the fullscreen scenes it is the only lever. (The measurements above are the record
of the retired star_lantern, which shipped as the worked example of this; its
header survives in git history.)
[params]brightness = "0.8 + clamp(bass * 2, 0, 1.2)" # peaks over 1.0 on a hitbloom_amount = "0.4 + clamp(onset * 2, 0, 0.9)" # ...and the hit bloomsbloom_radius = "1.2"Verifying a bloom preset from a still is harder than for any other stage, and
--set bass=1 will lie to you about it. A held-high band is already an
over-flattering stimulus (see docs/capturing.md), but the threshold makes it
much worse here than elsewhere: at bass = 1 the figure sits far over range and
the halo is enormous, while on real material — where a bass mean is around
0.007 against peaks near 0.19 — the frame may never cross the threshold at all.
Every other stage degrades smoothly between those two worlds; this one is a
cliff. Check a bloom preset with --signal dynamic:<bpm> or --audio, and treat
a --set still as a look at the loudest single frame the preset will ever have.
bloom_amount and bloom_radius are independent on purpose: raising the radius
spreads the same energy wider rather than adding more, so a preset can ride the
radius on a build-up without the frame getting brighter as it goes.
Cost. Bloom is the most expensive engine stage — a dozen-odd passes over a shrinking pyramid — and the pyramid is one level deeper on the rich tier, so the halo reaches a little further there. Everything else about it is identical between tiers.
Built from a8ce055 at version 0.115.0. This site tracks main and is not versioned per release.