Skip to main content

pfx_post/
preset.rs

1use crate::bloom::Bloom;
2use crate::chain::{Chain, Pass};
3use crate::color::REC709;
4use crate::comic::ModernComic;
5use crate::fx::{
6    self, Bw, Cel, Comic, Duotone, GradientMap, Halation, Halftone, Neon, Noir, OneBit, Outline,
7    PaperGrain, Pixelate, Scanlines, TiltShift, Watercolor,
8};
9use crate::grade::{Grain, Vignette};
10use crate::tone::Tone;
11
12#[derive(Clone, Copy, Debug, PartialEq, Eq)]
13pub enum Style {
14    Cel,
15    Bw,
16    Noir,
17    Vignette,
18    Neon,
19    RubberHose,
20    Sepia,
21    Film,
22    Crt,
23    OneBit,
24    Halftone,
25    Comic,
26    ModernComic,
27    Watercolor,
28    PaperGrain,
29    Pixel,
30    Duotone,
31    GradientMap,
32    Posterize,
33    Kuwahara,
34    TiltShift,
35}
36
37impl Style {
38    pub const ALL: [Self; 21] = [
39        Self::Cel,
40        Self::Bw,
41        Self::Noir,
42        Self::Vignette,
43        Self::Neon,
44        Self::RubberHose,
45        Self::Sepia,
46        Self::Film,
47        Self::Crt,
48        Self::OneBit,
49        Self::Halftone,
50        Self::Comic,
51        Self::ModernComic,
52        Self::Watercolor,
53        Self::PaperGrain,
54        Self::Pixel,
55        Self::Duotone,
56        Self::GradientMap,
57        Self::Posterize,
58        Self::Kuwahara,
59        Self::TiltShift,
60    ];
61
62    pub fn name(self) -> &'static str {
63        match self {
64            Self::Cel => "cel",
65            Self::Bw => "bw",
66            Self::Noir => "noir",
67            Self::Vignette => "vignette",
68            Self::Neon => "neon",
69            Self::RubberHose => "rubber_hose",
70            Self::Sepia => "sepia",
71            Self::Film => "film",
72            Self::Crt => "crt",
73            Self::OneBit => "one_bit",
74            Self::Halftone => "halftone",
75            Self::Comic => "comic",
76            Self::ModernComic => "modern_comic",
77            Self::Watercolor => "watercolor",
78            Self::PaperGrain => "paper_grain",
79            Self::Pixel => "pixel",
80            Self::Duotone => "duotone",
81            Self::GradientMap => "gradient_map",
82            Self::Posterize => "posterize",
83            Self::Kuwahara => "kuwahara",
84            Self::TiltShift => "tilt_shift",
85        }
86    }
87
88    pub fn parse(name: &str) -> Option<Self> {
89        Self::ALL.into_iter().find(|style| style.name() == name)
90    }
91
92    pub fn chain(self) -> Chain {
93        Chain {
94            passes: self.passes(),
95            seed: 0,
96            frame: 0,
97        }
98    }
99
100    fn passes(self) -> Vec<Pass> {
101        match self {
102            Self::Cel => vec![
103                Pass::Exposure(1.5),
104                Pass::Cel(Cel {
105                    bands: 3,
106                    shadow: 0.62,
107                    threshold: 0.45,
108                    softness: 0.045,
109                    spec: 0.35,
110                    spec_roughness: 0.25,
111                    spec_threshold: 0.72,
112                    light: [0.3, 0.75, 0.6],
113                }),
114                Pass::Cavity(fx::Cavity {
115                    strength: 0.35,
116                    distance: 2.0,
117                }),
118                Pass::Rim(fx::Rim {
119                    strength: 0.3,
120                    width: 0.18,
121                    color: [0.62, 0.82, 1.0],
122                }),
123                Pass::Outline(Outline {
124                    enabled: true,
125                    thickness: 1.25,
126                    color: [0.02, 0.015, 0.02],
127                    local_color: true,
128                    alpha: 0.92,
129                    crease_angle: 35.0,
130                    depth_gap: 0.003,
131                }),
132            ],
133            Self::Bw => vec![Pass::Bw(Bw { weights: REC709 })],
134            Self::Noir => vec![
135                Pass::Noir(Noir {
136                    contrast: 1.9,
137                    crush: 0.18,
138                    keep: None,
139                    keep_range: 0.45,
140                }),
141                Pass::Grain(Grain {
142                    strength: 0.07,
143                    response: 0.45,
144                    clamp: false,
145                }),
146                Pass::Vignette(Vignette::power(0.62, 2.4, 0.8, 1.28)),
147            ],
148            Self::Vignette => vec![Pass::Vignette(Vignette::power(0.55, 2.4, 0.8, 1.28))],
149            Self::Neon => vec![
150                Pass::Neon(Neon {
151                    saturation: 1.8,
152                    strength: 1.35,
153                    radius: 3,
154                }),
155                Pass::Bloom(Bloom {
156                    linear_taps: false,
157                    ..Bloom::pyramid(0.85, 0.55, 0.4, 0.3, 0.2, 5, 10.0, 4)
158                }),
159            ],
160            Self::RubberHose => vec![Pass::RubberHose],
161            Self::Sepia => vec![Pass::Sepia(1.0)],
162            Self::Film => vec![
163                Pass::Distortion(0.045),
164                Pass::Aberration(0.85),
165                Pass::Halation(Halation {
166                    strength: 0.4,
167                    threshold: 0.65,
168                    radius: 6,
169                }),
170                Pass::Tone(Tone::aces()),
171                Pass::Sepia(0.18),
172                Pass::Grain(Grain {
173                    strength: 0.03,
174                    response: 0.5,
175                    clamp: true,
176                }),
177                Pass::Vignette(Vignette::smoothstep(0.3, 0.72, 0.28, 0.8)),
178            ],
179            Self::Crt => vec![
180                Pass::Curvature(0.12),
181                Pass::Aberration(0.65),
182                Pass::Bloom(Bloom::pyramid(0.2, 0.9, 0.7, 0.6, 0.15, 12, 50.0, 2)),
183                Pass::Scanlines(Scanlines {
184                    strength: 0.38,
185                    period: 2,
186                }),
187                Pass::Aperture(0.45),
188                Pass::Vignette(Vignette::power(0.4, 2.4, 0.8, 1.28)),
189            ],
190            Self::OneBit => vec![Pass::OneBit(OneBit {
191                kind: fx::NoiseKind::Blue,
192            })],
193            Self::Halftone => vec![Pass::Halftone(Halftone {
194                cell: 6.0,
195                angle: 15.0,
196                ink: [0.02, 0.02, 0.03],
197            })],
198            Self::Comic => vec![Pass::Comic(Comic {
199                levels: 5,
200                ink: 0.9,
201            })],
202            Self::ModernComic => vec![Pass::ModernComic(ModernComic::default())],
203            Self::Watercolor => vec![Pass::Watercolor(Watercolor {
204                darkening: 0.65,
205                grain: 0.22,
206                scale: 6.0,
207            })],
208            Self::PaperGrain => vec![Pass::PaperGrain(PaperGrain {
209                strength: 0.28,
210                scale: 5.0,
211            })],
212            Self::Pixel => vec![Pass::Pixel(Pixelate {
213                size: 4,
214                levels: 0,
215                palette: true,
216            })],
217            Self::Duotone => vec![Pass::Duotone(Duotone {
218                shadow: [0.05, 0.08, 0.18],
219                highlight: [0.96, 0.82, 0.55],
220            })],
221            Self::GradientMap => vec![Pass::GradientMap(GradientMap {
222                stops: [
223                    [0.04, 0.02, 0.05, 0.0],
224                    [0.42, 0.16, 0.10, 0.35],
225                    [0.86, 0.52, 0.28, 0.7],
226                    [0.96, 0.90, 0.78, 1.0],
227                ],
228                count: 4,
229            })],
230            Self::Posterize => vec![Pass::Posterize(5.0)],
231            Self::Kuwahara => vec![Pass::Kuwahara(2)],
232            Self::TiltShift => vec![Pass::TiltShift(TiltShift {
233                focus: 0.5,
234                range: 0.22,
235                radius: 5.0,
236            })],
237        }
238    }
239}
240
241pub fn names() -> &'static [&'static str] {
242    &[
243        "cel",
244        "bw",
245        "noir",
246        "vignette",
247        "neon",
248        "rubber_hose",
249        "sepia",
250        "film",
251        "crt",
252        "one_bit",
253        "halftone",
254        "comic",
255        "modern_comic",
256        "watercolor",
257        "paper_grain",
258        "pixel",
259        "duotone",
260        "gradient_map",
261        "posterize",
262        "kuwahara",
263        "tilt_shift",
264    ]
265}