veloren_voxygen/render/pipelines/
clouds.rs1use 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 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 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 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 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: "main",
180 buffers: &[],
181 },
182 primitive: wgpu::PrimitiveState {
183 topology: wgpu::PrimitiveTopology::TriangleList,
184 strip_index_format: None,
185 front_face: wgpu::FrontFace::Ccw,
186 cull_mode: None,
187 unclipped_depth: false,
188 polygon_mode: wgpu::PolygonMode::Fill,
189 conservative: false,
190 },
191 depth_stencil: None,
192 multisample: wgpu::MultisampleState {
193 count: samples,
194 mask: !0,
195 alpha_to_coverage_enabled: false,
196 },
197 fragment: Some(wgpu::FragmentState {
198 module: fs_module,
199 entry_point: "main",
200 targets: &[Some(wgpu::ColorTargetState {
201 format,
202 blend: None,
203 write_mask: wgpu::ColorWrites::ALL,
204 })],
205 }),
206 multiview: None,
207 });
208
209 Self {
210 pipeline: render_pipeline,
211 }
212 }
213}