1use wgpu::*;
7
8use super::cubemap::CubemapTexture;
9use super::textures::ChannelTexture;
10
11pub fn create_bind_group_layout(device: &Device) -> BindGroupLayout {
29 device.create_bind_group_layout(&BindGroupLayoutDescriptor {
30 label: Some("Custom Shader Bind Group Layout"),
31 entries: &[
32 BindGroupLayoutEntry {
34 binding: 0,
35 visibility: ShaderStages::VERTEX | ShaderStages::FRAGMENT,
36 ty: BindingType::Buffer {
37 ty: BufferBindingType::Uniform,
38 has_dynamic_offset: false,
39 min_binding_size: None,
40 },
41 count: None,
42 },
43 BindGroupLayoutEntry {
45 binding: 1,
46 visibility: ShaderStages::FRAGMENT,
47 ty: BindingType::Texture {
48 sample_type: TextureSampleType::Float { filterable: true },
49 view_dimension: TextureViewDimension::D2,
50 multisampled: false,
51 },
52 count: None,
53 },
54 BindGroupLayoutEntry {
56 binding: 2,
57 visibility: ShaderStages::FRAGMENT,
58 ty: BindingType::Sampler(SamplerBindingType::Filtering),
59 count: None,
60 },
61 BindGroupLayoutEntry {
63 binding: 3,
64 visibility: ShaderStages::FRAGMENT,
65 ty: BindingType::Texture {
66 sample_type: TextureSampleType::Float { filterable: true },
67 view_dimension: TextureViewDimension::D2,
68 multisampled: false,
69 },
70 count: None,
71 },
72 BindGroupLayoutEntry {
74 binding: 4,
75 visibility: ShaderStages::FRAGMENT,
76 ty: BindingType::Sampler(SamplerBindingType::Filtering),
77 count: None,
78 },
79 BindGroupLayoutEntry {
81 binding: 5,
82 visibility: ShaderStages::FRAGMENT,
83 ty: BindingType::Texture {
84 sample_type: TextureSampleType::Float { filterable: true },
85 view_dimension: TextureViewDimension::D2,
86 multisampled: false,
87 },
88 count: None,
89 },
90 BindGroupLayoutEntry {
92 binding: 6,
93 visibility: ShaderStages::FRAGMENT,
94 ty: BindingType::Sampler(SamplerBindingType::Filtering),
95 count: None,
96 },
97 BindGroupLayoutEntry {
99 binding: 7,
100 visibility: ShaderStages::FRAGMENT,
101 ty: BindingType::Texture {
102 sample_type: TextureSampleType::Float { filterable: true },
103 view_dimension: TextureViewDimension::D2,
104 multisampled: false,
105 },
106 count: None,
107 },
108 BindGroupLayoutEntry {
110 binding: 8,
111 visibility: ShaderStages::FRAGMENT,
112 ty: BindingType::Sampler(SamplerBindingType::Filtering),
113 count: None,
114 },
115 BindGroupLayoutEntry {
117 binding: 9,
118 visibility: ShaderStages::FRAGMENT,
119 ty: BindingType::Texture {
120 sample_type: TextureSampleType::Float { filterable: true },
121 view_dimension: TextureViewDimension::D2,
122 multisampled: false,
123 },
124 count: None,
125 },
126 BindGroupLayoutEntry {
128 binding: 10,
129 visibility: ShaderStages::FRAGMENT,
130 ty: BindingType::Sampler(SamplerBindingType::Filtering),
131 count: None,
132 },
133 BindGroupLayoutEntry {
135 binding: 11,
136 visibility: ShaderStages::FRAGMENT,
137 ty: BindingType::Texture {
138 sample_type: TextureSampleType::Float { filterable: true },
139 view_dimension: TextureViewDimension::Cube,
140 multisampled: false,
141 },
142 count: None,
143 },
144 BindGroupLayoutEntry {
146 binding: 12,
147 visibility: ShaderStages::FRAGMENT,
148 ty: BindingType::Sampler(SamplerBindingType::Filtering),
149 count: None,
150 },
151 BindGroupLayoutEntry {
153 binding: 13,
154 visibility: ShaderStages::FRAGMENT,
155 ty: BindingType::Buffer {
156 ty: BufferBindingType::Uniform,
157 has_dynamic_offset: false,
158 min_binding_size: None,
159 },
160 count: None,
161 },
162 ],
163 })
164}
165
166pub struct BindGroupInputs<'a> {
168 pub layout: &'a BindGroupLayout,
170 pub uniform_buffer: &'a Buffer,
172 pub intermediate_texture_view: &'a TextureView,
174 pub custom_uniform_buffer: &'a Buffer,
176 pub sampler: &'a Sampler,
178 pub channel_textures: &'a [ChannelTexture; 4],
180 pub cubemap: &'a CubemapTexture,
182}
183
184pub fn create_bind_group(device: &Device, inputs: BindGroupInputs<'_>) -> BindGroup {
186 let BindGroupInputs {
187 layout,
188 uniform_buffer,
189 intermediate_texture_view,
190 custom_uniform_buffer,
191 sampler,
192 channel_textures,
193 cubemap,
194 } = inputs;
195
196 device.create_bind_group(&BindGroupDescriptor {
197 label: Some("Custom Shader Bind Group"),
198 layout,
199 entries: &[
200 BindGroupEntry {
201 binding: 0,
202 resource: uniform_buffer.as_entire_binding(),
203 },
204 BindGroupEntry {
206 binding: 1,
207 resource: BindingResource::TextureView(&channel_textures[0].view),
208 },
209 BindGroupEntry {
210 binding: 2,
211 resource: BindingResource::Sampler(&channel_textures[0].sampler),
212 },
213 BindGroupEntry {
215 binding: 3,
216 resource: BindingResource::TextureView(&channel_textures[1].view),
217 },
218 BindGroupEntry {
219 binding: 4,
220 resource: BindingResource::Sampler(&channel_textures[1].sampler),
221 },
222 BindGroupEntry {
224 binding: 5,
225 resource: BindingResource::TextureView(&channel_textures[2].view),
226 },
227 BindGroupEntry {
228 binding: 6,
229 resource: BindingResource::Sampler(&channel_textures[2].sampler),
230 },
231 BindGroupEntry {
233 binding: 7,
234 resource: BindingResource::TextureView(&channel_textures[3].view),
235 },
236 BindGroupEntry {
237 binding: 8,
238 resource: BindingResource::Sampler(&channel_textures[3].sampler),
239 },
240 BindGroupEntry {
242 binding: 9,
243 resource: BindingResource::TextureView(intermediate_texture_view),
244 },
245 BindGroupEntry {
246 binding: 10,
247 resource: BindingResource::Sampler(sampler),
248 },
249 BindGroupEntry {
251 binding: 11,
252 resource: BindingResource::TextureView(&cubemap.view),
253 },
254 BindGroupEntry {
255 binding: 12,
256 resource: BindingResource::Sampler(&cubemap.sampler),
257 },
258 BindGroupEntry {
260 binding: 13,
261 resource: custom_uniform_buffer.as_entire_binding(),
262 },
263 ],
264 })
265}
266
267pub fn create_render_pipeline(
276 device: &Device,
277 shader_module: &ShaderModule,
278 bind_group_layout: &BindGroupLayout,
279 surface_format: TextureFormat,
280 label: Option<&str>,
281) -> RenderPipeline {
282 let pipeline_layout = device.create_pipeline_layout(&PipelineLayoutDescriptor {
283 label: Some(label.unwrap_or("Custom Shader Pipeline Layout")),
284 bind_group_layouts: &[Some(bind_group_layout)],
285 immediate_size: 0,
286 });
287
288 device.create_render_pipeline(&RenderPipelineDescriptor {
289 label: Some(label.unwrap_or("Custom Shader Pipeline")),
290 layout: Some(&pipeline_layout),
291 vertex: VertexState {
292 module: shader_module,
293 entry_point: Some("vs_main"),
294 buffers: &[],
295 compilation_options: Default::default(),
296 },
297 fragment: Some(FragmentState {
298 module: shader_module,
299 entry_point: Some("fs_main"),
300 targets: &[Some(ColorTargetState {
301 format: surface_format,
302 blend: Some(BlendState::PREMULTIPLIED_ALPHA_BLENDING),
304 write_mask: ColorWrites::ALL,
305 })],
306 compilation_options: Default::default(),
307 }),
308 primitive: PrimitiveState {
309 topology: PrimitiveTopology::TriangleStrip,
310 ..Default::default()
311 },
312 depth_stencil: None,
313 multisample: MultisampleState::default(),
314 cache: None,
315 multiview_mask: None,
316 })
317}