1use std::num::NonZeroU64;
9
10use super::super::RenderEngine;
11
12impl RenderEngine {
13 pub(crate) fn create_shadow_pipeline(&mut self) {
15 let shader_source = include_str!("../../shaders/shadow_map.wgsl");
16 let shader = self
17 .device
18 .create_shader_module(wgpu::ShaderModuleDescriptor {
19 label: Some("Shadow Map Shader"),
20 source: wgpu::ShaderSource::Wgsl(shader_source.into()),
21 });
22
23 let bind_group_layout =
28 self.device
29 .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
30 label: Some("Shadow Bind Group Layout"),
31 entries: &[
32 wgpu::BindGroupLayoutEntry {
34 binding: 0,
35 visibility: wgpu::ShaderStages::VERTEX,
36 ty: wgpu::BindingType::Buffer {
37 ty: wgpu::BufferBindingType::Uniform,
38 has_dynamic_offset: false,
39 min_binding_size: NonZeroU64::new(80),
40 },
41 count: None,
42 },
43 wgpu::BindGroupLayoutEntry {
45 binding: 1,
46 visibility: wgpu::ShaderStages::VERTEX,
47 ty: wgpu::BindingType::Buffer {
48 ty: wgpu::BufferBindingType::Uniform,
49 has_dynamic_offset: false,
50 min_binding_size: NonZeroU64::new(64),
51 },
52 count: None,
53 },
54 wgpu::BindGroupLayoutEntry {
56 binding: 2,
57 visibility: wgpu::ShaderStages::VERTEX,
58 ty: wgpu::BindingType::Buffer {
59 ty: wgpu::BufferBindingType::Storage { read_only: true },
60 has_dynamic_offset: false,
61 min_binding_size: None,
62 },
63 count: None,
64 },
65 ],
66 });
67
68 let pipeline_layout = self
69 .device
70 .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
71 label: Some("Shadow Pipeline Layout"),
72 bind_group_layouts: &[&bind_group_layout],
73 push_constant_ranges: &[],
74 });
75
76 let pipeline = self
77 .device
78 .create_render_pipeline(&wgpu::RenderPipelineDescriptor {
79 label: Some("Shadow Render Pipeline"),
80 layout: Some(&pipeline_layout),
81 vertex: wgpu::VertexState {
82 module: &shader,
83 entry_point: Some("vs_main"),
84 buffers: &[],
85 compilation_options: wgpu::PipelineCompilationOptions::default(),
86 },
87 fragment: Some(wgpu::FragmentState {
88 module: &shader,
89 entry_point: Some("fs_main"),
90 targets: &[], compilation_options: wgpu::PipelineCompilationOptions::default(),
92 }),
93 primitive: wgpu::PrimitiveState {
94 topology: wgpu::PrimitiveTopology::TriangleList,
95 strip_index_format: None,
96 front_face: wgpu::FrontFace::Ccw,
97 cull_mode: Some(wgpu::Face::Back),
98 ..wgpu::PrimitiveState::default()
99 },
100 depth_stencil: Some(wgpu::DepthStencilState {
101 format: wgpu::TextureFormat::Depth32Float,
103 depth_write_enabled: true,
104 depth_compare: wgpu::CompareFunction::Less,
105 stencil: wgpu::StencilState::default(),
106 bias: wgpu::DepthBiasState {
107 constant: 2, slope_scale: 2.0,
109 clamp: 0.0,
110 },
111 }),
112 multisample: wgpu::MultisampleState::default(), multiview: None,
114 cache: None,
115 });
116
117 self.shadow_pipeline = Some(pipeline);
118 self.shadow_bind_group_layout = Some(bind_group_layout);
119 }
120
121 pub fn shadow_pipeline(&self) -> Option<&wgpu::RenderPipeline> {
123 self.shadow_pipeline.as_ref()
124 }
125
126 pub fn shadow_bind_group_layout(&self) -> Option<&wgpu::BindGroupLayout> {
128 self.shadow_bind_group_layout.as_ref()
129 }
130
131 pub(crate) fn create_ground_stencil_pipeline(&mut self) {
133 let shader = self
134 .device
135 .create_shader_module(wgpu::ShaderModuleDescriptor {
136 label: Some("Ground Stencil Shader"),
137 source: wgpu::ShaderSource::Wgsl(
138 include_str!("../../shaders/ground_stencil.wgsl").into(),
139 ),
140 });
141
142 let pipeline_layout = self
144 .device
145 .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
146 label: Some("Ground Stencil Pipeline Layout"),
147 bind_group_layouts: &[&self.ground_plane_bind_group_layout],
148 push_constant_ranges: &[],
149 });
150
151 self.ground_stencil_pipeline = Some(self.device.create_render_pipeline(
152 &wgpu::RenderPipelineDescriptor {
153 label: Some("Ground Stencil Pipeline"),
154 layout: Some(&pipeline_layout),
155 vertex: wgpu::VertexState {
156 module: &shader,
157 entry_point: Some("vs_main"),
158 buffers: &[],
159 compilation_options: wgpu::PipelineCompilationOptions::default(),
160 },
161 fragment: Some(wgpu::FragmentState {
162 module: &shader,
163 entry_point: Some("fs_main"),
164 targets: &[Some(wgpu::ColorTargetState {
165 format: wgpu::TextureFormat::Rgba16Float,
166 blend: None,
167 write_mask: wgpu::ColorWrites::empty(), })],
169 compilation_options: wgpu::PipelineCompilationOptions::default(),
170 }),
171 primitive: wgpu::PrimitiveState {
172 topology: wgpu::PrimitiveTopology::TriangleList,
173 ..wgpu::PrimitiveState::default()
174 },
175 depth_stencil: Some(wgpu::DepthStencilState {
176 format: wgpu::TextureFormat::Depth24PlusStencil8,
177 depth_write_enabled: false, depth_compare: wgpu::CompareFunction::Always,
179 stencil: wgpu::StencilState {
180 front: wgpu::StencilFaceState {
181 compare: wgpu::CompareFunction::Always,
182 fail_op: wgpu::StencilOperation::Keep,
183 depth_fail_op: wgpu::StencilOperation::Keep,
184 pass_op: wgpu::StencilOperation::Replace, },
186 back: wgpu::StencilFaceState {
187 compare: wgpu::CompareFunction::Always,
188 fail_op: wgpu::StencilOperation::Keep,
189 depth_fail_op: wgpu::StencilOperation::Keep,
190 pass_op: wgpu::StencilOperation::Replace,
191 },
192 read_mask: 0xFF,
193 write_mask: 0xFF,
194 },
195 bias: wgpu::DepthBiasState::default(),
196 }),
197 multisample: wgpu::MultisampleState::default(),
198 multiview: None,
199 cache: None,
200 },
201 ));
202 }
203
204 pub(crate) fn create_reflected_mesh_pipeline(&mut self) {
206 let shader = self
207 .device
208 .create_shader_module(wgpu::ShaderModuleDescriptor {
209 label: Some("Reflected Mesh Shader"),
210 source: wgpu::ShaderSource::Wgsl(
211 include_str!("../../shaders/reflected_mesh.wgsl").into(),
212 ),
213 });
214
215 let Some(reflection_pass) = &self.reflection_pass else {
218 return;
219 };
220
221 let mesh_bind_group_layout =
223 self.device
224 .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
225 label: Some("Reflected Mesh Bind Group Layout 0"),
226 entries: &[
227 wgpu::BindGroupLayoutEntry {
229 binding: 0,
230 visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
231 ty: wgpu::BindingType::Buffer {
232 ty: wgpu::BufferBindingType::Uniform,
233 has_dynamic_offset: false,
234 min_binding_size: NonZeroU64::new(272),
235 },
236 count: None,
237 },
238 wgpu::BindGroupLayoutEntry {
240 binding: 1,
241 visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
242 ty: wgpu::BindingType::Buffer {
243 ty: wgpu::BufferBindingType::Uniform,
244 has_dynamic_offset: false,
245 min_binding_size: NonZeroU64::new(160),
246 },
247 count: None,
248 },
249 wgpu::BindGroupLayoutEntry {
251 binding: 2,
252 visibility: wgpu::ShaderStages::VERTEX,
253 ty: wgpu::BindingType::Buffer {
254 ty: wgpu::BufferBindingType::Storage { read_only: true },
255 has_dynamic_offset: false,
256 min_binding_size: None,
257 },
258 count: None,
259 },
260 wgpu::BindGroupLayoutEntry {
262 binding: 3,
263 visibility: wgpu::ShaderStages::VERTEX,
264 ty: wgpu::BindingType::Buffer {
265 ty: wgpu::BufferBindingType::Storage { read_only: true },
266 has_dynamic_offset: false,
267 min_binding_size: None,
268 },
269 count: None,
270 },
271 wgpu::BindGroupLayoutEntry {
273 binding: 4,
274 visibility: wgpu::ShaderStages::VERTEX,
275 ty: wgpu::BindingType::Buffer {
276 ty: wgpu::BufferBindingType::Storage { read_only: true },
277 has_dynamic_offset: false,
278 min_binding_size: None,
279 },
280 count: None,
281 },
282 wgpu::BindGroupLayoutEntry {
284 binding: 5,
285 visibility: wgpu::ShaderStages::VERTEX,
286 ty: wgpu::BindingType::Buffer {
287 ty: wgpu::BufferBindingType::Storage { read_only: true },
288 has_dynamic_offset: false,
289 min_binding_size: None,
290 },
291 count: None,
292 },
293 wgpu::BindGroupLayoutEntry {
295 binding: 6,
296 visibility: wgpu::ShaderStages::VERTEX,
297 ty: wgpu::BindingType::Buffer {
298 ty: wgpu::BufferBindingType::Storage { read_only: true },
299 has_dynamic_offset: false,
300 min_binding_size: None,
301 },
302 count: None,
303 },
304 ],
305 });
306
307 let pipeline_layout = self
308 .device
309 .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
310 label: Some("Reflected Mesh Pipeline Layout"),
311 bind_group_layouts: &[
312 &mesh_bind_group_layout,
313 reflection_pass.bind_group_layout(),
314 &self.matcap_bind_group_layout,
315 &self.slice_plane_bind_group_layout,
316 ],
317 push_constant_ranges: &[],
318 });
319
320 self.reflected_mesh_pipeline = Some(self.device.create_render_pipeline(
321 &wgpu::RenderPipelineDescriptor {
322 label: Some("Reflected Mesh Pipeline"),
323 layout: Some(&pipeline_layout),
324 vertex: wgpu::VertexState {
325 module: &shader,
326 entry_point: Some("vs_main"),
327 buffers: &[],
328 compilation_options: wgpu::PipelineCompilationOptions::default(),
329 },
330 fragment: Some(wgpu::FragmentState {
331 module: &shader,
332 entry_point: Some("fs_main"),
333 targets: &[Some(wgpu::ColorTargetState {
334 format: wgpu::TextureFormat::Rgba16Float,
335 blend: Some(wgpu::BlendState {
336 color: wgpu::BlendComponent {
337 src_factor: wgpu::BlendFactor::SrcAlpha,
338 dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
339 operation: wgpu::BlendOperation::Add,
340 },
341 alpha: wgpu::BlendComponent {
342 src_factor: wgpu::BlendFactor::One,
343 dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
344 operation: wgpu::BlendOperation::Add,
345 },
346 }),
347 write_mask: wgpu::ColorWrites::ALL,
348 })],
349 compilation_options: wgpu::PipelineCompilationOptions::default(),
350 }),
351 primitive: wgpu::PrimitiveState {
352 topology: wgpu::PrimitiveTopology::TriangleList,
353 cull_mode: None, ..wgpu::PrimitiveState::default()
355 },
356 depth_stencil: Some(wgpu::DepthStencilState {
357 format: wgpu::TextureFormat::Depth24PlusStencil8,
358 depth_write_enabled: false, depth_compare: wgpu::CompareFunction::Always, stencil: wgpu::StencilState {
361 front: wgpu::StencilFaceState {
362 compare: wgpu::CompareFunction::Equal, fail_op: wgpu::StencilOperation::Keep,
364 depth_fail_op: wgpu::StencilOperation::Keep,
365 pass_op: wgpu::StencilOperation::Keep,
366 },
367 back: wgpu::StencilFaceState {
368 compare: wgpu::CompareFunction::Equal,
369 fail_op: wgpu::StencilOperation::Keep,
370 depth_fail_op: wgpu::StencilOperation::Keep,
371 pass_op: wgpu::StencilOperation::Keep,
372 },
373 read_mask: 0xFF,
374 write_mask: 0x00, },
376 bias: wgpu::DepthBiasState::default(),
377 }),
378 multisample: wgpu::MultisampleState::default(),
379 multiview: None,
380 cache: None,
381 },
382 ));
383
384 self.reflected_mesh_bind_group_layout = Some(mesh_bind_group_layout);
385 }
386
387 pub(crate) fn create_reflected_point_cloud_pipeline(&mut self) {
388 let shader = self
389 .device
390 .create_shader_module(wgpu::ShaderModuleDescriptor {
391 label: Some("Reflected Point Cloud Shader"),
392 source: wgpu::ShaderSource::Wgsl(
393 include_str!("../../shaders/reflected_point_sphere.wgsl").into(),
394 ),
395 });
396
397 let Some(reflection_pass) = &self.reflection_pass else {
398 return;
399 };
400
401 let point_bind_group_layout =
403 self.device
404 .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
405 label: Some("Reflected Point Cloud Bind Group Layout 0"),
406 entries: &[
407 wgpu::BindGroupLayoutEntry {
409 binding: 0,
410 visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
411 ty: wgpu::BindingType::Buffer {
412 ty: wgpu::BufferBindingType::Uniform,
413 has_dynamic_offset: false,
414 min_binding_size: NonZeroU64::new(272),
415 },
416 count: None,
417 },
418 wgpu::BindGroupLayoutEntry {
420 binding: 1,
421 visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
422 ty: wgpu::BindingType::Buffer {
423 ty: wgpu::BufferBindingType::Uniform,
424 has_dynamic_offset: false,
425 min_binding_size: NonZeroU64::new(96),
426 },
427 count: None,
428 },
429 wgpu::BindGroupLayoutEntry {
431 binding: 2,
432 visibility: wgpu::ShaderStages::VERTEX,
433 ty: wgpu::BindingType::Buffer {
434 ty: wgpu::BufferBindingType::Storage { read_only: true },
435 has_dynamic_offset: false,
436 min_binding_size: None,
437 },
438 count: None,
439 },
440 wgpu::BindGroupLayoutEntry {
442 binding: 3,
443 visibility: wgpu::ShaderStages::VERTEX,
444 ty: wgpu::BindingType::Buffer {
445 ty: wgpu::BufferBindingType::Storage { read_only: true },
446 has_dynamic_offset: false,
447 min_binding_size: None,
448 },
449 count: None,
450 },
451 ],
452 });
453
454 let pipeline_layout = self
455 .device
456 .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
457 label: Some("Reflected Point Cloud Pipeline Layout"),
458 bind_group_layouts: &[
459 &point_bind_group_layout,
460 reflection_pass.bind_group_layout(),
461 &self.matcap_bind_group_layout,
462 &self.slice_plane_bind_group_layout,
463 ],
464 push_constant_ranges: &[],
465 });
466
467 self.reflected_point_cloud_pipeline = Some(self.device.create_render_pipeline(
468 &wgpu::RenderPipelineDescriptor {
469 label: Some("Reflected Point Cloud Pipeline"),
470 layout: Some(&pipeline_layout),
471 vertex: wgpu::VertexState {
472 module: &shader,
473 entry_point: Some("vs_main"),
474 buffers: &[],
475 compilation_options: wgpu::PipelineCompilationOptions::default(),
476 },
477 fragment: Some(wgpu::FragmentState {
478 module: &shader,
479 entry_point: Some("fs_main"),
480 targets: &[Some(wgpu::ColorTargetState {
481 format: wgpu::TextureFormat::Rgba16Float,
482 blend: Some(wgpu::BlendState {
483 color: wgpu::BlendComponent {
484 src_factor: wgpu::BlendFactor::SrcAlpha,
485 dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
486 operation: wgpu::BlendOperation::Add,
487 },
488 alpha: wgpu::BlendComponent {
489 src_factor: wgpu::BlendFactor::One,
490 dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
491 operation: wgpu::BlendOperation::Add,
492 },
493 }),
494 write_mask: wgpu::ColorWrites::ALL,
495 })],
496 compilation_options: wgpu::PipelineCompilationOptions::default(),
497 }),
498 primitive: wgpu::PrimitiveState {
499 topology: wgpu::PrimitiveTopology::TriangleList,
500 ..wgpu::PrimitiveState::default()
501 },
502 depth_stencil: Some(wgpu::DepthStencilState {
503 format: wgpu::TextureFormat::Depth24PlusStencil8,
504 depth_write_enabled: false,
505 depth_compare: wgpu::CompareFunction::Always,
506 stencil: wgpu::StencilState {
507 front: wgpu::StencilFaceState {
508 compare: wgpu::CompareFunction::Equal,
509 fail_op: wgpu::StencilOperation::Keep,
510 depth_fail_op: wgpu::StencilOperation::Keep,
511 pass_op: wgpu::StencilOperation::Keep,
512 },
513 back: wgpu::StencilFaceState {
514 compare: wgpu::CompareFunction::Equal,
515 fail_op: wgpu::StencilOperation::Keep,
516 depth_fail_op: wgpu::StencilOperation::Keep,
517 pass_op: wgpu::StencilOperation::Keep,
518 },
519 read_mask: 0xFF,
520 write_mask: 0x00,
521 },
522 bias: wgpu::DepthBiasState::default(),
523 }),
524 multisample: wgpu::MultisampleState::default(),
525 multiview: None,
526 cache: None,
527 },
528 ));
529
530 self.reflected_point_cloud_bind_group_layout = Some(point_bind_group_layout);
531 }
532
533 pub(crate) fn create_reflected_curve_network_pipeline(&mut self) {
534 let shader = self
535 .device
536 .create_shader_module(wgpu::ShaderModuleDescriptor {
537 label: Some("Reflected Curve Network Shader"),
538 source: wgpu::ShaderSource::Wgsl(
539 include_str!("../../shaders/reflected_curve_network_tube.wgsl").into(),
540 ),
541 });
542
543 let Some(reflection_pass) = &self.reflection_pass else {
544 return;
545 };
546
547 let curve_bind_group_layout =
549 self.device
550 .create_bind_group_layout(&wgpu::BindGroupLayoutDescriptor {
551 label: Some("Reflected Curve Network Bind Group Layout 0"),
552 entries: &[
553 wgpu::BindGroupLayoutEntry {
555 binding: 0,
556 visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
557 ty: wgpu::BindingType::Buffer {
558 ty: wgpu::BufferBindingType::Uniform,
559 has_dynamic_offset: false,
560 min_binding_size: NonZeroU64::new(272),
561 },
562 count: None,
563 },
564 wgpu::BindGroupLayoutEntry {
566 binding: 1,
567 visibility: wgpu::ShaderStages::VERTEX | wgpu::ShaderStages::FRAGMENT,
568 ty: wgpu::BindingType::Buffer {
569 ty: wgpu::BufferBindingType::Uniform,
570 has_dynamic_offset: false,
571 min_binding_size: NonZeroU64::new(32),
572 },
573 count: None,
574 },
575 wgpu::BindGroupLayoutEntry {
577 binding: 2,
578 visibility: wgpu::ShaderStages::FRAGMENT,
579 ty: wgpu::BindingType::Buffer {
580 ty: wgpu::BufferBindingType::Storage { read_only: true },
581 has_dynamic_offset: false,
582 min_binding_size: None,
583 },
584 count: None,
585 },
586 wgpu::BindGroupLayoutEntry {
588 binding: 3,
589 visibility: wgpu::ShaderStages::FRAGMENT,
590 ty: wgpu::BindingType::Buffer {
591 ty: wgpu::BufferBindingType::Storage { read_only: true },
592 has_dynamic_offset: false,
593 min_binding_size: None,
594 },
595 count: None,
596 },
597 ],
598 });
599
600 let pipeline_layout = self
601 .device
602 .create_pipeline_layout(&wgpu::PipelineLayoutDescriptor {
603 label: Some("Reflected Curve Network Pipeline Layout"),
604 bind_group_layouts: &[
605 &curve_bind_group_layout,
606 reflection_pass.bind_group_layout(),
607 &self.matcap_bind_group_layout,
608 &self.slice_plane_bind_group_layout,
609 ],
610 push_constant_ranges: &[],
611 });
612
613 let vertex_buffer_layout = wgpu::VertexBufferLayout {
615 array_stride: std::mem::size_of::<[f32; 8]>() as wgpu::BufferAddress,
616 step_mode: wgpu::VertexStepMode::Vertex,
617 attributes: &[
618 wgpu::VertexAttribute {
620 format: wgpu::VertexFormat::Float32x4,
621 offset: 0,
622 shader_location: 0,
623 },
624 wgpu::VertexAttribute {
626 format: wgpu::VertexFormat::Uint32x4,
627 offset: 16,
628 shader_location: 1,
629 },
630 ],
631 };
632
633 self.reflected_curve_network_pipeline = Some(self.device.create_render_pipeline(
634 &wgpu::RenderPipelineDescriptor {
635 label: Some("Reflected Curve Network Pipeline"),
636 layout: Some(&pipeline_layout),
637 vertex: wgpu::VertexState {
638 module: &shader,
639 entry_point: Some("vs_main"),
640 buffers: &[vertex_buffer_layout],
641 compilation_options: wgpu::PipelineCompilationOptions::default(),
642 },
643 fragment: Some(wgpu::FragmentState {
644 module: &shader,
645 entry_point: Some("fs_main"),
646 targets: &[Some(wgpu::ColorTargetState {
647 format: wgpu::TextureFormat::Rgba16Float,
648 blend: Some(wgpu::BlendState {
649 color: wgpu::BlendComponent {
650 src_factor: wgpu::BlendFactor::SrcAlpha,
651 dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
652 operation: wgpu::BlendOperation::Add,
653 },
654 alpha: wgpu::BlendComponent {
655 src_factor: wgpu::BlendFactor::One,
656 dst_factor: wgpu::BlendFactor::OneMinusSrcAlpha,
657 operation: wgpu::BlendOperation::Add,
658 },
659 }),
660 write_mask: wgpu::ColorWrites::ALL,
661 })],
662 compilation_options: wgpu::PipelineCompilationOptions::default(),
663 }),
664 primitive: wgpu::PrimitiveState {
665 topology: wgpu::PrimitiveTopology::TriangleList,
666 cull_mode: None, ..wgpu::PrimitiveState::default()
668 },
669 depth_stencil: Some(wgpu::DepthStencilState {
670 format: wgpu::TextureFormat::Depth24PlusStencil8,
671 depth_write_enabled: false, depth_compare: wgpu::CompareFunction::Always, stencil: wgpu::StencilState {
674 front: wgpu::StencilFaceState {
675 compare: wgpu::CompareFunction::Equal,
676 fail_op: wgpu::StencilOperation::Keep,
677 depth_fail_op: wgpu::StencilOperation::Keep,
678 pass_op: wgpu::StencilOperation::Keep,
679 },
680 back: wgpu::StencilFaceState {
681 compare: wgpu::CompareFunction::Equal,
682 fail_op: wgpu::StencilOperation::Keep,
683 depth_fail_op: wgpu::StencilOperation::Keep,
684 pass_op: wgpu::StencilOperation::Keep,
685 },
686 read_mask: 0xFF,
687 write_mask: 0x00,
688 },
689 bias: wgpu::DepthBiasState::default(),
690 }),
691 multisample: wgpu::MultisampleState::default(),
692 multiview: None,
693 cache: None,
694 },
695 ));
696
697 self.reflected_curve_network_bind_group_layout = Some(curve_bind_group_layout);
698 }
699}