feat(blur): universal — the blur covers every layer, webcam included
The creator found the use case that reframes the feature: a moment of privacy while the webcam is on. A blur that can only cover the desktop cannot do that. - SceneCompositor applies the blur group AFTER every element is composited (still before the flash / social bar / ticker / zoom overlays), so it covers webcam, chat, alerts — anything. Its position in the layer list no longer affects the output, so it is added at the top and the reorder clamp is gone. - Supersedes the earlier "blur sits below the brand" rule: a universal blur does obscure the logo when it covers it. Called out in frame-pipeline.md so it is not re-litigated. - Preview mirrors it exactly: the blur host moved OUT of CanvasGrid to a sibling above it, so the VisualBrush samples every layer (and cannot sample itself). It used to sample only the backdrop, which is why a circle over the webcam would have shown sharp pixels in the editor and blurred ones in the stream.
This commit is contained in:
@@ -174,25 +174,13 @@ public sealed class SceneCompositor
|
||||
}
|
||||
|
||||
// Composite the above-split layers (dynamic + any static above them) per frame.
|
||||
var blurApplied = false;
|
||||
for (var i = Math.Max(0, split); i < scene.Elements.Count; i++)
|
||||
{
|
||||
var element = scene.Elements[i];
|
||||
if (!element.IsVisible) continue;
|
||||
|
||||
// Privacy blurs are handled as ONE group the first time one is reached: overlapping
|
||||
// boxes must resolve to the strongest single blur, never to a blurred blur. The group
|
||||
// runs at the lowest blur's z-position, which is where the creator put it — directly
|
||||
// above the background and below the brand logo.
|
||||
if (element is Source { Type: SourceType.Blur })
|
||||
{
|
||||
if (!blurApplied)
|
||||
{
|
||||
blurApplied = true;
|
||||
ApplyBlurLayers(scene, buffer, cropW, cropH, options, timings);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// Blurs are applied once, after every layer (see below) — they are universal.
|
||||
if (element is Source { Type: SourceType.Blur }) continue;
|
||||
|
||||
switch (element)
|
||||
{
|
||||
@@ -207,6 +195,12 @@ public sealed class SceneCompositor
|
||||
BlitBakedElement(buffer, cropW, cropH, options, element, frame, timings, $"#{i} {element.Name}");
|
||||
}
|
||||
|
||||
// ⛔ Privacy blur is UNIVERSAL (creator ruling 2026-11-01): it is applied after every
|
||||
// layer has been composited, so it can cover the webcam, chat, alerts, anything — the
|
||||
// creator's "moment of privacy" case. It is the only layer that ignores its z-position;
|
||||
// overlapping blurs still resolve to the strongest single one.
|
||||
ApplyBlurLayers(scene, buffer, cropW, cropH, options, timings);
|
||||
|
||||
if (flashFrame != null)
|
||||
{
|
||||
var tFlash = System.Diagnostics.Stopwatch.GetTimestamp();
|
||||
|
||||
Reference in New Issue
Block a user