maplibre/render/shaders/
mod.rs

1#![allow(clippy::identity_op)]
2
3use bytemuck_derive::{Pod, Zeroable};
4use cgmath::SquareMatrix;
5
6use crate::{
7    coords::WorldCoords,
8    legacy::buckets::symbol_bucket::SymbolVertex,
9    render::resource::{FragmentState, VertexBufferLayout, VertexState},
10};
11
12pub type Vec2f32 = [f32; 2];
13pub type Vec3f32 = [f32; 3];
14pub type Vec4f32 = [f32; 4];
15pub type Mat4x4f32 = [Vec4f32; 4];
16
17impl From<WorldCoords> for Vec3f32 {
18    fn from(world_coords: WorldCoords) -> Self {
19        [world_coords.x as f32, world_coords.y as f32, 0.0]
20    }
21}
22
23pub trait Shader {
24    fn describe_vertex(&self) -> VertexState;
25    fn describe_fragment(&self) -> FragmentState;
26}
27
28pub struct TileMaskShader {
29    pub format: wgpu::TextureFormat,
30    pub draw_colors: bool,
31    pub debug_lines: bool,
32}
33
34impl Shader for TileMaskShader {
35    fn describe_vertex(&self) -> VertexState {
36        VertexState {
37            source: if self.debug_lines {
38                include_str!("tile_debug.vertex.wgsl")
39            } else {
40                include_str!("tile_mask.vertex.wgsl")
41            },
42            entry_point: "main",
43            buffers: vec![VertexBufferLayout {
44                array_stride: std::mem::size_of::<ShaderTileMetadata>() as u64,
45                step_mode: wgpu::VertexStepMode::Instance,
46                attributes: vec![
47                    // translate
48                    wgpu::VertexAttribute {
49                        offset: 0,
50                        format: wgpu::VertexFormat::Float32x4,
51                        shader_location: 4,
52                    },
53                    wgpu::VertexAttribute {
54                        offset: 1 * wgpu::VertexFormat::Float32x4.size(),
55                        format: wgpu::VertexFormat::Float32x4,
56                        shader_location: 5,
57                    },
58                    wgpu::VertexAttribute {
59                        offset: 2 * wgpu::VertexFormat::Float32x4.size(),
60                        format: wgpu::VertexFormat::Float32x4,
61                        shader_location: 6,
62                    },
63                    wgpu::VertexAttribute {
64                        offset: 3 * wgpu::VertexFormat::Float32x4.size(),
65                        format: wgpu::VertexFormat::Float32x4,
66                        shader_location: 7,
67                    },
68                    // zoom factor
69                    wgpu::VertexAttribute {
70                        offset: 4 * wgpu::VertexFormat::Float32x4.size(),
71                        format: wgpu::VertexFormat::Float32,
72                        shader_location: 9,
73                    },
74                ],
75            }],
76        }
77    }
78
79    fn describe_fragment(&self) -> FragmentState {
80        FragmentState {
81            source: include_str!("basic.fragment.wgsl"),
82            entry_point: "main",
83            targets: vec![Some(wgpu::ColorTargetState {
84                format: self.format,
85                blend: None,
86                write_mask: if self.draw_colors {
87                    wgpu::ColorWrites::ALL
88                } else {
89                    wgpu::ColorWrites::empty()
90                },
91            })],
92        }
93    }
94}
95
96pub struct FillShader {
97    pub format: wgpu::TextureFormat,
98}
99
100impl Shader for FillShader {
101    fn describe_vertex(&self) -> VertexState {
102        VertexState {
103            source: include_str!("fill.vertex.wgsl"),
104            entry_point: "main",
105            buffers: vec![
106                // vertex data
107                VertexBufferLayout {
108                    array_stride: std::mem::size_of::<ShaderVertex>() as u64,
109                    step_mode: wgpu::VertexStepMode::Vertex,
110                    attributes: vec![
111                        // position
112                        wgpu::VertexAttribute {
113                            offset: 0,
114                            format: wgpu::VertexFormat::Float32x2,
115                            shader_location: 0,
116                        },
117                        // normal
118                        wgpu::VertexAttribute {
119                            offset: wgpu::VertexFormat::Float32x2.size(),
120                            format: wgpu::VertexFormat::Float32x2,
121                            shader_location: 1,
122                        },
123                    ],
124                },
125                // tile metadata
126                VertexBufferLayout {
127                    array_stride: std::mem::size_of::<ShaderTileMetadata>() as u64,
128                    step_mode: wgpu::VertexStepMode::Instance,
129                    attributes: vec![
130                        // translate
131                        wgpu::VertexAttribute {
132                            offset: 0,
133                            format: wgpu::VertexFormat::Float32x4,
134                            shader_location: 4,
135                        },
136                        wgpu::VertexAttribute {
137                            offset: 1 * wgpu::VertexFormat::Float32x4.size(),
138                            format: wgpu::VertexFormat::Float32x4,
139                            shader_location: 5,
140                        },
141                        wgpu::VertexAttribute {
142                            offset: 2 * wgpu::VertexFormat::Float32x4.size(),
143                            format: wgpu::VertexFormat::Float32x4,
144                            shader_location: 6,
145                        },
146                        wgpu::VertexAttribute {
147                            offset: 3 * wgpu::VertexFormat::Float32x4.size(),
148                            format: wgpu::VertexFormat::Float32x4,
149                            shader_location: 7,
150                        },
151                        // zoom_factor
152                        wgpu::VertexAttribute {
153                            offset: 4 * wgpu::VertexFormat::Float32x4.size(),
154                            format: wgpu::VertexFormat::Float32,
155                            shader_location: 9,
156                        },
157                    ],
158                },
159                // layer metadata
160                VertexBufferLayout {
161                    array_stride: std::mem::size_of::<ShaderLayerMetadata>() as u64,
162                    step_mode: wgpu::VertexStepMode::Instance,
163                    attributes: vec![
164                        // z_index
165                        wgpu::VertexAttribute {
166                            offset: 0,
167                            format: wgpu::VertexFormat::Float32,
168                            shader_location: 10,
169                        },
170                    ],
171                },
172                // features
173                VertexBufferLayout {
174                    array_stride: std::mem::size_of::<FillShaderFeatureMetadata>() as u64,
175                    step_mode: wgpu::VertexStepMode::Vertex,
176                    attributes: vec![
177                        // color
178                        wgpu::VertexAttribute {
179                            offset: 0,
180                            format: wgpu::VertexFormat::Float32x4,
181                            shader_location: 8,
182                        },
183                    ],
184                },
185            ],
186        }
187    }
188
189    fn describe_fragment(&self) -> FragmentState {
190        FragmentState {
191            source: include_str!("fill.fragment.wgsl"),
192            entry_point: "main",
193            targets: vec![Some(wgpu::ColorTargetState {
194                format: self.format,
195                blend: None,
196                write_mask: wgpu::ColorWrites::ALL,
197            })],
198        }
199    }
200}
201
202pub struct LineShader {
203    pub format: wgpu::TextureFormat,
204}
205
206impl Shader for LineShader {
207    fn describe_vertex(&self) -> VertexState {
208        VertexState {
209            source: include_str!("line.vertex.wgsl"),
210            entry_point: "main",
211            buffers: vec![
212                // vertex data
213                VertexBufferLayout {
214                    array_stride: std::mem::size_of::<ShaderVertex>() as u64,
215                    step_mode: wgpu::VertexStepMode::Vertex,
216                    attributes: vec![
217                        // position
218                        wgpu::VertexAttribute {
219                            offset: 0,
220                            format: wgpu::VertexFormat::Float32x2,
221                            shader_location: 0,
222                        },
223                        // normal
224                        wgpu::VertexAttribute {
225                            offset: wgpu::VertexFormat::Float32x2.size(),
226                            format: wgpu::VertexFormat::Float32x2,
227                            shader_location: 1,
228                        },
229                    ],
230                },
231                // tile metadata
232                VertexBufferLayout {
233                    array_stride: std::mem::size_of::<ShaderTileMetadata>() as u64,
234                    step_mode: wgpu::VertexStepMode::Instance,
235                    attributes: vec![
236                        // translate
237                        wgpu::VertexAttribute {
238                            offset: 0,
239                            format: wgpu::VertexFormat::Float32x4,
240                            shader_location: 4,
241                        },
242                        wgpu::VertexAttribute {
243                            offset: 1 * wgpu::VertexFormat::Float32x4.size(),
244                            format: wgpu::VertexFormat::Float32x4,
245                            shader_location: 5,
246                        },
247                        wgpu::VertexAttribute {
248                            offset: 2 * wgpu::VertexFormat::Float32x4.size(),
249                            format: wgpu::VertexFormat::Float32x4,
250                            shader_location: 6,
251                        },
252                        wgpu::VertexAttribute {
253                            offset: 3 * wgpu::VertexFormat::Float32x4.size(),
254                            format: wgpu::VertexFormat::Float32x4,
255                            shader_location: 7,
256                        },
257                        // zoom_factor
258                        wgpu::VertexAttribute {
259                            offset: 4 * wgpu::VertexFormat::Float32x4.size(),
260                            format: wgpu::VertexFormat::Float32,
261                            shader_location: 9,
262                        },
263                        // viewport_width
264                        wgpu::VertexAttribute {
265                            offset: 4 * wgpu::VertexFormat::Float32x4.size()
266                                + wgpu::VertexFormat::Float32.size(),
267                            format: wgpu::VertexFormat::Float32,
268                            shader_location: 11,
269                        },
270                        // viewport_height
271                        wgpu::VertexAttribute {
272                            offset: 4 * wgpu::VertexFormat::Float32x4.size()
273                                + 2 * wgpu::VertexFormat::Float32.size(),
274                            format: wgpu::VertexFormat::Float32,
275                            shader_location: 12,
276                        },
277                    ],
278                },
279                // layer metadata
280                VertexBufferLayout {
281                    array_stride: std::mem::size_of::<ShaderLayerMetadata>() as u64,
282                    step_mode: wgpu::VertexStepMode::Instance,
283                    attributes: vec![
284                        // z_index
285                        wgpu::VertexAttribute {
286                            offset: 0,
287                            format: wgpu::VertexFormat::Float32,
288                            shader_location: 10,
289                        },
290                        // line_width
291                        wgpu::VertexAttribute {
292                            offset: wgpu::VertexFormat::Float32.size(),
293                            format: wgpu::VertexFormat::Float32,
294                            shader_location: 13,
295                        },
296                    ],
297                },
298                // features
299                VertexBufferLayout {
300                    array_stride: std::mem::size_of::<FillShaderFeatureMetadata>() as u64,
301                    step_mode: wgpu::VertexStepMode::Vertex,
302                    attributes: vec![
303                        // color
304                        wgpu::VertexAttribute {
305                            offset: 0,
306                            format: wgpu::VertexFormat::Float32x4,
307                            shader_location: 8,
308                        },
309                    ],
310                },
311            ],
312        }
313    }
314
315    fn describe_fragment(&self) -> FragmentState {
316        FragmentState {
317            source: include_str!("line.fragment.wgsl"),
318            entry_point: "main",
319            targets: vec![Some(wgpu::ColorTargetState {
320                format: self.format,
321                blend: Some(wgpu::BlendState {
322                    color: wgpu::BlendComponent {
323                        src_factor: wgpu::BlendFactor::SrcAlpha,
324                        dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
325                        operation: wgpu::BlendOperation::Add,
326                    },
327                    alpha: wgpu::BlendComponent {
328                        src_factor: wgpu::BlendFactor::One,
329                        dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
330                        operation: wgpu::BlendOperation::Add,
331                    },
332                }),
333                write_mask: wgpu::ColorWrites::ALL,
334            })],
335        }
336    }
337}
338
339#[repr(C)]
340#[derive(Copy, Clone, Pod, Zeroable)]
341pub struct ShaderCamera {
342    view_proj: Mat4x4f32,   // 64 bytes
343    view_position: Vec4f32, // 16 bytes
344}
345
346impl ShaderCamera {
347    pub fn new(view_proj: Mat4x4f32, view_position: Vec4f32) -> Self {
348        Self {
349            view_position,
350            view_proj,
351        }
352    }
353}
354
355impl Default for ShaderCamera {
356    fn default() -> Self {
357        Self {
358            view_position: [0.0; 4],
359            view_proj: cgmath::Matrix4::identity().into(),
360        }
361    }
362}
363
364#[repr(C)]
365#[derive(Copy, Clone, Pod, Zeroable)]
366pub struct ShaderGlobals {
367    camera: ShaderCamera,
368}
369
370impl ShaderGlobals {
371    pub fn new(camera_uniform: ShaderCamera) -> Self {
372        Self {
373            camera: camera_uniform,
374        }
375    }
376}
377
378#[repr(C)]
379#[derive(Copy, Clone, Pod, Zeroable)]
380pub struct ShaderVertex {
381    pub position: Vec2f32,
382    pub normal: Vec2f32,
383}
384
385impl ShaderVertex {
386    pub fn new(position: Vec2f32, normal: Vec2f32) -> Self {
387        Self { position, normal }
388    }
389}
390
391impl Default for ShaderVertex {
392    fn default() -> Self {
393        ShaderVertex::new([0.0, 0.0], [0.0, 0.0])
394    }
395}
396
397#[repr(C)]
398#[derive(Debug, Copy, Clone, Pod, Zeroable)]
399pub struct FillShaderFeatureMetadata {
400    pub color: Vec4f32,
401}
402
403#[repr(C)]
404#[derive(Debug, Copy, Clone, Pod, Zeroable, Default)]
405pub struct SDFShaderFeatureMetadata {
406    pub opacity: f32,
407}
408
409#[repr(C)]
410#[derive(Copy, Clone, Pod, Zeroable)]
411pub struct ShaderLayerMetadata {
412    pub z_index: f32,
413    pub line_width: f32,
414}
415
416#[repr(C)]
417#[derive(Copy, Clone, Pod, Zeroable)]
418pub struct ShaderTileMetadata {
419    pub transform: Mat4x4f32,
420    pub zoom_factor: f32,
421    pub viewport_width: f32,
422    pub viewport_height: f32,
423}
424
425impl ShaderTileMetadata {
426    pub fn new(transform: Mat4x4f32, zoom_factor: f32) -> Self {
427        Self {
428            transform,
429            zoom_factor,
430            viewport_width: 512.0,
431            viewport_height: 512.0,
432        }
433    }
434}
435
436#[repr(C)]
437#[derive(Copy, Clone, Pod, Zeroable)]
438pub struct ShaderTextureVertex {
439    pub position: Vec2f32,
440    pub tex_coords: Vec2f32,
441}
442
443impl ShaderTextureVertex {
444    pub fn new(position: Vec2f32, tex_coords: Vec2f32) -> Self {
445        Self {
446            position,
447            tex_coords,
448        }
449    }
450}
451
452impl Default for ShaderTextureVertex {
453    fn default() -> Self {
454        ShaderTextureVertex::new([0.0, 0.0], [0.0, 0.0])
455    }
456}
457
458pub struct RasterShader {
459    pub format: wgpu::TextureFormat,
460}
461
462impl Shader for RasterShader {
463    fn describe_vertex(&self) -> VertexState {
464        VertexState {
465            source: include_str!("raster.vertex.wgsl"),
466            entry_point: "main",
467            buffers: vec![
468                // tile metadata
469                VertexBufferLayout {
470                    array_stride: std::mem::size_of::<ShaderTileMetadata>() as u64,
471                    step_mode: wgpu::VertexStepMode::Instance,
472                    attributes: vec![
473                        // translate
474                        wgpu::VertexAttribute {
475                            offset: 0,
476                            format: wgpu::VertexFormat::Float32x4,
477                            shader_location: 4,
478                        },
479                        wgpu::VertexAttribute {
480                            offset: 1 * wgpu::VertexFormat::Float32x4.size(),
481                            format: wgpu::VertexFormat::Float32x4,
482                            shader_location: 5,
483                        },
484                        wgpu::VertexAttribute {
485                            offset: 2 * wgpu::VertexFormat::Float32x4.size(),
486                            format: wgpu::VertexFormat::Float32x4,
487                            shader_location: 6,
488                        },
489                        wgpu::VertexAttribute {
490                            offset: 3 * wgpu::VertexFormat::Float32x4.size(),
491                            format: wgpu::VertexFormat::Float32x4,
492                            shader_location: 7,
493                        },
494                        // zoom_factor
495                        wgpu::VertexAttribute {
496                            offset: 4 * wgpu::VertexFormat::Float32x4.size(),
497                            format: wgpu::VertexFormat::Float32,
498                            shader_location: 9,
499                        },
500                    ],
501                },
502                // layer metadata
503                VertexBufferLayout {
504                    array_stride: std::mem::size_of::<ShaderLayerMetadata>() as u64,
505                    step_mode: wgpu::VertexStepMode::Instance,
506                    attributes: vec![
507                        // z_index
508                        wgpu::VertexAttribute {
509                            offset: 0,
510                            format: wgpu::VertexFormat::Float32,
511                            shader_location: 10,
512                        },
513                    ],
514                },
515            ],
516        }
517    }
518
519    fn describe_fragment(&self) -> FragmentState {
520        FragmentState {
521            source: include_str!("raster.fragment.wgsl"),
522            entry_point: "main",
523            targets: vec![Some(wgpu::ColorTargetState {
524                format: self.format,
525                blend: Some(wgpu::BlendState {
526                    color: wgpu::BlendComponent::REPLACE,
527                    alpha: wgpu::BlendComponent::REPLACE,
528                }),
529                write_mask: wgpu::ColorWrites::ALL,
530            })],
531        }
532    }
533}
534
535#[repr(C)]
536#[derive(Copy, Clone, Pod, Zeroable)]
537pub struct ShaderSymbolVertex {
538    // 4 bytes * 3 = 12 bytes
539    pub position: [f32; 3],
540    // 4 bytes * 3 = 12 bytes
541    pub text_anchor: [f32; 3],
542    // 4 bytes * 2 = 8 bytes
543    pub tex_coords: [f32; 2],
544    // 1 byte * 4 = 4 bytes
545    pub color: [u8; 4],
546    // 1 byte
547    pub is_glyph: u32,
548}
549
550#[repr(C)]
551#[derive(Copy, Clone, Pod, Zeroable)]
552pub struct ShaderSymbolVertexNew {
553    pub a_pos_offset: [i32; 4],
554    pub a_data: [u32; 4],
555    pub a_pixeloffset: [i32; 4],
556}
557
558const MAX_GLYPH_ICON_SIZE: u32 = 255;
559const SIZE_PACK_FACTOR: u32 = 128;
560const MAX_PACKED_SIZE: u32 = MAX_GLYPH_ICON_SIZE * SIZE_PACK_FACTOR;
561
562impl ShaderSymbolVertexNew {
563    pub fn new(vertex: &SymbolVertex) -> Self {
564        let a_size_min =
565            (MAX_PACKED_SIZE.min((vertex.size_data.start * SIZE_PACK_FACTOR as f64) as u32) << 1)
566                + vertex.is_sdf as u32;
567        let a_size_max =
568            MAX_PACKED_SIZE.min((vertex.size_data.end * SIZE_PACK_FACTOR as f64) as u32);
569
570        ShaderSymbolVertexNew {
571            a_pos_offset: [
572                vertex.label_anchor.x as i32,
573                vertex.label_anchor.y as i32,
574                (vertex.o.x * 32.).round() as i32,
575                ((vertex.o.y + vertex.glyph_offset_y) * 32.) as i32,
576            ],
577            a_data: [vertex.tx as u32, vertex.ty as u32, a_size_min, a_size_max],
578            a_pixeloffset: [
579                (vertex.pixel_offset.x * 16.) as i32,
580                (vertex.pixel_offset.y * 16.) as i32,
581                (vertex.min_font_scale.x * 256.) as i32,
582                (vertex.min_font_scale.y * 256.) as i32,
583            ],
584        }
585    }
586}
587
588pub struct SymbolShader {
589    pub format: wgpu::TextureFormat,
590}
591
592impl Shader for SymbolShader {
593    fn describe_vertex(&self) -> VertexState {
594        VertexState {
595            source: include_str!("sdf_new.vertex.wgsl"),
596            entry_point: "main",
597            buffers: vec![
598                // vertex data
599                VertexBufferLayout {
600                    array_stride: std::mem::size_of::<ShaderSymbolVertexNew>() as u64,
601                    step_mode: wgpu::VertexStepMode::Vertex,
602                    attributes: vec![
603                        // a_pos_offset
604                        wgpu::VertexAttribute {
605                            offset: 0,
606                            format: wgpu::VertexFormat::Sint32x4,
607                            shader_location: 0,
608                        },
609                        // a_data
610                        wgpu::VertexAttribute {
611                            offset: wgpu::VertexFormat::Sint32x4.size(),
612                            format: wgpu::VertexFormat::Uint32x4,
613                            shader_location: 1,
614                        },
615                        // a_pixeloffset
616                        wgpu::VertexAttribute {
617                            offset: wgpu::VertexFormat::Sint32x4.size()
618                                + wgpu::VertexFormat::Uint32x4.size(),
619                            format: wgpu::VertexFormat::Sint32x4,
620                            shader_location: 2,
621                        },
622                    ],
623                },
624                // tile metadata
625                VertexBufferLayout {
626                    array_stride: std::mem::size_of::<ShaderTileMetadata>() as u64,
627                    step_mode: wgpu::VertexStepMode::Instance,
628                    attributes: vec![
629                        // translate
630                        wgpu::VertexAttribute {
631                            offset: 0,
632                            format: wgpu::VertexFormat::Float32x4,
633                            shader_location: 4,
634                        },
635                        wgpu::VertexAttribute {
636                            offset: 1 * wgpu::VertexFormat::Float32x4.size(),
637                            format: wgpu::VertexFormat::Float32x4,
638                            shader_location: 5,
639                        },
640                        wgpu::VertexAttribute {
641                            offset: 2 * wgpu::VertexFormat::Float32x4.size(),
642                            format: wgpu::VertexFormat::Float32x4,
643                            shader_location: 6,
644                        },
645                        wgpu::VertexAttribute {
646                            offset: 3 * wgpu::VertexFormat::Float32x4.size(),
647                            format: wgpu::VertexFormat::Float32x4,
648                            shader_location: 7,
649                        },
650                        // zoom_factor
651                        wgpu::VertexAttribute {
652                            offset: 4 * wgpu::VertexFormat::Float32x4.size(),
653                            format: wgpu::VertexFormat::Float32,
654                            shader_location: 9,
655                        },
656                    ],
657                },
658                // layer metadata
659                VertexBufferLayout {
660                    array_stride: std::mem::size_of::<ShaderLayerMetadata>() as u64,
661                    step_mode: wgpu::VertexStepMode::Instance,
662                    attributes: vec![
663                        // z_index
664                        wgpu::VertexAttribute {
665                            offset: 0,
666                            format: wgpu::VertexFormat::Float32,
667                            shader_location: 10,
668                        },
669                        // text_size (repurposed from line_width)
670                        wgpu::VertexAttribute {
671                            offset: wgpu::VertexFormat::Float32.size(),
672                            format: wgpu::VertexFormat::Float32,
673                            shader_location: 13,
674                        },
675                    ],
676                },
677                // features
678                //VertexBufferLayout {
679                //    array_stride: std::mem::size_of::<SDFShaderFeatureMetadata>() as u64,
680                //    step_mode: wgpu::VertexStepMode::Vertex,
681                //    attributes: vec![
682                //        // opacity
683                //        wgpu::VertexAttribute {
684                //            offset: 0,
685                //            format: wgpu::VertexFormat::Float32,
686                //            shader_location: 12,
687                //        },
688                //    ],
689                //},
690            ],
691        }
692    }
693
694    fn describe_fragment(&self) -> FragmentState {
695        FragmentState {
696            source: include_str!("sdf_new.fragment.wgsl"),
697            entry_point: "main",
698            targets: vec![Some(wgpu::ColorTargetState {
699                format: self.format,
700                write_mask: wgpu::ColorWrites::ALL,
701                blend: Some(wgpu::BlendState {
702                    color: wgpu::BlendComponent {
703                        src_factor: wgpu::BlendFactor::SrcAlpha,
704                        dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
705                        operation: wgpu::BlendOperation::Add,
706                    },
707                    alpha: wgpu::BlendComponent {
708                        src_factor: wgpu::BlendFactor::One,
709                        dst_factor: wgpu::BlendFactor::Zero,
710                        operation: wgpu::BlendOperation::Add,
711                    },
712                }),
713            })],
714        }
715    }
716}
717
718#[repr(C)]
719#[derive(Copy, Clone, Debug, Pod, Zeroable)]
720pub struct BackgroundLayerMetadata {
721    pub color: [f32; 4],
722    pub z_index: f32,
723}
724
725pub struct BackgroundShader {
726    pub format: wgpu::TextureFormat,
727}
728
729impl Shader for BackgroundShader {
730    fn describe_vertex(&self) -> VertexState {
731        VertexState {
732            source: include_str!("background.vertex.wgsl"),
733            entry_point: "main",
734            buffers: vec![VertexBufferLayout {
735                array_stride: std::mem::size_of::<BackgroundLayerMetadata>() as u64,
736                step_mode: wgpu::VertexStepMode::Instance,
737                attributes: vec![
738                    wgpu::VertexAttribute {
739                        offset: 0,
740                        format: wgpu::VertexFormat::Float32x4,
741                        shader_location: 0,
742                    },
743                    wgpu::VertexAttribute {
744                        offset: 16,
745                        format: wgpu::VertexFormat::Float32,
746                        shader_location: 1,
747                    },
748                ],
749            }],
750        }
751    }
752
753    fn describe_fragment(&self) -> FragmentState {
754        FragmentState {
755            source: include_str!("basic.fragment.wgsl"),
756            entry_point: "main",
757            targets: vec![Some(wgpu::ColorTargetState {
758                format: self.format,
759                blend: None,
760                write_mask: wgpu::ColorWrites::ALL,
761            })],
762        }
763    }
764}