veloren_voxygen/render/pipelines/
rain_occlusion.rs1use super::super::{
2 AaMode, Bound, Consts, FigureLayout, GlobalsLayouts, TerrainLayout, TerrainVertex,
3};
4use bytemuck::{Pod, Zeroable};
5use vek::*;
6
7#[repr(C)]
8#[derive(Copy, Clone, Debug, Zeroable, Pod, Default)]
9pub struct Locals {
10 rain_occlusion_matrices: [[f32; 4]; 4],
11 rain_occlusion_texture_mat: [[f32; 4]; 4],
12 rain_dir_mat: [[f32; 4]; 4],
15 integrated_rain_vel: f32,
17 rain_density: f32,
18 occlusion_dummy: [f32; 2],
20}
21const _: () = assert!(core::mem::size_of::<Locals>() % 16 == 0);
23
24impl Locals {
25 pub fn new(
26 rain_occlusion_matrices: Mat4<f32>,
27 rain_occlusion_texture_mat: Mat4<f32>,
28 rain_dir_mat: Mat4<f32>,
29 rain_density: f32,
30 integrated_rain_vel: f32,
31 ) -> Self {
32 Self {
33 rain_occlusion_matrices: rain_occlusion_matrices.into_col_arrays(),
34 rain_occlusion_texture_mat: rain_occlusion_texture_mat.into_col_arrays(),
35 rain_dir_mat: rain_dir_mat.into_col_arrays(),
36 integrated_rain_vel,
37 rain_density,
38 occlusion_dummy: [0.0; 2],
39 }
40 }
41}
42
43pub type BoundLocals = Bound<Consts<Locals>>;
44
45pub struct RainOcclusionLayout {
46 pub locals: wgpu::BindGroupLayout,
47}
48
49impl RainOcclusionLayout {
50 pub fn new(device: &wgpu::Device) -> Self {
51 Self {
52 locals: device.create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
53 label: None,
54 entries: &[wgpu::BindGroupLayoutEntry {
55 binding: 0,
56 visibility: wgpu::ShaderStages::VERTEX_FRAGMENT,
57 ty: wgpu::BindingType::Buffer {
58 ty: wgpu::BufferBindingType::Uniform,
59 has_dynamic_offset: false,
60 min_binding_size: None,
61 },
62 count: None,
63 }],
64 }),
65 }
66 }
67
68 pub fn bind_locals(&self, device: &wgpu::Device, locals: Consts<Locals>) -> BoundLocals {
69 let bind_group = device.create_bind_group(&wgpu::BindGroupDescriptor {
70 label: None,
71 layout: &self.locals,
72 entries: &[wgpu::BindGroupEntry {
73 binding: 0,
74 resource: locals.buf().as_entire_binding(),
75 }],
76 });
77
78 BoundLocals {
79 bind_group,
80 with: locals,
81 }
82 }
83}
84
85pub struct RainOcclusionFigurePipeline {
86 pub pipeline: wgpu::RenderPipeline,
87}
88
89impl RainOcclusionFigurePipeline {
90 pub fn new(
91 device: &wgpu::Device,
92 vs_module: &wgpu::ShaderModule,
93 global_layout: &GlobalsLayouts,
94 figure_layout: &FigureLayout,
95 aa_mode: AaMode,
96 ) -> Self {
97 common_base::span!(_guard, "new");
98
99 let render_pipeline_layout =
100 device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
101 label: Some("Rain occlusion figure pipeline layout"),
102 push_constant_ranges: &[],
103 bind_group_layouts: &[&global_layout.globals, &figure_layout.locals],
104 });
105
106 let samples = aa_mode.samples();
107
108 let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
109 label: Some("Rain occlusion figure pipeline"),
110 layout: Some(&render_pipeline_layout),
111 vertex: wgpu::VertexState {
112 module: vs_module,
113 entry_point: Some("main"),
114 buffers: &[TerrainVertex::desc()],
115 compilation_options: Default::default(),
116 },
117 primitive: wgpu::PrimitiveState {
118 topology: wgpu::PrimitiveTopology::TriangleList,
119 strip_index_format: None,
120 front_face: wgpu::FrontFace::Ccw,
121 cull_mode: Some(wgpu::Face::Back),
122 unclipped_depth: true,
123 polygon_mode: wgpu::PolygonMode::Fill,
124 conservative: false,
125 },
126 depth_stencil: Some(wgpu::DepthStencilState {
127 format: wgpu::TextureFormat::Depth24Plus,
128 depth_write_enabled: true,
129 depth_compare: wgpu::CompareFunction::Less,
130 stencil: wgpu::StencilState {
131 front: wgpu::StencilFaceState::IGNORE,
132 back: wgpu::StencilFaceState::IGNORE,
133 read_mask: 0,
134 write_mask: 0,
135 },
136 bias: wgpu::DepthBiasState {
137 constant: 0,
138 slope_scale: 0.0,
139 clamp: 0.0,
140 },
141 }),
142 multisample: wgpu::MultisampleState {
143 count: samples,
144 mask: !0,
145 alpha_to_coverage_enabled: false,
146 },
147 fragment: None,
148 multiview: None,
149 cache: None,
150 });
151
152 Self {
153 pipeline: render_pipeline,
154 }
155 }
156}
157
158pub struct RainOcclusionPipeline {
159 pub pipeline: wgpu::RenderPipeline,
160}
161
162impl RainOcclusionPipeline {
163 pub fn new(
164 device: &wgpu::Device,
165 vs_module: &wgpu::ShaderModule,
166 global_layout: &GlobalsLayouts,
167 terrain_layout: &TerrainLayout,
168 aa_mode: AaMode,
169 ) -> Self {
170 let render_pipeline_layout =
171 device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
172 label: Some("Rain occlusion pipeline layout"),
173 push_constant_ranges: &[],
174 bind_group_layouts: &[&global_layout.globals, &terrain_layout.locals],
175 });
176
177 let samples = aa_mode.samples();
178
179 let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
180 label: Some("Rain occlusion pipeline"),
181 layout: Some(&render_pipeline_layout),
182 vertex: wgpu::VertexState {
183 module: vs_module,
184 entry_point: Some("main"),
185 buffers: &[TerrainVertex::desc()],
186 compilation_options: Default::default(),
187 },
188 primitive: wgpu::PrimitiveState {
189 topology: wgpu::PrimitiveTopology::TriangleList,
190 strip_index_format: None,
191 front_face: wgpu::FrontFace::Ccw,
192 cull_mode: None,
193 unclipped_depth: true,
194 polygon_mode: wgpu::PolygonMode::Fill,
195 conservative: false,
196 },
197 depth_stencil: Some(wgpu::DepthStencilState {
198 format: wgpu::TextureFormat::Depth24Plus,
199 depth_write_enabled: true,
200 depth_compare: wgpu::CompareFunction::Less,
201 stencil: wgpu::StencilState {
202 front: wgpu::StencilFaceState::IGNORE,
203 back: wgpu::StencilFaceState::IGNORE,
204 read_mask: 0,
205 write_mask: 0,
206 },
207 bias: wgpu::DepthBiasState {
208 constant: 0,
209 slope_scale: 0.0,
210 clamp: 0.0,
211 },
212 }),
213 multisample: wgpu::MultisampleState {
214 count: samples,
215 mask: !0,
216 alpha_to_coverage_enabled: false,
217 },
218 fragment: None,
219 multiview: None,
220 cache: None,
221 });
222
223 Self {
224 pipeline: render_pipeline,
225 }
226 }
227}