Light Wrap Mask

This operator changes nothing on its own. It computes the light wrap's mask once and publishes it, so that Background Match operators in other scenes can reuse it instead of each working it out again.

What it is for

The mask is the expensive half of a light wrap. It needs the foreground's alpha blurred at a radius proportional to frame height, and — unlike the background side, which is sampled on a timer — it cannot be cached between frames, because the subject moves.

That is fine for one composite. It stops being fine when one keyed presenter feeds many branded scenes: every one of those scenes blurs the same alpha, independently, every frame. Twenty branded outputs means twenty identical blurs.

Put this operator in the keyer scene, after the keyer, and the blur happens once.

Measured at 4K on a two-scene setup, a Background Match that found a published mask ran in 3.4 ms against 5.5 ms computing its own — one separable blur, about 2.1 ms, removed per consumer.

It is break-even with one consumer

Worth being clear about: with a single consumer this saves nothing. The blur moves from the consumer to this operator, it does not disappear. The whole gain is in the fan-out:

Branding scenes With this operator Without
1 2.0 + 3.4 = 5.4 ms 5.5 ms
20 2.0 + 20 × 3.4 = 70.6 ms 20 × 5.5 = 110.4 ms

So reach for it when several scenes share one keyed source. For a single composite it is simply unnecessary.

Using it

  • Size — how far the mask reaches in, as a percentage of frame height rather than a pixel count, so it is the same effect at every resolution.
  • Show — Picture passes the input through untouched; Mask displays the mask being published. Use Mask while choosing the size, then put it back.

Place it after the keyer and after spill suppression, for the same reason Background Match goes last: the mask is derived from coverage, so it wants a matte that is already final.

Size lives here, not on the consumers

A shared mask is a blur at one particular radius, so it can only serve consumers that want that radius. Background Match therefore checks the radius before accepting a published mask, and falls back to computing its own whenever it does not agree.

That is not only a technical constraint. Twenty brandings of the same presenter should agree on their edge geometry; having the size settable per branding is an invitation to twenty subtly different looks.

How consumers find it

Background Match follows its own layer's input: if that input is a scene, it looks through that scene's layers for this operator, and on into any scene feeding that, to a depth of four.

It is deliberately not a search of the whole project. The mask describes one particular foreground, and a project-wide "first publisher wins" rule would silently hand the wrong presenter's mask to a scene the moment a project contained two.

When it does not take effect

Background Match refuses a published mask, and quietly computes its own, when:

  • this operator is not active, or is not in a scene feeding that layer
  • the radius does not agree, because the two Size settings differ
  • the mask's resolution does not match the consumer's

Every one of those is a performance difference and not a visual one — the locally computed mask is produced by the same kernel as the published one, so the picture is the same either way. That is what makes the sharing safe to adopt one scene at a time.

Because the difference is invisible in the picture and large in cost, Background Match reports which path it took in its own panel, and writes a line to the log whenever it changes. If sharing quietly stops — this operator removed, or its Size changed — that log line is how it gets noticed.

A note on precision

The mask is published through an 8-bit buffer, so it is quantised to 256 levels where a locally computed one used to stay in floating point inside a single kernel. Measured against the previous behaviour, the largest difference this produces anywhere in a frame is one code value, on about 3 % of pixels. The output is 8-bit as well, so that is at the noise floor of the pipeline rather than something you can see.

Light Wrap Mask - Settings

Properties marked (Components) or (AudioMixer) broadcast a live PropertyChanged event to clients subscribed to that WebSocket channel.

Property Description
Size (Components) How far the mask reaches in from the foreground's edge, as a percentage of frame height rather than a pixel count, so it is the same effect at every resolution. This is the setting consumers inherit. [default = 50]
Show (Components) Whether to pass the picture through or show the mask being published. Mask is for setting the size up; leave it on Picture in service. [default = Picture]
Status Status line: the radius being published, or why nothing is.
Reset to Defaults Return every setting to its default.

Inherits from: AbstractOperator, AbstractAudioMetering, NamedModel.

See also: Light Wrap Mask in Script Engine Objects.