Phaser AE

Post-process chain

Free packv3.0.0-52D and 3DPost

The full-screen effect runtime. Once the world is drawn, `post` runs each effect you added as one pass over the frame, in order, and the HUD is drawn crisp above the result. It owns the chain rather than the looks, so you compose the effect packs you want, or write your own in a few lines of WGSL.

This is a Free pack. Every phaser.io account can use it in their games.

Released October 14, 2026 · updated October 20, 2026

Post-process chain: a screenshot of its demo
A note about these graphics

Expansion packs don't come with graphics. This screenshot is one way of drawing what the pack does, made for its demo: none of the sprites, tiles or backgrounds in it are in the pack.

That's by design. A pack is a game's logic, mechanics and effects, and it works with whatever art you give it. Some packs draw effects, backdrops or 3D scenes of their own, but none carries a game's sprites.

So the look is yours. Make the art on phaser.io, bring your own, or let your agent draw it in code: the same pack can look like anything.

What it does

After the world and its lighting are drawn, the chain copies the frame into a pair of textures and runs each effect as one fragment pass that reads the previous result; the last pass writes the screen. Effects run in the order you add them, and the order is part of the look: pixelate then bloom glows the blocks, bloom then pixelate pixelates the glow, and a CRT belongs last. The HUD on world-screen is drawn after the chain, so score text never blooms, curves or pixelates.

Each add returns a handle, and its params change on any frame. A param is a number, a colour or a vector, and its default decides which: a colour takes any CSS colour, a vector takes an array or one number for every component. The wrong kind of value throws, so a typo never silently turns the screen black, and adding an effect no composed pack provides throws with the list of what is available and the pack to add. Handles belong to the scene, so its teardown removes them.

Writing a look of your own is one call. registerPostEffect takes a name, a one-line description, a table of default params and a WGSL snippet that reads the previous result through tex(p) and leaves the new pixel in color. checkPostEffect checks a definition with no GPU: its name, its params and the sixteen slots they share, that the code sets color and avoids unbounded loops and stray texture calls, and that it translates for WebGL2, which catches a misspelt name or a param read by name instead of by slot.

Features

  • An ordered chain — effects run in add order, each reading the last; chain and available list them.
  • Live handles — set changes a param on any frame, remove takes the effect out, and clear empties the chain.
  • Typed params — numbers, CSS colours and vectors of two to four numbers, checked on every add and set.
  • Effects of your own — registerPostEffect turns a WGSL snippet into an effect you add by name, from a game or from a pack.
  • Checked before drawing — checkPostEffect returns the problem in one sentence; an effect that still fails to compile on a device is reported once and skipped, so the rest of the chain draws.
  • The HUD stays crisp — world-screen's HUD and overlay draw above the chain.
  • 2D and 3D, WebGPU and WebGL2 — it runs over whatever the world drew, and WebGL2 translates each snippet.
  • Reachable from other packs — through the kernel registry, which is how title-screen adds its bloom and vignette.

Good for

  • Neon, vector and synthwave games — bloom on from the first frame, from post-bloom.
  • Retro and arcade looks — a curved CRT tube, scanlines, pixelate and posterize, from post-looks.
  • Moody and cinematic games — a colour grade and film grain for noir, horror or a golden hour.
  • Game feel — a hit that pushes a colour split up and back, a low-health vignette, a pause that drains the colour.
  • A house style — a sepia, palette or tint effect of your own, registered once and added by name.

Make it yours

The chain is built entirely from add calls, so its make-up and order are the game's to choose, and any param can be tweened. There are no pack options. A game's own effects get the same treatment as the packs' effects: up to sixteen slots, live params, and the same checks.

Two very different chains: an arcade shooter adds pixelate, then bloom, then crt last, so the glowing blocks sit on a curved tube; a noir adventure adds a black-and-white grade, then grain, then a strong vignette, and adds a sepia effect of its own for its flashbacks.

A quick look

Two effects from packs, a param changed live, and an effect of the game's own:

import { registerPostEffect } from '@phaser-ae/post';

const bloom = game.post.add('bloom', { strength: 1.2 });   // params override the pack's defaults
bloom.set('threshold', 0.4);                                // live, any frame
game.post.add('vignette', { color: '#5a0008' });            // a colour param takes a CSS string

registerPostEffect(game.kernel, { name: 'sepia', description: 'old photograph', params: { amount: 0.8 },
    code: `let g = dot(color.rgb, vec3(0.299, 0.587, 0.114)); color = vec4(mix(color.rgb, vec3(g * 1.07, g * 0.74, g * 0.43), p0), color.a);` });
game.post.add('sepia');

Works with

Good to know

  • Every effect is a full-screen pass, so eight effects cost eight passes; keep the chain short on a low-end GPU.
  • An effect sees only the previous result, never the original frame or the scene's depth, so a multi-resolution bloom or a depth-aware effect needs a pack with passes of its own.
  • Sixteen slots an effect: a number takes one, a colour three and a vector its width. Colours are RGB only.
  • The check is the WebGL2 translator's, not the browser's WGSL compiler, so try a new effect on WebGPU once.
  • Against the 3D packs' own full-screen passes, the chain runs in the order the packs are composed: compose post after them to run it over their result.

More Post packs

Show all →