Vixen
dd8b0a81
csharp
public readonly record struct UiDropShadow

The shadow a composited group's filter: drop-shadow() casts from its own alpha.

Read the guide page for this →

Remarks

⚠ A shadow of the alpha silhouette and not of the box, which is the whole difference between this and box-shadow and the reason the two share no code. DrawListBuilder.EmitShadow emits a rounded rectangle the shape of the border box and lets ui-box.frag resolve its falloff analytically, because a box's silhouette is known in closed form. A drop-shadow's is not: it is whatever the subtree rasterised to — text, an icon's path, a partly transparent image, a child with its own mask — so it can only be had by blurring the coverage that was actually drawn. Filter Effects 1 § 8.4 defines it that way, and it is why this is a member of UiLayer rather than a second DrawCommandKind.Shadow.

⚠ The standard deviation, and it is not the half-extent Thickness carries on a Shadow. Two conventions for one word live a few types apart: box-shadow's third length is the total fade distance and the box shader wants half of it, while drop-shadow(x y r) is a Gaussian of σ = r with no halving. This is the second one — the same convention Blur uses, and deliberately so, because the two are executed by the same kernel.

⚠ Straight colour, because the two halves are spent in different places and neither wants the product. The RGB becomes Tint, a colour matrix that replaces whatever the surface holds; the alpha becomes the shadow quad's own vertex alpha, which both executors apply to all four channels of an already-premultiplied sample. Storing the premultiplied colour would make the first half wrong — a shadow at 25% opacity would be painted in a colour a quarter as bright and then faded to a quarter — and the mistake is a shadow that is sixteen times too faint rather than one that is missing, which is the harder of the two to notice.

⚠ It does not commute with the group's own blur and the order is fixed rather than carried. A Gaussian of the shadow of a picture is not the shadow of the Gaussian of it — the alpha channel is blurred twice one way round and once the other — so unlike Blur and Filter there is no arithmetic here that lets an executor choose. Both executors run this after the group's own blur, over the finished surface, which is the order UtilityComposition.Filter assembles and the order CSS gives for blur(σ) drop-shadow(…). A stylesheet that writes the two the other way round gets this one; see DrawListBuilder.One, which says so.

⚠ The colour matrix does not commute with the group's Filter either, and here it does not have to. A grayscale before a drop-shadow greys the element and leaves the shadow the colour it was written in; after it, CSS would grey the shadow too. This runs the shadow's own tint over the silhouette and nothing else, which is the first reading — and it is the only one the fixed order can produce, because Tint discards the sampled colour entirely. Anything the group's matrix did to the RGB is multiplied by zero.

Fields and properties (5)

  • public Vector2 Offset

    How far the shadow is displaced, in document pixels. Positive y is down.

  • public float Blur

    The Gaussian standard deviation, in document pixels. As Blur.

  • public Color4 Colour

    What the silhouette is painted in, straight rather than premultiplied — the two halves are consumed by different machinery, and Tint says which goes where.

  • public bool IsInvisible

    Whether this shadow would paint nothing, whatever the silhouette is.

  • public UiColorMatrix Tint

    The matrix that turns a group's surface into its silhouette, painted in this colour.

Methods (1)

  • public UiDropShadow(Vector2 Offset, float Blur, Color4 Colour)

    The shadow a composited group's filter: drop-shadow() casts from its own alpha.

Used by (11)

  • DrawCommandVixen.Ui
  • DrawListBuilderVixen.Ui
  • ElementFilterVixen.Ui
  • FilterDropShadowTestsVixen.Ui.Controls.Tests
  • FrameVixen.Ui.Testing
  • OpeningVixen.Ui
  • UiCompositingTestsVixen.Graphics.Golden.Tests
  • UiGeometryBuilderVixen.Ui
  • UiLayerVixen.Ui
  • UiRendererVixen.Ui.Renderer
  • UtilityFamilySupportTestsVixen.Editor.Ui.Tests