rend3_routine/common/
samplers.rs

1use std::num::NonZeroU8;
2
3use rend3::util::bind_merge::{BindGroupBuilder, BindGroupLayoutBuilder};
4use wgpu::{
5    AddressMode, BindingType, CompareFunction, Device, FilterMode, Sampler, SamplerBindingType, SamplerDescriptor,
6    ShaderStages,
7};
8
9/// Container holding a variety of samplers.
10pub struct Samplers {
11    /// Aniso 16 sampler
12    pub linear: Sampler,
13    /// Nearest neighbor sampler
14    pub nearest: Sampler,
15    /// Bilinear greater-or-equal comparison sampler
16    pub shadow: Sampler,
17}
18
19impl Samplers {
20    /// Create a new set of samplers with this device.
21    pub fn new(device: &Device) -> Self {
22        profiling::scope!("Samplers::new");
23
24        let linear = create_sampler(device, FilterMode::Linear, None);
25        let nearest = create_sampler(device, FilterMode::Nearest, None);
26        let shadow = create_sampler(device, FilterMode::Linear, Some(CompareFunction::GreaterEqual));
27
28        Self {
29            linear,
30            nearest,
31            shadow,
32        }
33    }
34
35    /// Add the samplers to the given bind group layout builder.
36    pub fn add_to_bgl(bglb: &mut BindGroupLayoutBuilder) {
37        bglb.append(
38            ShaderStages::FRAGMENT,
39            BindingType::Sampler(SamplerBindingType::Filtering),
40            None,
41        )
42        .append(
43            ShaderStages::FRAGMENT,
44            BindingType::Sampler(SamplerBindingType::NonFiltering),
45            None,
46        )
47        .append(
48            ShaderStages::FRAGMENT,
49            BindingType::Sampler(SamplerBindingType::Comparison),
50            None,
51        );
52    }
53
54    /// Add the samplers to the given bind group builder.
55    pub fn add_to_bg<'a>(&'a self, bgb: &mut BindGroupBuilder<'a>) {
56        bgb.append_sampler(&self.linear)
57            .append_sampler(&self.nearest)
58            .append_sampler(&self.shadow);
59    }
60}
61
62fn create_sampler(device: &Device, filter: FilterMode, compare: Option<CompareFunction>) -> Sampler {
63    device.create_sampler(&SamplerDescriptor {
64        label: Some("linear"),
65        address_mode_u: AddressMode::Repeat,
66        address_mode_v: AddressMode::Repeat,
67        address_mode_w: AddressMode::Repeat,
68        mag_filter: filter,
69        min_filter: filter,
70        mipmap_filter: filter,
71        lod_min_clamp: 0.0,
72        lod_max_clamp: 100.0,
73        compare,
74        anisotropy_clamp: NonZeroU8::new(16),
75        border_color: None,
76    })
77}