pub enum BlendMode {
Show 29 variants
Clear,
Src,
Dst,
SrcOver,
DstOver,
SrcIn,
DstIn,
SrcOut,
DstOut,
SrcATop,
DstATop,
Xor,
Plus,
Modulate,
Multiply,
Screen,
Overlay,
Darken,
Lighten,
ColorDodge,
ColorBurn,
HardLight,
SoftLight,
Difference,
Exclusion,
Hue,
Saturation,
Color,
Luminosity,
}Expand description
How a draw combines with what a target already holds.
Three families: the Porter-Duff set, which decides which of the source and destination survive and where; the separable modes, which mix the two arithmetically channel by channel; and the non-separable modes, which exchange whole attributes of a color. Only the first works everywhere.
Variants§
Clear
Leave nothing behind. Neither source nor destination survives.
Src
Replace the destination outright, alpha included.
Not the same as Self::SrcOver with an opaque source: this overwrites
destination alpha too, which decides whether a layer composites
correctly when it is itself drawn onto something else.
Dst
Keep the destination and discard the source.
SrcOver
Source over destination: the default for drawing one thing on another.
DstOver
Destination over source, as though the source were drawn underneath.
SrcIn
Source, clipped to where the destination is.
DstIn
Destination, clipped to where the source is.
SrcOut
Source, clipped to where the destination is not.
DstOut
Destination, clipped to where the source is not.
SrcATop
Source drawn on top, but only within the destination’s shape.
DstATop
Destination drawn on top, but only within the source’s shape.
Xor
Whichever of the two is not overlapped by the other.
Plus
The two added together, saturating.
Used for light accumulation, where overlapping contributions should brighten rather than replace.
Modulate
The two multiplied together.
Multiply
Multiply the two, which always darkens.
Screen
The inverse of multiplying the inverses, which always lightens.
Overlay
Multiply or screen depending on the destination, so the destination decides the contrast.
Darken
The darker of the two, per channel.
Lighten
The lighter of the two, per channel.
ColorDodge
Brighten the destination in proportion to the source.
ColorBurn
Darken the destination in proportion to the inverse of the source.
HardLight
Overlay with the roles reversed, so the source decides the contrast.
SoftLight
A gentler hard-light, without the hard transition at the midpoint.
Difference
The absolute difference, which inverts where the two agree.
Exclusion
Like difference, but with a softer response near the midpoint.
Hue
The source’s hue, with the backdrop’s saturation and luminosity.
Saturation
The source’s saturation, with the backdrop’s hue and luminosity.
Color
The source’s hue and saturation, with the backdrop’s luminosity.
Luminosity
The source’s luminosity, with the backdrop’s hue and saturation.
Implementations§
Source§impl BlendMode
impl BlendMode
Sourcepub const PORTER_DUFF: &'static [BlendMode]
pub const PORTER_DUFF: &'static [BlendMode]
The modes every device can do, with no extension.
Sourcepub const ALL: &'static [BlendMode]
pub const ALL: &'static [BlendMode]
Every mode, for exhaustive tests and reporting.
Deliberately not what a backend iterates to decide what it supports —
that is what Self::is_advanced and the capability flag are for.
Sourcepub fn is_destructive(self) -> bool
pub fn is_destructive(self) -> bool
Whether this mode changes the destination where the source is absent.
The modes for which “the source drew nothing here” is not the same as
“leave this pixel alone”: DstIn zeroes what the source did not cover,
Clear zeroes everything, Src replaces it. A layer composited with
one of these has to cover everything it might affect rather than only
what it drew, so it is the test for whether a layer’s target may be
narrowed to its content.
The same nine upstream lists in Entity::IsBlendModeDestructive, and
the reason to match it exactly is that this decides a target’s size:
a mode missing here is a layer that silently stops masking what it
used to.
Sourcepub const fn code(self) -> f32
pub const fn code(self) -> f32
Whether this mode needs advanced blending.
Callers check crate::Capabilities::advanced_blend before using one, and a
backend without it refuses rather than substituting something that looks
close: a silently wrong blend mode is a picture nobody can debug from.
The number a shader reads to identify this mode.
Spelled out rather than cast from the discriminant, because the discriminant is an implementation detail a reordering would change and this number is written into a uniform buffer that a shader decodes. The two must agree, and only one of them is visible from the shader.
pub const fn is_advanced(self) -> bool
Sourcepub const fn factors(self) -> Option<BlendFactors>
pub const fn factors(self) -> Option<BlendFactors>
The factors this mode blends with, assuming premultiplied color.
None for an advanced mode: those are not expressible as factors at
all, which is exactly why they need an extension. Returning an
option rather than a plausible pair keeps a backend from silently
rendering the wrong thing.
Sourcepub const fn reads_destination(self) -> bool
pub const fn reads_destination(self) -> bool
Whether the destination contributes to the result.
A mode that ignores it can skip loading the target on a tiler, which is a bandwidth saving rather than a correctness one.
Sourcepub const fn respects_coverage(self) -> bool
pub const fn respects_coverage(self) -> bool
Whether a source scaled by coverage composites as though the shape were partly there.
This is what decides whether a shape may be antialiased by computing coverage in the fragment stage rather than by multisampling. Such a shape is drawn on a quad larger than itself and emits a fragment everywhere on it, including where coverage is nothing — so the mode has to leave the destination alone for a fully transparent source, or the quad erases what is behind it in the gap between the two.
Which is exactly the destination factor being One or
OneMinusSrcAlpha: the source term vanishes with the alpha whatever its
own factor is, so only the destination’s own weight is left. Every
advanced mode qualifies as well — their equations carry a
(1 - source alpha) on the destination by construction, and reduce to
it when the source contributes nothing.
The same condition happens to be what makes the partly covered edge correct rather than merely harmless. Weighting a premultiplied source by coverage and compositing gives the same answer as mixing the unweighted result into the destination by coverage, which is what multisampling would have produced.
Sourcepub const fn is_plain_write(self) -> bool
pub const fn is_plain_write(self) -> bool
Whether this simply writes the source, so blending can be switched off.