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: "main",
114 buffers: &[TerrainVertex::desc()],
115 },
116 primitive: wgpu::PrimitiveState {
117 topology: wgpu::PrimitiveTopology::TriangleList,
118 strip_index_format: None,
119 front_face: wgpu::FrontFace::Ccw,
120 cull_mode: Some(wgpu::Face::Back),
121 unclipped_depth: true,
122 polygon_mode: wgpu::PolygonMode::Fill,
123 conservative: false,
124 },
125 depth_stencil: Some(wgpu::DepthStencilState {
126 format: wgpu::TextureFormat::Depth24Plus,
127 depth_write_enabled: true,
128 depth_compare: wgpu::CompareFunction::Less,
129 stencil: wgpu::StencilState {
130 front: wgpu::StencilFaceState::IGNORE,
131 back: wgpu::StencilFaceState::IGNORE,
132 read_mask: 0,
133 write_mask: 0,
134 },
135 bias: wgpu::DepthBiasState {
136 constant: 0,
137 slope_scale: 0.0,
138 clamp: 0.0,
139 },
140 }),
141 multisample: wgpu::MultisampleState {
142 count: samples,
143 mask: !0,
144 alpha_to_coverage_enabled: false,
145 },
146 fragment: None,
147 multiview: None,
148 });
149
150 Self {
151 pipeline: render_pipeline,
152 }
153 }
154}
155
156pub struct RainOcclusionPipeline {
157 pub pipeline: wgpu::RenderPipeline,
158}
159
160impl RainOcclusionPipeline {
161 pub fn new(
162 device: &wgpu::Device,
163 vs_module: &wgpu::ShaderModule,
164 global_layout: &GlobalsLayouts,
165 terrain_layout: &TerrainLayout,
166 aa_mode: AaMode,
167 ) -> Self {
168 let render_pipeline_layout =
169 device.create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
170 label: Some("Rain occlusion pipeline layout"),
171 push_constant_ranges: &[],
172 bind_group_layouts: &[&global_layout.globals, &terrain_layout.locals],
173 });
174
175 let samples = aa_mode.samples();
176
177 let render_pipeline = device.create_render_pipeline(&wgpu::RenderPipelineDescriptor {
178 label: Some("Rain occlusion pipeline"),
179 layout: Some(&render_pipeline_layout),
180 vertex: wgpu::VertexState {
181 module: vs_module,
182 entry_point: "main",
183 buffers: &[TerrainVertex::desc()],
184 },
185 primitive: wgpu::PrimitiveState {
186 topology: wgpu::PrimitiveTopology::TriangleList,
187 strip_index_format: None,
188 front_face: wgpu::FrontFace::Ccw,
189 cull_mode: None,
190 unclipped_depth: true,
191 polygon_mode: wgpu::PolygonMode::Fill,
192 conservative: false,
193 },
194 depth_stencil: Some(wgpu::DepthStencilState {
195 format: wgpu::TextureFormat::Depth24Plus,
196 depth_write_enabled: true,
197 depth_compare: wgpu::CompareFunction::Less,
198 stencil: wgpu::StencilState {
199 front: wgpu::StencilFaceState::IGNORE,
200 back: wgpu::StencilFaceState::IGNORE,
201 read_mask: 0,
202 write_mask: 0,
203 },
204 bias: wgpu::DepthBiasState {
205 constant: 0,
206 slope_scale: 0.0,
207 clamp: 0.0,
208 },
209 }),
210 multisample: wgpu::MultisampleState {
211 count: samples,
212 mask: !0,
213 alpha_to_coverage_enabled: false,
214 },
215 fragment: None,
216 multiview: None,
217 });
218
219 Self {
220 pipeline: render_pipeline,
221 }
222 }
223}