public readonly record struct UiBackdropWhat a composited group's backdrop-filter does to the picture behind it.
Remarks
⚠ The same three shapes UiLayer already executes, pointed at a different picture — and that is the whole of why this feature needed a compositor change rather than a shader. A blur, a colour matrix and a quad are exactly what a filter costs. The difference is what is convolved: a filter reads the group's own surface, and this reads the destination the group is about to composite into. Nothing behind the group has been drawn at the moment its surface is rendered, so the backdrop is not read back — it is re-rendered, from the same draw list, up to the group's own first draw. See UiRenderer.Capture and SoftwareUiRasterizer.Frame.Run.
⚠ Every UiLayer is a backdrop root, which is what makes this a single prefix and not a walk up the ancestors. Filter Effects 2 § 2 says an element forms a backdrop root if it has a filter, an opacity below one, a mask or a clip path — and a group exists in this engine for precisely those reasons and no other. So a nested group's backdrop is its parent's own surface so far, which starts from transparent black, and only a top-level group's backdrop includes whatever the host painted before the interface. There is no accumulation to get wrong.
⚠ Alpha rides the backdrop quad's vertex alpha rather than the matrix, for UiDropShadow's reason. UiColorMatrix has three rows and cannot scale alpha, and backdrop-opacity-50 is one of the ten roots this exists for. Both executors multiply all four channels of an already-premultiplied sample by the quad's alpha, so that is where it can go — and the group's own opacity multiplies into the same number, which is what CSS means by the backdrop image being painted inside the element's own stacking context.
⚠ The order among the three is free, and unlike Shadow it is free for a reason rather than by convention. A Gaussian is a weighted sum whose weights sum to one, a colour matrix is affine in premultiplied colour, and an alpha scale is a scalar: all three commute exactly. There is no second Gaussian here to fail to commute with, which is what a drop shadow is and why backdrop-filter refuses drop-shadow().
⚠ The picture is clipped to the group's border box and not to Bounds, and not to its corner radius either. The bounds are the group's ink, which a child overflowing its parent makes larger than the element — filtering the backdrop over that would put a blurred rectangle outside the panel that asked for it. So BackdropBounds is carried separately. What is not closed is the radius: CSS clips the filtered backdrop to the border box including its curve, and rounded-2xl backdrop-blur-md therefore shows square corners here. See docs/guide/ui/compositing.md, which states it as a divergence and prices closing it.
Fields and properties (4)
public float BlurThe Gaussian standard deviation, in document pixels. As Blur.
public float AlphaWhat opacity() fades the filtered backdrop by, one being unchanged. ⚠ The only one of the nine functions that Matrix could not carry — see the remark.
public UiColorMatrix? MatrixThe colour transform the eight remaining functions compose into, or null.
public bool IsIdentityWhether this would change the picture, and so whether it is worth a surface.
Methods (1)
public UiBackdrop(float Blur, float Alpha, UiColorMatrix? Matrix = null)What a composited group's backdrop-filter does to the picture behind it.
Used by (9)
- BackdropFilterTestsVixen.Ui.Controls.Tests
- DrawCommandVixen.Ui
- DrawListBuilderVixen.Ui
- FrameVixen.Ui.Testing
- OpeningVixen.Ui
- UiCompositingTestsVixen.Graphics.Golden.Tests
- UiGeometryBuilderVixen.Ui
- UiLayerVixen.Ui
- UiRendererVixen.Ui.Renderer