fyrox_graphics/sampler.rs
1// Copyright (c) 2019-present Dmitry Stepanov and Fyrox Engine contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in all
11// copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19// SOFTWARE.
20
21//! A sampler is a GPU entity that defines how texels will be fetched from a texture. See [`GpuSamplerDescriptor`]
22//! docs for more info.
23
24use crate::define_shared_wrapper;
25use fyrox_core::define_as_any_trait;
26use std::fmt::Debug;
27
28define_as_any_trait!(GpuSamplerAsAny => GpuSamplerTrait);
29
30/// A set of potential options that can be used to configure a GPU sampler.
31pub struct GpuSamplerDescriptor {
32 /// Minification filter of the texture. See [`MinificationFilter`] docs for more info.
33 pub min_filter: MinificationFilter,
34 /// Magnification filter of the texture. See [`MagnificationFilter`] docs for more info.
35 pub mag_filter: MagnificationFilter,
36 /// S coordinate wrap mode. See [`WrapMode`] docs for more info.
37 pub s_wrap_mode: WrapMode,
38 /// T coordinate wrap mode. See [`WrapMode`] docs for more info.
39 pub t_wrap_mode: WrapMode,
40 /// R coordinate wrap mode. See [`WrapMode`] docs for more info.
41 pub r_wrap_mode: WrapMode,
42 /// Anisotropy level of the texture. Default is 1.0. Max number is usually depends on the
43 /// GPU, but the cap is 16.0 on pretty much any platform. This number should be a power of two.
44 pub anisotropy: f32,
45 /// Sets the minimum level-of-detail parameter. This floating-point value limits the selection
46 /// of highest resolution mipmap (lowest mipmap level). The initial value is -1000.0.
47 pub min_lod: f32,
48 /// Sets the maximum level-of-detail parameter. This floating-point value limits the selection
49 /// of the lowest resolution mipmap (highest mipmap level). The initial value is 1000.0.
50 pub max_lod: f32,
51 /// Specifies a fixed bias value that is to be added to the level-of-detail parameter for the
52 /// texture before texture sampling. The specified value is added to the shader-supplied bias
53 /// value (if any) and subsequently clamped into the implementation-defined range
54 /// `−bias_max..bias_max`, where `bias_max` is the value that can be fetched from the current
55 /// graphics server. The initial value is 0.0.
56 pub lod_bias: f32,
57}
58
59impl Default for GpuSamplerDescriptor {
60 fn default() -> Self {
61 Self {
62 min_filter: Default::default(),
63 mag_filter: Default::default(),
64 s_wrap_mode: Default::default(),
65 t_wrap_mode: Default::default(),
66 r_wrap_mode: Default::default(),
67 anisotropy: 1.0,
68 min_lod: -1000.0,
69 max_lod: 1000.0,
70 lod_bias: 0.0,
71 }
72 }
73}
74
75impl GpuSamplerDescriptor {
76 /// Create a sampler for a rander target.
77 pub fn new_rt_sampler() -> Self {
78 Self {
79 min_filter: MinificationFilter::Nearest,
80 mag_filter: MagnificationFilter::Nearest,
81 s_wrap_mode: WrapMode::ClampToEdge,
82 t_wrap_mode: WrapMode::ClampToEdge,
83 r_wrap_mode: WrapMode::ClampToEdge,
84 ..Default::default()
85 }
86 }
87}
88
89/// Sampler is a GPU entity that defines how texels will be fetched from a texture. See [`GpuSamplerDescriptor`]
90/// docs for more info.
91pub trait GpuSamplerTrait: GpuSamplerAsAny + Debug {}
92
93define_shared_wrapper!(GpuSampler<dyn GpuSamplerTrait>);
94
95/// The texture magnification function is used when the pixel being textured maps to an area
96/// less than or equal to one texture element.
97#[derive(Default, Copy, Clone, PartialOrd, PartialEq, Eq, Hash, Debug)]
98#[repr(u32)]
99pub enum MagnificationFilter {
100 /// Returns the value of the texture element that is nearest to the center of the pixel
101 /// being textured.
102 Nearest,
103 /// Returns the weighted average of the four texture elements that are closest to the
104 /// center of the pixel being textured.
105 #[default]
106 Linear,
107}
108
109/// The texture minifying function is used whenever the pixel being textured maps to an area
110/// greater than one texture element.
111#[derive(Default, Copy, Clone, PartialOrd, PartialEq, Eq, Hash, Debug)]
112pub enum MinificationFilter {
113 /// Returns the value of the texture element that is nearest to the center of the pixel
114 /// being textured.
115 Nearest,
116 /// Chooses the mipmap that most closely matches the size of the pixel being textured and
117 /// uses the Nearest criterion (the texture element nearest to the center of the pixel)
118 /// to produce a texture value.
119 NearestMipMapNearest,
120 /// Chooses the two mipmaps that most closely match the size of the pixel being textured
121 /// and uses the Nearest criterion (the texture element nearest to the center of the pixel)
122 /// to produce a texture value from each mipmap. The final texture value is a weighted average
123 /// of those two values.
124 NearestMipMapLinear,
125 /// Returns the weighted average of the four texture elements that are closest to the
126 /// center of the pixel being textured.
127 #[default]
128 Linear,
129 /// Chooses the mipmap that most closely matches the size of the pixel being textured and
130 /// uses the Linear criterion (a weighted average of the four texture elements that are
131 /// closest to the center of the pixel) to produce a texture value.
132 LinearMipMapNearest,
133 /// Chooses the two mipmaps that most closely match the size of the pixel being textured
134 /// and uses the Linear criterion (a weighted average of the four texture elements that
135 /// are closest to the center of the pixel) to produce a texture value from each mipmap.
136 /// The final texture value is a weighted average of those two values.
137 LinearMipMapLinear,
138}
139
140/// Defines a law of texture coordinate modification.
141#[derive(Default, Copy, Clone, Eq, PartialEq, Debug)]
142pub enum WrapMode {
143 /// Causes the integer part of a coordinate to be ignored; GPU uses only the fractional part,
144 /// thereby creating a repeating pattern.
145 #[default]
146 Repeat,
147 /// Causes a coordinates to be clamped to the range, where N is the size of the texture
148 /// in the direction of clamping
149 ClampToEdge,
150 /// Evaluates a coordinates in a similar manner to ClampToEdge. However, in cases where clamping
151 /// would have occurred in ClampToEdge mode, the fetched texel data is substituted with the values
152 /// specified by border color.
153 ClampToBorder,
154 /// Causes the coordinate to be set to the fractional part of the texture coordinate if the integer
155 /// part of coordinate is even; if the integer part of coordinate is odd, then the coordinate texture
156 /// coordinate is set to 1-frac, where frac represents the fractional part of coordinate.
157 MirroredRepeat,
158 /// Causes a coordinate to be repeated as for MirroredRepeat for one repetition of the texture, at
159 /// which point the coordinate to be clamped as in ClampToEdge.
160 MirrorClampToEdge,
161}
162
163/// Texture coordinate.
164#[derive(Copy, Clone, Eq, PartialEq, Debug)]
165pub enum Coordinate {
166 /// S coordinate, similar to X axis.
167 S,
168 /// T coordinate, similar to Y axis.
169 T,
170 /// R coordinate, similar to Z axis.
171 R,
172}