public readonly record struct UiColorMatrixThe per-pixel colour transform a composited group's filter applies to its surface.
Remarks
⚠ Three rows and not five, because none of the seven functions this represents touches alpha and none of them reads it. CSS's feColorMatrix is 4×5 — twenty coefficients, an alpha row and an alpha column — and every one of brightness, contrast, grayscale, invert, saturate, sepia and hue-rotate leaves the alpha row at 0 0 0 1 0 and the alpha column at zero. Storing the eight coefficients that are always the same buys nothing and costs thirty-two bytes in a push constant range that has to fit beside the projection.
⚠ Applied to premultiplied colour, with the offset scaled by alpha, and that is what makes the whole feature cost nothing. A colour matrix is defined on un-premultiplied colour: c' = M·(c/a) + o, so c'·a = M·c + o·a. The premultiplied form needs no division and no reconstruction — see Apply — which matters twice over. It means transparent black stays transparent black, so a viewport-sized surface whose group inks a corner of it does not acquire a rectangle of invert(1) white everywhere the group is not; and it means the transform is linear in the sampled value, so it commutes exactly with a bilinear sampler and with the Gaussian in ui-blur.frag. See Filter, which leans on that commutation to run the two filters in whichever order is cheap.
⚠ The arithmetic is in the engine's linear working space, and browsers do it in sRGB. Filter Effects 1 § 8.5 says the shorthand functions run with color-interpolation-filters: sRGB, so a browser's grayscale(1) averages gamma-encoded values. Everything in Vixen is linear from the parser down — StyleValueParser converts on the way in — so matching a browser exactly would mean an encode and a decode per pixel in both executors, to reproduce a rule the spec itself calls a legacy default. What that costs is that a grayscale-50 here is slightly darker than the same class in a browser; what it buys is that the transform stays linear, which is the property the paragraph above spends. Written down rather than discovered.
⚠ default is not the identity, and the nullable is not decoration. An all-zero matrix maps every colour to transparent-adjacent black, so a consumer that read a zeroed field as "no filter" would be right about the intent and wrong about the picture. Both Filter and Filter are UiColorMatrix? for exactly that reason: absence is null, never a struct that happens to be zeroed.
Fields and properties (6)
public Vector4 RedThe red output: three coefficients and an offset.
public Vector4 GreenThe green output.
public Vector4 BlueThe blue output.
public static readonly Vector3 LuminanceThe luminance weights grayscale() and saturate() are defined with.
public static UiColorMatrix IdentityThe transform that changes nothing.
public bool IsIdentityWhether this is Identity and so worth nothing to apply.
Methods (10)
public UiColorMatrix(Vector4 Red, Vector4 Green, Vector4 Blue)The per-pixel colour transform a composited group's filter applies to its surface.
public Color4 Apply(Color4 colour)Transforms one premultiplied colour.
public UiColorMatrix Then(in UiColorMatrix next)This transform, and then .
public static UiColorMatrix Brightness(float amount)Lightens or darkens: c' = c · amount.
public static UiColorMatrix Contrast(float amount)Pushes towards or away from mid grey: c' = c · amount + (0.5 − 0.5 · amount).
public static UiColorMatrix Grayscale(float amount)Drains colour towards luminance.
public static UiColorMatrix Saturate(float amount)Scales the distance from luminance.
public static UiColorMatrix Sepia(float amount)Ages towards a warm monochrome.
public static UiColorMatrix Invert(float amount)Flips towards the complement: c' = c + amount · (1 − 2c).
public static UiColorMatrix HueRotate(float degrees)Rotates the hue about the luminance axis.
Used by (13)
- BackdropFilterTestsVixen.Ui.Controls.Tests
- DrawCommandVixen.Ui
- DrawListBuilderVixen.Ui
- ElementFilterVixen.Ui
- FrameVixen.Ui.Testing
- OpeningVixen.Ui
- UiBackdropVixen.Ui
- UiCompositingTestsVixen.Graphics.Golden.Tests
- UiDropShadowVixen.Ui
- UiLayerVixen.Ui
- UiRendererVixen.Ui.Renderer
- EditorUiCompositingDeviceTestsVixen.Editor.App.Tests
- UtilityFamilySupportTestsVixen.Editor.Ui.Tests