1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Copyright (c) 2023 Xu Shaohua <shaohua@biofan.org>. All rights reserved.
// Use of this source is governed by Lesser General Public License that can be found
// in the LICENSE file.
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum FilterMode {
/// single sample point (nearest neighbor)
Nearest,
/// interporate between 2x2 sample points (bilinear interpolation)
Linear,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq)]
pub enum MipmapMode {
/// ignore mipmap levels, sample from the "base"
None,
/// sample from the nearest level
Nearest,
/// interpolate between the two nearest levels
Linear,
}
/// Specify B and C (each between 0...1) to create a shader that applies the corresponding
/// cubic reconstruction filter to the image.
///
/// Example values:
/// ```txt
/// B = 1/3, C = 1/3 "Mitchell" filter
/// B = 0, C = 1/2 "Catmull-Rom" filter
/// ```
///
/// See ["Reconstruction Filters in Computer Graphics" Don P. Mitchell, Arun N. Netravali, 1988](
/// https://www.cs.utexas.edu/~fussell/courses/cs384g-fall2013/lectures/mitchell/Mitchell.pdf)
///
/// [Desmos worksheet](https://www.desmos.com/calculator/aghdpicrvr)
/// [Nice overview](https://entropymine.com/imageworsener/bicubic/)
#[derive(Debug, Default, Clone, PartialEq)]
pub struct CubicResampler {
val_b: f32,
val_c: f32,
}
impl CubicResampler {
#[must_use]
pub const fn new() -> Self {
Self {
val_b: 0.0,
val_c: 0.0,
}
}
/// Historic default for `FilterQuality::High`
#[must_use]
pub fn mitchell() -> Self {
Self {
val_b: 1.0 / 3.0,
val_c: 1.0 / 3.0,
}
}
#[must_use]
pub fn catmull_rom() -> Self {
Self {
val_b: 0.0,
val_c: 1.0 / 2.0,
}
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct SamplingOptions {
max_aniso: i32,
use_cubic: bool,
cubic: CubicResampler,
filter: FilterMode,
mipmap: MipmapMode,
}
impl Default for SamplingOptions {
fn default() -> Self {
Self::new()
}
}
impl SamplingOptions {
#[must_use]
pub const fn new() -> Self {
Self {
max_aniso: 0,
use_cubic: false,
cubic: CubicResampler::new(),
filter: FilterMode::Nearest,
mipmap: MipmapMode::None,
}
}
#[must_use]
pub const fn with_modes(filter: FilterMode, mipmap: MipmapMode) -> Self {
Self {
filter,
mipmap,
..Self::new()
}
}
#[must_use]
pub const fn with_resampler(cubic: CubicResampler) -> Self {
Self {
cubic,
..Self::new()
}
}
#[must_use]
pub fn with_aniso(&self, max_aniso: i32) -> Self {
Self {
max_aniso: max_aniso.max(1),
..Self::new()
}
}
#[must_use]
pub const fn is_aniso(&self) -> bool {
self.max_aniso != 0
}
}