Skip to main content

alpha2_render/
blend.rs

1/// Color space in which compositing arithmetic is evaluated.
2#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
3pub enum BlendSpace {
4    /// Convert sRGB-encoded inputs to linear light before blending.
5    #[default]
6    LinearLight,
7    /// Blend directly in sRGB-encoded component space.
8    SrgbEncoded,
9}
10
11impl BlendSpace {
12    pub(crate) const fn shader_value(self) -> f32 {
13        match self {
14            Self::LinearLight => 0.0,
15            Self::SrgbEncoded => 1.0,
16        }
17    }
18}
19
20/// RGB blend operation applied before Porter-Duff source-over.
21///
22/// Formulas follow W3C Compositing and Blending Level 1, evaluated in the renderer's
23/// [`BlendSpace`]. The first twelve are separable; `Hue`, `Saturation`, `Color` and
24/// `Luminosity` are not. `PlusLighter` is the Level 2 additive operator.
25#[derive(Copy, Clone, Debug, Default, Eq, Hash, PartialEq)]
26pub enum BlendMode {
27    /// Preserve the source color.
28    #[default]
29    Normal,
30    /// Multiply source and backdrop components.
31    Multiply,
32    /// Inverse-multiply source and backdrop components.
33    Screen,
34    /// Multiply dark backdrop regions and screen light regions.
35    Overlay,
36    /// The darker of source and backdrop, per channel.
37    Darken,
38    /// The lighter of source and backdrop, per channel.
39    Lighten,
40    /// Brighten the backdrop to reflect the source.
41    ColorDodge,
42    /// Darken the backdrop to reflect the source.
43    ColorBurn,
44    /// Multiply or screen, depending on the source.
45    HardLight,
46    /// Darken or lighten, depending on the source: a diffused hard light.
47    SoftLight,
48    /// The absolute difference of source and backdrop.
49    Difference,
50    /// Like difference, with lower contrast.
51    Exclusion,
52    /// The source's hue with the backdrop's saturation and luminosity.
53    Hue,
54    /// The source's saturation with the backdrop's hue and luminosity.
55    Saturation,
56    /// The source's hue and saturation with the backdrop's luminosity.
57    Color,
58    /// The source's luminosity with the backdrop's hue and saturation.
59    Luminosity,
60    /// Premultiplied source plus backdrop, color and alpha clamped to 1.
61    PlusLighter,
62}
63
64impl BlendMode {
65    /// Every mode: Level 1 in specification order, then `PlusLighter`.
66    pub const ALL: [Self; 17] = [
67        Self::Normal,
68        Self::Multiply,
69        Self::Screen,
70        Self::Overlay,
71        Self::Darken,
72        Self::Lighten,
73        Self::ColorDodge,
74        Self::ColorBurn,
75        Self::HardLight,
76        Self::SoftLight,
77        Self::Difference,
78        Self::Exclusion,
79        Self::Hue,
80        Self::Saturation,
81        Self::Color,
82        Self::Luminosity,
83        Self::PlusLighter,
84    ];
85
86    /// The index `composite.wesl` switches on.
87    pub(crate) const fn shader_value(self) -> f32 {
88        match self {
89            Self::Normal => 0.0,
90            Self::Multiply => 1.0,
91            Self::Screen => 2.0,
92            Self::Overlay => 3.0,
93            Self::Darken => 4.0,
94            Self::Lighten => 5.0,
95            Self::ColorDodge => 6.0,
96            Self::ColorBurn => 7.0,
97            Self::HardLight => 8.0,
98            Self::SoftLight => 9.0,
99            Self::Difference => 10.0,
100            Self::Exclusion => 11.0,
101            Self::Hue => 12.0,
102            Self::Saturation => 13.0,
103            Self::Color => 14.0,
104            Self::Luminosity => 15.0,
105            Self::PlusLighter => 16.0,
106        }
107    }
108}