Bloom
Let light brighter than the screen can show spill into its surroundings, through a blurred copy of only the brightest pixels.
Cards
One live example to tweak, learn and copy.
How it works
A camera lens and the eye both scatter a little of every light into the area around it. You never notice it on a gray wall, but around a lamp, a neon sign or the sun the scattered light is bright enough to see: a soft halo that makes the source look brighter than the white of the screen. Bloom fakes that halo, and it is the main reason a renderer keeps colors above 1 at all.
The recipe has three parts:
- Bright pass. Keep only the pixels whose brightness is above a threshold, usually around 1, and turn the rest
black. Without values above 1 there is nothing to tell a lamp from a white shirt, which is why bloom needs an
HDRRendering keeps light values above 1 in float buffers (HDR), then a tone-mapping curve compresses them into the 0–1 a screen can show.Rendering
HDR & tone mapping
Rendering keeps light values above 1 in float buffers (HDR), then a tone-mapping curve compresses them into the 0–1 a screen can show.
Reinhard = c / (1 + c)scene. - Blur. Spread what is left with a wide blur, almost always at half size or smaller, because the halo is soft and a big radius at full size is expensive. Engines chain several sizes and add them up, so the halo has a bright core and a long faint tail.
- Composite. Add the blur back onto the original frame, then tone-map, since the sum is brighter still.
Each part is its own pass, with a render targetA texture a draw writes into instead of the screen, so a later pass can read the result. Blur, bloom and every multi-pass effect use them. Render target A texture a draw writes into instead of the screen, so a later pass can read the result. Blur, bloom and every multi-pass effect use them. Post-process chain Full-screen passes run in order over the finished frame, each reading the image the previous one wrote. Bloom, tone mapping and color grading live here.
Further reading
- Mipmap (opens in a new tab)Reference
- Anisotropic filtering (opens in a new tab)Reference
- textureLod (opens in a new tab)Reference
- Kernel (image processing) (opens in a new tab)Reference
- Gaussian blur (opens in a new tab)Reference
- Sobel operator (opens in a new tab)Reference
- step (opens in a new tab)Reference
- smoothstep (opens in a new tab)Reference
- Shaping functions (opens in a new tab)Book
- HDR (opens in a new tab)Article
- Environment and post-processing (opens in a new tab)Docs
- Khronos PBR Neutral Tone Mapper (opens in a new tab)Reference
- Framebuffers (opens in a new tab)Article
- Bloom (opens in a new tab)Article
- Custom post-processing (opens in a new tab)Docs
- glFramebufferTexture2D (opens in a new tab)Reference
- EXT_color_buffer_float extension (opens in a new tab)Docs
- Bloom (shader effect) (opens in a new tab)Reference
- Next Generation Post Processing in Call of Duty: Advanced Warfare (opens in a new tab)Paper
- Relative luminance (opens in a new tab)Reference