veloren_voxygen/render/pipelines/
clouds.rs

1use super::{
2    super::{AaMode, Consts},
3    GlobalsLayouts,
4};
5use bytemuck::{Pod, Zeroable};
6use vek::*;
7
8#[repr(C)]
9#[derive(Copy, Clone, Debug, Zeroable, Pod)]
10pub struct Locals {
11    all_mat_inv: [[f32; 4]; 4],
12}
13
14impl Default for Locals {
15    fn default() -> Self { Self::new(Mat4::identity(), Mat4::identity()) }
16}
17
18impl Locals {
19    pub fn new(proj_mat_inv: Mat4<f32>, view_mat_inv: Mat4<f32>) -> Self {
20        Self {
21            all_mat_inv: (view_mat_inv * proj_mat_inv).into_col_arrays(),
22        }
23    }
24}
25
26pub struct BindGroup {
27    pub(in super::super) bind_group: wgpu::BindGroup,
28}
29
30pub struct CloudsLayout {
31    pub layout: wgpu::BindGroupLayout,
32}
33
34impl CloudsLayout {
35    pub fn new(device: &wgpu::Device) -> Self {
36        Self {
37            layout: device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
38                label: None,
39                entries: &[
40                    // Color source
41                    wgpu::BindGroupLayoutEntry {
42                        binding: 0,
43                        visibility: wgpu::ShaderStages::FRAGMENT,
44                        ty: wgpu::BindingType::Texture {
45                            sample_type: wgpu::TextureSampleType::Float { filterable: true },
46                            view_dimension: wgpu::TextureViewDimension::D2,
47                            multisampled: false,
48                        },
49                        count: None,
50                    },
51                    wgpu::BindGroupLayoutEntry {
52                        binding: 1,
53                        visibility: wgpu::ShaderStages::FRAGMENT,
54                        ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::Filtering),
55                        count: None,
56                    },
57                    // Depth source
58                    wgpu::BindGroupLayoutEntry {
59                        binding: 2,
60                        visibility: wgpu::ShaderStages::FRAGMENT,
61                        ty: wgpu::BindingType::Texture {
62                            sample_type: wgpu::TextureSampleType::Float { filterable: false },
63                            view_dimension: wgpu::TextureViewDimension::D2,
64                            multisampled: false,
65                        },
66                        count: None,
67                    },
68                    wgpu::BindGroupLayoutEntry {
69                        binding: 3,
70                        visibility: wgpu::ShaderStages::FRAGMENT,
71                        ty: wgpu::BindingType::Sampler(wgpu::SamplerBindingType::NonFiltering),
72                        count: None,
73                    },
74                    // Locals
75                    wgpu::BindGroupLayoutEntry {
76                        binding: 4,
77                        visibility: wgpu::ShaderStages::FRAGMENT,
78                        ty: wgpu::BindingType::Buffer {
79                            ty: wgpu::BufferBindingType::Uniform,
80                            has_dynamic_offset: false,
81                            min_binding_size: None,
82                        },
83                        count: None,
84                    },
85                    // Materials source
86                    wgpu::BindGroupLayoutEntry {
87                        binding: 5,
88                        visibility: wgpu::ShaderStages::FRAGMENT,
89                        ty: wgpu::BindingType::Texture {
90                            sample_type: wgpu::TextureSampleType::Uint,
91                            view_dimension: wgpu::TextureViewDimension::D2,
92                            multisampled: false,
93                        },
94                        count: None,
95                    },
96                ],
97            }),
98        }
99    }
100
101    pub fn bind(
102        &self,
103        device: &wgpu::Device,
104        src_color: &wgpu::TextureView,
105        src_mat: &wgpu::TextureView,
106        src_depth: &wgpu::TextureView,
107        sampler: &wgpu::Sampler,
108        depth_sampler: &wgpu::Sampler,
109        locals: &Consts<Locals>,
110    ) -> BindGroup {
111        let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
112            label: None,
113            layout: &self.layout,
114            entries: &[
115                wgpu::BindGroupEntry {
116                    binding: 0,
117                    resource: wgpu::BindingResource::TextureView(src_color),
118                },
119                wgpu::BindGroupEntry {
120                    binding: 1,
121                    resource: wgpu::BindingResource::Sampler(sampler),
122                },
123                wgpu::BindGroupEntry {
124                    binding: 2,
125                    resource: wgpu::BindingResource::TextureView(src_depth),
126                },
127                wgpu::BindGroupEntry {
128                    binding: 3,
129                    resource: wgpu::BindingResource::Sampler(depth_sampler),
130                },
131                wgpu::BindGroupEntry {
132                    binding: 4,
133                    resource: locals.buf().as_entire_binding(),
134                },
135                wgpu::BindGroupEntry {
136                    binding: 5,
137                    resource: wgpu::BindingResource::TextureView(src_mat),
138                },
139            ],
140        });
141
142        BindGroup { bind_group }
143    }
144}
145
146pub struct CloudsPipeline {
147    pub pipeline: wgpu::RenderPipeline,
148}
149
150impl CloudsPipeline {
151    pub fn new(
152        device: &wgpu::Device,
153        vs_module: &wgpu::ShaderModule,
154        fs_module: &wgpu::ShaderModule,
155        global_layout: &GlobalsLayouts,
156        layout: &CloudsLayout,
157        aa_mode: AaMode,
158        format: wgpu::TextureFormat,
159    ) -> Self {
160        common_base::span!(_guard, "CloudsPipeline::new");
161        let render_pipeline_layout =
162            device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
163                label: Some("Clouds pipeline layout"),
164                push_constant_ranges: &[],
165                bind_group_layouts: &[
166                    &global_layout.globals,
167                    &global_layout.shadow_textures,
168                    &layout.layout,
169                ],
170            });
171
172        let samples = aa_mode.samples();
173
174        let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
175            label: Some("Clouds pipeline"),
176            layout: Some(&render_pipeline_layout),
177            vertex: wgpu::VertexState {
178                module: vs_module,
179                entry_point: Some("main"),
180                buffers: &[],
181                compilation_options: Default::default(),
182            },
183            primitive: wgpu::PrimitiveState {
184                topology: wgpu::PrimitiveTopology::TriangleList,
185                strip_index_format: None,
186                front_face: wgpu::FrontFace::Ccw,
187                cull_mode: None,
188                unclipped_depth: false,
189                polygon_mode: wgpu::PolygonMode::Fill,
190                conservative: false,
191            },
192            depth_stencil: None,
193            multisample: wgpu::MultisampleState {
194                count: samples,
195                mask: !0,
196                alpha_to_coverage_enabled: false,
197            },
198            fragment: Some(wgpu::FragmentState {
199                module: fs_module,
200                entry_point: Some("main"),
201                targets: &[Some(wgpu::ColorTargetState {
202                    format,
203                    blend: None,
204                    write_mask: wgpu::ColorWrites::ALL,
205                })],
206                compilation_options: Default::default(),
207            }),
208            multiview: None,
209            cache: None,
210        });
211
212        Self {
213            pipeline: render_pipeline,
214        }
215    }
216}