Command Palette

Search for a command to run...

Hectal
Course outline
Topic 15.3Advanced ~22 min · step 3 of 6

Bloom and Glow

In one line

Bloom makes very bright pixels glow into their surroundings, like a lamp seen through mist. Three numbers control it (threshold, strength, radius), a brightness trick keeps it on the lights only, and it costs a chain of smaller pictures.

0/6 · 0%

Think of it like this

A car's headlight on a foggy night. The bulb is much brighter than the fog, so the fog around it lights up and the light seems to spill outwards. A dim number plate in the same fog does not spill. Bloom copies that: it finds what is far brighter than the rest and spreads a soft halo around it.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

bloom
A glow around very bright areas, made by blurring them and adding them back.
threshold
The brightness below which a pixel is ignored by bloom.
strength
How much of the blurred glow is added back.
radius
How much the wide blurs count compared with the tight ones: a bigger radius spreads the glow further.
HDR
High dynamic range: values above 1 are allowed, so a lamp can be brighter than white.
layers
A bit mask on every three.js object. A camera draws an object only if they share a layer; Layers.test checks it.

Step by step

01Set up a lamp and a panel

The panel is orange (never brighter than 1). The lamp's colour is (3, 3, 2.4), about three times as bright as white, set with Color.setRGB. Both use MeshBasicMaterial, so lighting changes nothing.

02Sweep the threshold

At threshold 0 everything glows: the pixel beside the panel reads 115 although the panel is only orange. At 0.9 only the lamp passes: beside the lamp 115, beside the panel 15. At 5 nothing is bright enough and both read 0.

The remaining 15 beside the panel is the lamp's far haze. Take the lamp away and the panel reads 0 at threshold 0.9.

03Pick the threshold with the brightness in mind

The threshold is compared with the pixel's luminance, the weighted brightness 0.2126 R + 0.7152 G + 0.0722 B. The lamp colour (3, 3, 2.4) has luminance about 2.96. A threshold of 2.9 still glows (105 beside the lamp). A threshold of 3.1 does not (0). The pass blends over a very narrow range (0.01) so the cutoff is sharp.

04Select by layer instead

The second example adds a white wall twice as bright as white. With a threshold of 1 the wall glows (255 beside it). With the layers trick only the lamp is on layer 1, everything else is drawn black for the bloom picture, and the wall stays at 15.

Try it yourself

  1. 1

    Find the lamp's brightness

    In the first example change [0, 0.9, 5] to [2.9, 3.1]. It prints threshold 2.9 | beside the lamp: 105 and threshold 3.1 | beside the lamp: 0: the lamp is exactly between them.

  2. 2

    Turn the strength up

    Change 0.5, 0.2, 0 to 1.5, 0.2, 0. At threshold 0.9 the pixel beside the lamp reads 185 and beside the panel 35: the glow is brighter and reaches further, and the far haze lifts the panel too.

Code & diagrams

Threshold: what glows New tab

0 = black, 255 = white, rounded to steps of 5. Lamp brightness 3, strength 0.5, radius 0.2.

idle

Console

Run the scene to see its console.

Expected console output

threshold 0   | beside the lamp: 120 | beside the orange panel: 115 (0 = black, 255 = white)
threshold 0.9 | beside the lamp: 115 | beside the orange panel:  15 (0 = black, 255 = white)
threshold 5   | beside the lamp:   0 | beside the orange panel:   0 (0 = black, 255 = white)
Selective bloom with layers New tab

Two composers: the first blooms only layer 1 (the lamp), the second draws the real scene and adds the glow. The wall is twice as bright as white and still does not glow.

idle

Console

Run the scene to see its console.

Expected console output

threshold 1:      beside the wall 255 | beside the lamp 135
selective layers: beside the wall 15 | beside the lamp 115

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

Threshold 0

In the first example read the first line, threshold 0.

terminal
$ Run
── what you'll see ──
threshold 0 | beside the lamp: 120 | beside the orange panel: 115 (0 = black, 255 = white)

Break #2

A bright thing that should not glow

In the second example read the first line (threshold 1).

terminal
$ Run
── what you'll see ──
threshold 1: beside the wall 255 | beside the lamp 135

Myth vs fact

Myth

Bloom is a blur you can add to any image.

Fact

It needs HDR values. If every pixel is 1 or less, a threshold at 1 selects nothing, and a lower one makes dim things glow.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    UnrealBloomPass is a luminosity high-pass, five separable Gaussian blurs (kernel sizes 6, 10, 14, 18 and 22) at half, quarter... of the canvas, and a composite that weights the five by [1, 0.8, 0.6, 0.4, 0.2] with radius shaping the mix. Its source (three/examples/jsm/postprocessing/UnrealBloomPass.js) is short and answers most questions.

  • ▸

    The postprocessing library's SelectiveBloomEffect does the layers idea for you, and its BloomEffect has luminanceThreshold, intensity and mipmapBlur. On WebGPU the node bloom(node, strength, radius, threshold) is the same maths.

Remember this

  1. 1

    The problem this solves: a screen cannot show a lamp brighter than white. A pure white lamp looks like a white sticker. The eye reads the glow around a bright thing as its brightness, so adding the glow makes a flat white disc look like a real light.

  2. 2

    **How UnrealBloomPass works.** It (1) keeps only the pixels brighter than the threshold, (2) blurs them at 5 sizes, each half the one before, (3) adds the five blurs back onto the picture, scaled by strength. radius decides how much the big, wide blurs count against the small, tight ones. Big blurs make the soft far haze.

  3. 3

    Why the lamp must be brighter than 1. Colours inside a half-float chain are not capped at 1. A lamp material with emissiveIntensity 5 writes values up to 5. A flat, unlit orange surface can reach 1 at most. A threshold slightly above 1 selects the lamp and nothing else, as long as no lit surface is brighter than 1 (see the layers trick below). The first example uses a lamp of brightness 3: a threshold of 0.9 makes it glow and leaves the orange panel alone.

  4. 4

    Selecting what glows. The threshold is the cheap selector: make the lights brighter than anything else. It fails when something that should not glow is also bright, such as a sunlit white wall or a chrome highlight. The second example uses the layers trick: draw once with everything not on layer 1 painted black, bloom that picture, then add it to a normal draw. The wall's halo drops from 255 to 15, and the lamp's glow stays (135 before, 115 after: a little of the wall's light was adding to it).

  5. 5

    What it costs. The pass owns 11 half-float targets (1 for the bright pixels, 5 blur sizes, each blurred across and then down), starting at half the canvas size: 14.5 MB at 1920 × 1080, beside the composer's own two targets (31.6 MB). On a 390 × 844 phone at ratio 3 that is 20.7 MB and 45.2 MB. At ratio 1 it is 2.3 MB and 5.0 MB.

Explain it without notes

01

Why can bloom pick out a lamp from the other surfaces, and when does that stop working?

02

How do you cut bloom's cost on a phone?

Practice

01

A showroom's brightest lit paint reaches linear brightness 0.8 and the headlight lens is 5. What threshold would you use, and why not 0?

02

Write the lines that put only the headlight lens on layer 1 and test whether an object is on it.

Done when you can

  • Explain threshold, strength and radius in one sentence each

  • Pick a threshold from the brightness of lights and surfaces

  • Keep bloom to the lights with a threshold or with layers

  • Say what bloom's pictures cost and how to cut it