Skip to content

Blend Modes

Every source node in the chain has a blend mode that controls how its pixels combine with the current accumulator. The math below uses src for the incoming source value and dst for the value already in the accumulator.

Mode reference

ModeFormulaEffectTypical use
overresult = srcSource replaces the accumulator (modulated by opacity).Default — simple layering on top of whatever is below.
addresult = min(1, src + dst)Strong brighten, clips at 1.0.Glows, lasers, sparkles, additive particles. Pairs well with bloom.
multiplyresult = src * dstDarkens and tints.Colour grading, shadows, ink effects.
screenresult = 1 - (1 - src) * (1 - dst)Brightens without the hard clip of add.Light leaks, atmospheric fog, soft luminance boosts.
overlayresult = dst < 0.5 ? 2*dst*src : 1 - 2*(1-dst)*(1-src)Multiplies darks and screens lights — contrast boost.Adding texture to a flat base while keeping its structure legible.
softlightresult = (1 - 2*src) * dst² + 2*src*dstGentler contrast lift than overlay.Subtle highlighting where overlay is too aggressive.
dodgeresult = min(dst / max(1 - src, 0.001), 1)The most aggressive brighten mode.Hot cores, seed layers for bloom, extreme brightening at low opacity.
differenceresult = abs(dst - src)Absolute difference per channel — subtractive, colour-inverting.High-contrast psychedelic effects. Dramatic on motion.
exclusionresult = dst + src - 2 * dst * srcSofter colour-inverting effect than difference.Muted psychedelic looks where difference is too harsh.

Per-mode detail

over — Over

result = src

Effect: Source replaces the accumulator (modulated by opacity).

Use: Default — simple layering on top of whatever is below.

add — Add

result = min(1, src + dst)

Effect: Strong brighten, clips at 1.0.

Use: Glows, lasers, sparkles, additive particles. Pairs well with bloom.

multiply — Multiply

result = src * dst

Effect: Darkens and tints.

Use: Colour grading, shadows, ink effects.

screen — Screen

result = 1 - (1 - src) * (1 - dst)

Effect: Brightens without the hard clip of add.

Use: Light leaks, atmospheric fog, soft luminance boosts.

overlay — Overlay

result = dst < 0.5 ? 2*dst*src : 1 - 2*(1-dst)*(1-src)

Effect: Multiplies darks and screens lights — contrast boost.

Use: Adding texture to a flat base while keeping its structure legible.

softlight — Soft Light

result = (1 - 2*src) * dst² + 2*src*dst

Effect: Gentler contrast lift than overlay.

Use: Subtle highlighting where overlay is too aggressive.

dodge — Dodge

result = min(dst / max(1 - src, 0.001), 1)

Effect: The most aggressive brighten mode.

Use: Hot cores, seed layers for bloom, extreme brightening at low opacity.

difference — Difference

result = abs(dst - src)

Effect: Absolute difference per channel — subtractive, colour-inverting.

Use: High-contrast psychedelic effects. Dramatic on motion.

exclusion — Exclusion

result = dst + src - 2 * dst * src

Effect: Softer colour-inverting effect than difference.

Use: Muted psychedelic looks where difference is too harsh.

Implementation

These formulas live in packages/engine/src/chain/blend.ts as pure TypeScript functions used by the engine’s unit tests to verify correctness. The actual blending in the render pipeline happens in GLSL inside graphics/src/BlendCompositor.ts. The two are kept in lockstep: any change to one must match the other, and the test suite verifies agreement at a sample of input values.

  • The Chain Model — how blend modes fit into the accumulator pipeline.
  • How the Chain Works — the hands-on version of chain compositing, including blend mode selection.