Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commit44fd9e59bd

README.md

PostProcess Component

Applies a stack of post-process effects to the scene, declaratively, from a single entity. Each effect references a .shader asset (@domain: post-process) and carries its own configurable property values — tuned like material properties, with no shader edit required.

This is the load-time reproducer for post-processing: where an agent's live postprocess.add(...) + postprocess.setProperty(...) calls produce effects that vanish on reload, a PostProcess component re-registers the exact same stack — with the exact same tuning — every time the scene loads. The persist freeze converts live execute-origin effects into .shader assets + one entity carrying this component, so what you see is what you get across save/reload.

Properties

FieldTypeDescription
effectsarrayThe effect stack. Each entry: { shader, priority?, enabled?, layer?, values?, textures? }.
shape"global" | "box" | "sphere"Where the stack applies. Default "global" (unbounded).
extentsvec3Box region half-extents, world units. Default {5, 5, 5}.
radiusnumberSphere region radius, world units. Default 5.
falloffnumberSoft-edge distance outside the volume the stack fades over. Default 0.
prioritynumberOrder of this region against other PostProcess regions, added to each effect's own priority. Default 0.
displaystruct { curve, exposure }The display transform this region sets while it is live — curve (0 linear, 1 Reinhard, 2 ACES, 3 Khronos PBR Neutral, default 3) and exposure (multiplier on the scene's light before the curve, default 1). Takes effect only when setsDisplay is true and shape is "global".
setsDisplaybooleanWhether this region writes display to the chain's __display__ transform while it is live. Default false.

Each effect entry:

KeyTypeDescription
shaderasset referenceThe .shader asset (a @domain: post-process shader) this effect runs. Builtin shaders (@builtin::shaders.post.vignette, …) or scene-authored custom shaders both work.
prioritynumberChain order within this region — lower runs earlier. Default 100.
enabledbooleanPer-effect toggle. Default true.
layer"all" | "scene"Which composited image this effect grades: "scene" is the rendered picture before the UI reaches it, in the scene's own light; "all" is the picture fitted to the screen with every widget on it. Left empty, the entry follows its shader's space — a light shader grades "scene", a display shader grades "all".
valuestableNamed property overrides { [prop] = value }, applied via postprocess.setProperty after the effect is added — the configurable tuning.
texturestableTexture bindings { [prop] = path }, applied via postprocess.setTexture after the effect is added.

The component-level enabled flag (engine-managed, not declared here) toggles the whole stack: disabling the component removes every effect (and restores the chain's own display transform if this region set one); enabling it re-registers them (onEnable / onDisable).

Usage

entity.find("fx").component.add("PostProcess", {
    effects = {
        { shader = "@builtin::shaders.post.vignette", priority = 0,
          values = { intensity = 0.6 } },
        { shader = "@builtin::shaders.post.grayscale", priority = 10,
          values = { intensity = 1.0 } },
    },
})

Setting the display transform from a global region:

entity.find("look").component.add("PostProcess", {
    setsDisplay = true,
    display = { curve = 2, exposure = 1.5 }, -- ACES
})

Two global regions with setsDisplay = true both write __display__ — whichever registers last wins the frame. The regions setting it share one ordered record of who is live, so they come off in any order: removing the newer of two leaves the older one's display standing, removing the older leaves the newer one's, and removing the last leaves whatever stood before any of them wrote.

The exposure package drives __display__.exposure on its own, from a GPU readback each tick it meters. A region arriving or leaving sets the exposure and the package's next readback sets it again, so with auto-exposure running the exposure a region asks for holds for a frame while its curve holds for as long as the region does.

Methods

  • pp:getEffectNames() — the live effect names currently registered, in stack order.
  • pp:setProperty(index, prop, value) — tune a property of one effect at runtime (forwards to postprocess.setProperty), like editing a material property.