Skip to content

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.

ParamDefaultMeaning
bloom_amount0Strength 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_threshold1.0Where “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_radius1.0How 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 hit
bloom_amount = "0.4 + clamp(onset * 2, 0, 0.9)" # ...and the hit blooms
bloom_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.