Skip to main content

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}