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}