Skip to content

Postprocessing

The Postprocessing component owns the scene-wide effect chain (bloom, vignette, depth-of-field, tone mapping, SSAO, and more). Each effect has its own enabled flag plus per-effect parameters.

It is a singleton there is exactly one Postprocessing entity per scene, owned by the editor.

IMPORTANT

The render system only applies effects when the master toggle postEnabled is true. Enabling an individual effect alone has no visual impact unless the master toggle is also on.

Managed by: PostprocessingSyncSystem

Get the component from the world

Use world.getPostprocessingComponent() — a convenience method that handles the entity lookup for you:

ts
import { Behaviour } from "@relu-interactives/spatial-ecs";

export default class ReadPostprocessing extends Behaviour {
  init() {
    const post = this.world.getPostprocessingComponent();
    if (!post) return;

    console.log("post enabled?", post.values.postEnabled);
  }
}

post.values is the live state object — mutate fields on it directly. The PostprocessingSyncSystem reads it every frame and rebuilds the composer pipeline as effects are toggled.

Change values at runtime

Enable the master toggle and a few effects

ts
post.values.postEnabled = true;

post.values.bloom.enabled = true;
post.values.bloom.intensity = 1.5;
post.values.bloom.threshold = 0.25;
post.values.bloom.radius = 0.8;

post.values.vignette.enabled = true;
post.values.vignette.darkness = 1.4;

Toggle a single effect from a script

ts
function setBloom(post, on) {
  post.values.postEnabled = on || somethingElseEnabled(post);
  post.values.bloom.enabled = on;
}

Cinematic depth of field

ts
post.values.dof.enabled = true;
post.values.dof.focusDistance = 0.02; // distance from the camera (normalised)
post.values.dof.focalLength = 0.05;
post.values.dof.bokehScale = 4;

Color grading

ts
post.values.toneMapping.enabled = true;
post.values.toneMapping.exposure = 1.1;

post.values.hueSaturation.enabled = true;
post.values.hueSaturation.hue = 0.05;       // radians
post.values.hueSaturation.saturation = 0.2; // 0 = unchanged

Authorable values

Top-level master toggle:

PathTypeDefault
postEnabledbooleanfalse

Each effect lives under its own key with enabled plus parameters:

EffectPath prefixKey parameters
Depth of fielddoffocusDistance, focalLength, bokehScale
Bloombloomintensity, threshold, radius
Vignettevignetteoffset, darkness
Chromatic aberrationchromAberrationoffsetX, offsetY
Film noisenoiseopacity
Pixelationpixelationgranularity
Tone mappingtoneMappingexposure
Hue / saturationhueSaturationhue, saturation
Sepiasepiaintensity
SMAAsmaa(toggle only)
SSAOssaointensity, radius
Dot screendotScreenscale, angle, opacity
Glitchglitchdelay, duration, strength, mode, active

For the full type, including every legacy/optional parameter, see PostprocessingState.

API reference