gloss_renderer/forward_renderer/render_passes/
prepass.rs

1extern crate nalgebra as na;
2
3use crate::{
4    camera::Camera,
5    components::{
6        Colors, DiffuseTex, Edges, EnvironmentMapGpu, Faces, LightEmit, ModelMatrix, Name, NormalTex, Normals, Renderable, RoughnessTex,
7        ShadowCaster, ShadowMap, Tangents, UVs, Verts, VisLines, VisMesh, VisNormals, VisPoints, VisWireframe,
8    },
9    config::Config,
10    geom::{Geom, PerVertexNormalsWeightingType},
11    scene::Scene,
12};
13use easy_wgpu::{
14    gpu::Gpu,
15    texture::{TexParams, Texture},
16};
17use gloss_hecs::{Changed, CommandBuffer, Entity};
18use gloss_utils::{
19    bshare::{ToBurn, ToNalgebraFloat, ToNalgebraInt},
20    tensor::{DynamicTensorFloat2D, DynamicTensorInt2D, DynamicTensorOps},
21};
22use log::{debug, warn};
23/// Makes sure that the meshes are all with with correct components. Add model
24/// matrices to the ones that will be rendered and dummy textures so that we can
25/// use the same pipeline for all of them
26pub struct PrePass {
27    command_buffer: CommandBuffer, //defer insertions and deletion of scene entities for whenever we apply this command buffer
28}
29impl Default for PrePass {
30    fn default() -> Self {
31        Self::new()
32    }
33}
34impl PrePass {
35    pub fn new() -> Self {
36        let command_buffer = CommandBuffer::new();
37        Self { command_buffer }
38    }
39
40    pub fn add_auto_components(&mut self, gpu: &Gpu, scene: &mut Scene) {
41        //this adds a lot of components automatically if they are needed
42        self.add_model_matrix(scene);
43        self.add_vertex_normals(scene);
44        self.command_buffer.run_on(&mut scene.world); //run the command buffer so now all entities actually have Normals, this is
45                                                      // necessary so that the add_tangents correctly computes tangents for all
46                                                      // entities which have Verts,Faces,Normals and UVs
47        self.add_tangents(scene); //keep before adding dummy uvs so if we don't have uvs we just add some dumym
48                                  // tangents
49        self.add_dummy_uvs(scene);
50        self.add_dummy_colors(scene);
51
52        self.add_dummy_diffuse_tex(scene, gpu);
53        self.add_dummy_normal_tex(scene, gpu);
54        self.add_dummy_roughness_tex(scene, gpu);
55        self.add_dummy_environment_map(scene, gpu);
56
57        //auto vis options depending on the components
58        self.add_vis_lines(scene);
59        self.add_vis_wireframe(scene);
60        self.add_vis_normals(scene);
61        self.add_vis_points(scene);
62        self.add_vis_mesh(scene);
63        self.command_buffer.run_on(&mut scene.world); //in order to actually
64                                                      // create the model matrix
65                                                      // so that adding lights
66                                                      // works
67    }
68
69    pub fn run(
70        &mut self,
71        gpu: &Gpu,
72        camera: &mut Camera,
73        scene: &mut Scene,
74        // width: u32,
75        // height: u32,
76        config: &mut Config,
77    ) {
78        self.begin_pass();
79
80        //sanity checks
81        self.check_entity_names(scene); //checks that all entities have names
82
83        //automatic camera and lights only on first render
84
85        //this adds a lot of components automatically if they are needed
86        self.add_auto_components(gpu, scene);
87
88        //if we have objects in the scene, make the config objects that were set to
89        // auto, to a value that is concrete
90        if !config.is_concrete() && scene.nr_renderables() != 0 {
91            scene.make_concrete_config(config);
92        }
93        if config.is_concrete() && !config.is_consumed() {
94            let (width, height) = camera.get_target_res(scene);
95            scene.from_config(config, width, height);
96            self.add_auto_components(gpu, scene); //whatever we now added in
97                                                  // the scene like lights,etc
98                                                  // might also need auto
99                                                  // components
100        }
101
102        //add new objects the first time we render like the floor and lights
103        //requires that the objects already have model_matrix
104        // if scene.get_lights(false).is_empty() && scene.get_renderables(false).len()
105        // != 0 {     scene.add_auto_lights();
106        // }
107        self.add_shadow_maps(scene, gpu);
108
109        // if !scene.has_floor() && scene.get_renderables(false).len() != 0 {
110        //     scene.add_floor();
111        // }
112
113        // //setup camera
114        // if !scene.world.has::<PosLookat>(camera.entity).unwrap()
115        //     && scene.get_renderables(false).len() != 0
116        // {
117        //     self.set_auto_cam(camera, scene);
118        // }
119
120        self.end_pass_sanity_check(scene);
121
122        self.end_pass(scene);
123    }
124
125    fn begin_pass(&self) {}
126
127    fn end_pass(&mut self, scene: &mut Scene) {
128        self.command_buffer.run_on(&mut scene.world);
129    }
130
131    fn check_entity_names(&mut self, scene: &mut Scene) {
132        let mut query = scene.world.query::<()>().without::<&Name>();
133        for (_entity, _comp) in query.iter() {
134            warn!("Entity does not have a name, please assign name to all of them");
135        }
136    }
137
138    fn add_vis_lines(&mut self, scene: &mut Scene) {
139        let mut query = scene.world.query::<Option<&Faces>>().with::<(&Verts, &Edges)>().without::<&VisLines>();
140        for (entity, faces) in query.iter() {
141            //we automatically enable vis_lines if we don't have faces so we have only
142            // edges component
143            let show_lines = faces.is_none();
144
145            self.command_buffer.insert_one(
146                entity,
147                VisLines {
148                    added_automatically: true,
149                    show_lines,
150                    ..Default::default()
151                },
152            );
153        }
154    }
155
156    fn add_vis_wireframe(&mut self, scene: &mut Scene) {
157        let mut query = scene.world.query::<()>().with::<(&Verts, &Faces)>().without::<&VisWireframe>();
158        for (entity, _comp) in query.iter() {
159            self.command_buffer.insert_one(
160                entity,
161                VisWireframe {
162                    added_automatically: true,
163                    ..Default::default()
164                },
165            );
166        }
167    }
168
169    fn add_vis_normals(&mut self, scene: &mut Scene) {
170        let mut query = scene.world.query::<()>().with::<(&Verts, &Normals)>().without::<&VisNormals>();
171        for (entity, _comp) in query.iter() {
172            self.command_buffer.insert_one(
173                entity,
174                VisNormals {
175                    added_automatically: true,
176                    ..Default::default()
177                },
178            );
179        }
180    }
181
182    fn add_vis_points(&mut self, scene: &mut Scene) {
183        let mut query = scene
184            .world
185            .query::<(Option<&Faces>, Option<&Edges>)>()
186            .with::<&Verts>()
187            .without::<&VisPoints>();
188        for (entity, (faces, edges)) in query.iter() {
189            //we automatically enable vis_points if we don't have faces or edges component
190            // and we have only verts
191            let show_points = faces.is_none() && edges.is_none();
192
193            self.command_buffer.insert_one(
194                entity,
195                VisPoints {
196                    added_automatically: true,
197                    show_points,
198                    ..Default::default()
199                },
200            );
201        }
202    }
203
204    fn add_vis_mesh(&mut self, scene: &mut Scene) {
205        let mut query = scene.world.query::<()>().with::<(&Verts, &Faces)>().without::<&VisMesh>();
206        for (entity, _comp) in query.iter() {
207            self.command_buffer.insert_one(
208                entity,
209                VisMesh {
210                    added_automatically: true,
211                    ..Default::default()
212                },
213            );
214        }
215    }
216
217    fn add_model_matrix(&mut self, scene: &mut Scene) {
218        let mut query = scene.world.query::<()>().with::<&Renderable>().without::<&ModelMatrix>();
219        for (entity, _comp) in query.iter() {
220            self.command_buffer.insert_one(entity, ModelMatrix::default());
221        }
222    }
223
224    fn add_vertex_normals(&mut self, scene: &mut Scene) {
225        // We panic if prepass sees Wgpu backend tensors for now and if faces and verts
226        // are on different backends
227        let insert_normals = |entity: Entity, verts: &Verts, faces: &Faces, command_buffer: &mut CommandBuffer| {
228            match (&verts.0, &faces.0) {
229                // Handle both NdArray variants
230                (DynamicTensorFloat2D::NdArray(verts_tensor), DynamicTensorInt2D::NdArray(faces_tensor)) => {
231                    let normals = Geom::compute_per_vertex_normals(
232                        &verts_tensor.to_nalgebra(),
233                        &faces_tensor.to_nalgebra(),
234                        &PerVertexNormalsWeightingType::Area,
235                    );
236                    let normals_tensor = DynamicTensorFloat2D::NdArray(normals.into_burn(&verts_tensor.device()));
237                    command_buffer.insert_one(entity, Normals(normals_tensor));
238                }
239                // Let prepass support only NdArray since we dont really do any parallel computations
240                // Handle both Candle variants
241                (DynamicTensorFloat2D::Candle(verts_tensor), DynamicTensorInt2D::Candle(faces_tensor)) => {
242                    let normals = Geom::compute_per_vertex_normals_burn(verts_tensor, faces_tensor, &PerVertexNormalsWeightingType::Area);
243                    let normals_tensor = DynamicTensorFloat2D::Candle(normals);
244                    command_buffer.insert_one(entity, Normals(normals_tensor));
245                }
246                // Panic for unsupported Wgpu backend
247                (DynamicTensorFloat2D::Wgpu(_), _) | (_, DynamicTensorInt2D::Wgpu(_)) => {
248                    panic!("Wgpu backend is not supported for the prepass! Make sure normals are being added in smpl-rs");
249                }
250                // Handle mismatched backends (e.g., one is NdArray and the other is Candle)
251                _ => {
252                    panic!(
253                        "Mismatched backends between verts and faces tensors! Faces - {:?} Verts - {:?}",
254                        &verts.0, &faces.0
255                    );
256                }
257            }
258        };
259
260        //add normals to all entities that have verts and faces but don't have Normals
261        let mut query = scene.world.query::<(&Verts, &Faces)>().with::<&Renderable>().without::<&Normals>();
262        for (entity, (verts, faces)) in query.iter() {
263            insert_normals(entity, verts, faces, &mut self.command_buffer);
264        }
265
266        //also all the entities that have verts,faces AND normals but the normals don't
267        // correspond in size to the verts this can happen when we update a
268        // entity with a different Verts and Faces but don't update the Normals for some
269        // reason
270        let mut query = scene.world.query::<(&Verts, &Faces, &Normals)>().with::<&Renderable>();
271        for (entity, (verts, faces, normals)) in query.iter() {
272            if verts.0.nrows() != normals.0.nrows() {
273                insert_normals(entity, verts, faces, &mut self.command_buffer);
274            }
275        }
276    }
277    #[allow(clippy::too_many_lines)]
278    fn add_tangents(&mut self, scene: &mut Scene) {
279        let insert_tangents = |entity: Entity, verts: &Verts, faces: &Faces, normals: &Normals, uvs: &UVs, command_buffer: &mut CommandBuffer| {
280            match (&verts.0, &faces.0, &normals.0, &uvs.0) {
281                // Handle both NdArray and dynamic backends
282                (
283                    DynamicTensorFloat2D::NdArray(verts_tensor),
284                    DynamicTensorInt2D::NdArray(faces_tensor),
285                    DynamicTensorFloat2D::NdArray(normals_tensor),
286                    DynamicTensorFloat2D::NdArray(uvs_tensor),
287                ) => {
288                    // Compute tangents for NdArray backend
289                    let tangents = Geom::compute_tangents(
290                        &verts_tensor.to_nalgebra(),
291                        &faces_tensor.to_nalgebra(),
292                        &normals_tensor.to_nalgebra(),
293                        &uvs_tensor.to_nalgebra(),
294                    );
295                    let tangents_tensor = DynamicTensorFloat2D::NdArray(tangents.into_burn(&verts_tensor.device()));
296                    command_buffer.insert_one(entity, Tangents(tangents_tensor));
297                }
298                // Let prepass support only NdArray since we dont really do any parallel computations
299                // (
300                //     DynamicTensorFloat2D::Candle(verts_tensor),
301                //     DynamicTensorInt2D::Candle(faces_tensor),
302                //     DynamicTensorFloat2D::Candle(normals_tensor),
303                //     DynamicTensorFloat2D::Candle(uvs_tensor),
304                // ) => {
305                //     // Compute tangents for Candle backend
306                //     let tangents = Geom::compute_tangents_burn(
307                //         verts_tensor,
308                //         faces_tensor,
309                //         normals_tensor,
310                //         uvs_tensor,
311                //     );
312                //     let tangents_tensor = DynamicTensorFloat2D::Candle(tangents);
313                //     command_buffer.insert_one(entity, Tangents(tangents_tensor));
314                // }
315                _ => {
316                    panic!("Unsupported backend combination for tangents calculation!");
317                }
318            }
319        };
320
321        //all the entities that have verts, faces, normals and uvs but NO tangents
322        let mut query = scene
323            .world
324            .query::<(&Verts, &Faces, &Normals, &UVs)>()
325            .with::<&Renderable>()
326            .without::<&Tangents>();
327        for (entity, (verts, faces, normals, uvs)) in query.iter() {
328            insert_tangents(entity, verts, faces, normals, uvs, &mut self.command_buffer);
329        }
330
331        //also all the entities that have verts,faces, normals,uvs AND tangents but the
332        // tangents don't correspond in size to the verts this can happen when
333        // we update a entity with a different Verts and Faces but don't update the
334        // Tangents for some reason
335        let mut query = scene.world.query::<(&Verts, &Faces, &Normals, &UVs, &Tangents)>().with::<&Renderable>();
336        for (entity, (verts, faces, normals, uvs, tangents)) in query.iter() {
337            if verts.0.nrows() != tangents.0.nrows() {
338                insert_tangents(entity, verts, faces, normals, uvs, &mut self.command_buffer);
339            }
340        }
341
342        //if we don't have real uvs then we add dummy tangents and the next function
343        // will also just add dummy uvs
344        let mut query = scene.world.query::<(&Verts, &Faces)>().with::<&Renderable>().without::<&UVs>();
345        for (entity, (verts, _faces)) in query.iter() {
346            // Match the backend of verts
347            match &verts.0 {
348                DynamicTensorFloat2D::NdArray(verts_tensor) => {
349                    // Compute tangents using the NdArray backend
350                    let tangents = Geom::compute_dummy_tangents(verts_tensor.dims()[0], &verts_tensor.device());
351                    let tangents_tensor = DynamicTensorFloat2D::NdArray(tangents);
352                    self.command_buffer.insert_one(entity, Tangents(tangents_tensor));
353                }
354                DynamicTensorFloat2D::Candle(verts_tensor) => {
355                    // Compute tangents using the Candle backend
356                    let tangents = Geom::compute_dummy_tangents(verts_tensor.dims()[0], &verts_tensor.device());
357                    let tangents_tensor = DynamicTensorFloat2D::Candle(tangents);
358                    self.command_buffer.insert_one(entity, Tangents(tangents_tensor));
359                }
360                DynamicTensorFloat2D::Wgpu(verts_tensor) => {
361                    // Compute tangents using the Wgpu backend
362                    let tangents = Geom::compute_dummy_tangents(verts_tensor.dims()[0], &verts_tensor.device());
363                    let tangents_tensor = DynamicTensorFloat2D::Wgpu(tangents);
364                    self.command_buffer.insert_one(entity, Tangents(tangents_tensor));
365                }
366            }
367        }
368
369        // If we have verts, faces, NO uvs but we do have tangents, make sure the
370        // tangents have the same size as verts
371        let mut query = scene.world.query::<(&Verts, &Faces, &Tangents)>().with::<&Renderable>().without::<&UVs>();
372
373        for (entity, (verts, _faces, tangents)) in query.iter() {
374            if verts.0.nrows() != tangents.0.nrows() {
375                match &verts.0 {
376                    DynamicTensorFloat2D::NdArray(verts_tensor) => {
377                        // Compute tangents using the NdArray backend
378                        let tangents = Geom::compute_dummy_tangents(verts_tensor.dims()[0], &verts_tensor.device());
379                        let tangents_tensor = DynamicTensorFloat2D::NdArray(tangents);
380                        self.command_buffer.insert_one(entity, Tangents(tangents_tensor));
381                    }
382                    DynamicTensorFloat2D::Candle(verts_tensor) => {
383                        // Compute tangents using the Candle backend
384                        let tangents = Geom::compute_dummy_tangents(verts_tensor.dims()[0], &verts_tensor.device());
385                        let tangents_tensor = DynamicTensorFloat2D::Candle(tangents);
386                        self.command_buffer.insert_one(entity, Tangents(tangents_tensor));
387                    }
388                    DynamicTensorFloat2D::Wgpu(verts_tensor) => {
389                        // Compute tangents using the Wgpu backend
390                        let tangents = Geom::compute_dummy_tangents(verts_tensor.dims()[0], &verts_tensor.device());
391                        let tangents_tensor = DynamicTensorFloat2D::Wgpu(tangents);
392                        self.command_buffer.insert_one(entity, Tangents(tangents_tensor));
393                    }
394                }
395            }
396        }
397    }
398
399    // fn add_dummy_uvs(&mut self, scene: &mut Scene) {
400    //     //add dummy uvs if we don't have them
401    //     let mut query = scene
402    //         .world
403    //         .query::<(&Verts, &Faces)>()
404    //         .with::<&Renderable>()
405    //         .without::<&UVs>();
406    //     for (entity, (verts, _faces)) in query.iter() {
407    //         let uvs = Geom::compute_dummy_uvs(verts.0.nrows());
408    //         let uvs_tensor = DynamicTensorFloat2D::NdArray(uvs);
409    //         self.command_buffer.insert_one(entity, UVs(uvs_tensor));
410    //     }
411
412    //     //if we do have uvs, we make sure that they are the same size
413    //     let mut query = scene
414    //         .world
415    //         .query::<(&Verts, &Faces, &UVs)>()
416    //         .with::<&Renderable>();
417    //     for (entity, (verts, _faces, uvs)) in query.iter() {
418    //         if verts.0.nrows() != uvs.0.nrows() {
419    //             let uvs = Geom::compute_dummy_uvs(verts.0.nrows());
420    //             let uvs_tensor = DynamicTensorFloat2D::NdArray(uvs);
421    //             self.command_buffer.insert_one(entity, UVs(uvs_tensor));
422    //         }
423    //     }
424    // }
425    fn add_dummy_uvs(&mut self, scene: &mut Scene) {
426        // Add dummy uvs if we don't have them
427        let mut query = scene.world.query::<(&Verts, &Faces)>().with::<&Renderable>().without::<&UVs>();
428
429        for (entity, (verts, _faces)) in query.iter() {
430            match &verts.0 {
431                DynamicTensorFloat2D::NdArray(verts_tensor) => {
432                    // Compute dummy uvs for NdArray backend
433                    let uvs = Geom::compute_dummy_uvs(verts_tensor.dims()[0], &verts_tensor.device());
434                    let uvs_tensor = DynamicTensorFloat2D::NdArray(uvs);
435                    self.command_buffer.insert_one(entity, UVs(uvs_tensor));
436                }
437                DynamicTensorFloat2D::Candle(verts_tensor) => {
438                    // Compute dummy uvs for Candle backend
439                    let uvs = Geom::compute_dummy_uvs(verts_tensor.dims()[0], &verts_tensor.device());
440                    let uvs_tensor = DynamicTensorFloat2D::Candle(uvs);
441                    self.command_buffer.insert_one(entity, UVs(uvs_tensor));
442                }
443                DynamicTensorFloat2D::Wgpu(verts_tensor) => {
444                    // Compute dummy uvs for Wgpu backend
445                    let uvs = Geom::compute_dummy_uvs(verts_tensor.dims()[0], &verts_tensor.device());
446                    let uvs_tensor = DynamicTensorFloat2D::Wgpu(uvs);
447                    self.command_buffer.insert_one(entity, UVs(uvs_tensor));
448                }
449            }
450        }
451
452        // If we do have uvs, make sure that they are the same size
453        let mut query = scene.world.query::<(&Verts, &Faces, &UVs)>().with::<&Renderable>();
454
455        for (entity, (verts, _faces, uvs)) in query.iter() {
456            if verts.0.nrows() != uvs.0.nrows() {
457                match &verts.0 {
458                    DynamicTensorFloat2D::NdArray(verts_tensor) => {
459                        // Recompute uvs for NdArray backend
460                        let uvs = Geom::compute_dummy_uvs(verts_tensor.dims()[0], &verts_tensor.device());
461                        let uvs_tensor = DynamicTensorFloat2D::NdArray(uvs);
462                        self.command_buffer.insert_one(entity, UVs(uvs_tensor));
463                    }
464                    DynamicTensorFloat2D::Candle(verts_tensor) => {
465                        // Recompute uvs for Candle backend
466                        let uvs = Geom::compute_dummy_uvs(verts_tensor.dims()[0], &verts_tensor.device());
467                        let uvs_tensor = DynamicTensorFloat2D::Candle(uvs);
468                        self.command_buffer.insert_one(entity, UVs(uvs_tensor));
469                    }
470                    DynamicTensorFloat2D::Wgpu(verts_tensor) => {
471                        // Recompute uvs for Wgpu backend
472                        let uvs = Geom::compute_dummy_uvs(verts_tensor.dims()[0], &verts_tensor.device());
473                        let uvs_tensor = DynamicTensorFloat2D::Wgpu(uvs);
474                        self.command_buffer.insert_one(entity, UVs(uvs_tensor));
475                    }
476                }
477            }
478        }
479    }
480
481    // fn add_dummy_colors(&mut self, scene: &mut Scene) {
482    //     //we add dummy colors if we don't have them
483    //     let mut query = scene
484    //         .world
485    //         .query::<&Verts>()
486    //         .with::<&Renderable>()
487    //         .without::<&Colors>();
488    //     for (entity, verts) in query.iter() {
489    //         let colors = Geom::compute_dummy_colors(verts.0.nrows());
490    //         let colors_tensor = DynamicTensorFloat2D::NdArray(colors);
491    //         self.command_buffer
492    //             .insert_one(entity, Colors(colors_tensor));
493    //     }
494    //     //if we do have colors, we make sure they are the same size as verts
495    //     let mut query = scene
496    //         .world
497    //         .query::<(&Verts, &Colors)>()
498    //         .with::<&Renderable>();
499    //     for (entity, (verts, colors)) in query.iter() {
500    //         if verts.0.nrows() != colors.0.nrows() {
501    //             let colors = Geom::compute_dummy_colors(verts.0.nrows());
502    //             let colors_tensor = DynamicTensorFloat2D::NdArray(colors);
503    //             self.command_buffer
504    //                 .insert_one(entity, Colors(colors_tensor));
505    //         }
506    //     }
507    // }
508    fn add_dummy_colors(&mut self, scene: &mut Scene) {
509        // We add dummy colors if we don't have them
510        let mut query = scene.world.query::<&Verts>().with::<&Renderable>().without::<&Colors>();
511
512        for (entity, verts) in query.iter() {
513            match &verts.0 {
514                DynamicTensorFloat2D::NdArray(verts_tensor) => {
515                    // Compute dummy colors for NdArray backend
516                    let colors = Geom::compute_dummy_colors(verts_tensor.dims()[0], &verts_tensor.device());
517                    let colors_tensor = DynamicTensorFloat2D::NdArray(colors);
518                    self.command_buffer.insert_one(entity, Colors(colors_tensor));
519                }
520                DynamicTensorFloat2D::Candle(verts_tensor) => {
521                    // Compute dummy colors for Candle backend
522                    let colors = Geom::compute_dummy_colors(verts_tensor.dims()[0], &verts_tensor.device());
523                    let colors_tensor = DynamicTensorFloat2D::Candle(colors);
524                    self.command_buffer.insert_one(entity, Colors(colors_tensor));
525                }
526                DynamicTensorFloat2D::Wgpu(verts_tensor) => {
527                    // Compute dummy colors for Wgpu backend
528                    let colors = Geom::compute_dummy_colors(verts_tensor.dims()[0], &verts_tensor.device());
529                    let colors_tensor = DynamicTensorFloat2D::Wgpu(colors);
530                    self.command_buffer.insert_one(entity, Colors(colors_tensor));
531                }
532            }
533        }
534
535        // If we do have colors, make sure they are the same size as verts
536        let mut query = scene.world.query::<(&Verts, &Colors)>().with::<&Renderable>();
537
538        for (entity, (verts, colors)) in query.iter() {
539            if verts.0.nrows() != colors.0.nrows() {
540                match &verts.0 {
541                    DynamicTensorFloat2D::NdArray(verts_tensor) => {
542                        // Recompute colors for NdArray backend
543                        let colors = Geom::compute_dummy_colors(verts_tensor.dims()[0], &verts_tensor.device());
544                        let colors_tensor = DynamicTensorFloat2D::NdArray(colors);
545                        self.command_buffer.insert_one(entity, Colors(colors_tensor));
546                    }
547                    DynamicTensorFloat2D::Candle(verts_tensor) => {
548                        // Recompute colors for Candle backend
549                        let colors = Geom::compute_dummy_colors(verts_tensor.dims()[0], &verts_tensor.device());
550                        let colors_tensor = DynamicTensorFloat2D::Candle(colors);
551                        self.command_buffer.insert_one(entity, Colors(colors_tensor));
552                    }
553                    DynamicTensorFloat2D::Wgpu(verts_tensor) => {
554                        // Recompute colors for Wgpu backend
555                        let colors = Geom::compute_dummy_colors(verts_tensor.dims()[0], &verts_tensor.device());
556                        let colors_tensor = DynamicTensorFloat2D::Wgpu(colors);
557                        self.command_buffer.insert_one(entity, Colors(colors_tensor));
558                    }
559                }
560            }
561        }
562    }
563
564    fn add_dummy_diffuse_tex(&mut self, scene: &mut Scene, gpu: &Gpu) {
565        let mut query = scene.world.query::<()>().with::<&Renderable>().without::<&DiffuseTex>();
566        for (entity, _comp) in query.iter() {
567            let tex = Texture::create_default_texture(gpu.device(), gpu.queue());
568            self.command_buffer.insert_one(entity, DiffuseTex(tex));
569        }
570    }
571
572    fn add_dummy_normal_tex(&mut self, scene: &mut Scene, gpu: &Gpu) {
573        let mut query = scene.world.query::<()>().with::<&Renderable>().without::<&NormalTex>();
574        for (entity, _comp) in query.iter() {
575            let tex = Texture::create_default_texture(gpu.device(), gpu.queue());
576            self.command_buffer.insert_one(entity, NormalTex(tex));
577        }
578    }
579
580    fn add_dummy_roughness_tex(&mut self, scene: &mut Scene, gpu: &Gpu) {
581        let mut query = scene.world.query::<()>().with::<&Renderable>().without::<&RoughnessTex>();
582        for (entity, _comp) in query.iter() {
583            let tex = Texture::create_default_texture(gpu.device(), gpu.queue());
584            self.command_buffer.insert_one(entity, RoughnessTex(tex));
585        }
586    }
587
588    fn add_dummy_environment_map(&mut self, scene: &mut Scene, gpu: &Gpu) {
589        //environment map
590        if !scene.has_resource::<EnvironmentMapGpu>() {
591            let env = EnvironmentMapGpu::new_dummy(gpu.device(), gpu.queue());
592            scene.add_resource(env);
593        }
594    }
595
596    //creates a new shadow map for all the lights that have the shadowcasting
597    // component
598    fn add_shadow_maps(&mut self, scene: &mut Scene, gpu: &Gpu) {
599        let mut query = scene
600            .world
601            .query::<(&ShadowCaster, Changed<ShadowCaster>, Option<&ShadowMap>)>()
602            .with::<&LightEmit>();
603
604        for (entity, (shadow_caster, is_shadow_changed, shadow_map)) in query.iter() {
605            if is_shadow_changed || shadow_map.is_none() {
606                debug!(
607                    "creating shadow map, because is_shadow_changed {} or shadow_map.is_none() {}",
608                    is_shadow_changed,
609                    shadow_map.is_none()
610                );
611                let tex_depth = easy_wgpu::texture::Texture::new(
612                    gpu.device(),
613                    shadow_caster.shadow_res,
614                    shadow_caster.shadow_res,
615                    wgpu::TextureFormat::Depth32Float,
616                    wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING,
617                    TexParams::default(),
618                );
619                // let tex_depth_moments = easy_wgpu::texture::Texture::new(
620                //     gpu.device(),
621                //     shadow_caster.shadow_res,
622                //     shadow_caster.shadow_res,
623                //     wgpu::TextureFormat::Rg32Float,
624                //     wgpu::TextureUsages::RENDER_ATTACHMENT |
625                // wgpu::TextureUsages::TEXTURE_BINDING, );
626                self.command_buffer.insert_one(
627                    entity,
628                    ShadowMap {
629                        tex_depth,
630                        // tex_depth_moments,
631                    },
632                );
633            }
634        }
635    }
636
637    fn end_pass_sanity_check(&mut self, scene: &mut Scene) {
638        //check that entities that have verts and colors, have the same number of
639        // vertices and colors
640        let mut query = scene.world.query::<(&Verts, &Colors)>();
641        for (_entity, (verts, colors)) in query.iter() {
642            assert!(
643                verts.0.shape() == colors.0.shape(),
644                "verts is {:?} and colors is{:?}",
645                verts.0.shape(),
646                colors.0.shape()
647            );
648        }
649    }
650
651    // fn set_auto_cam(&mut self, cam: &mut Camera, scene: &mut Scene) {
652    //     let scale = scene.get_scale();
653    //     let centroid = scene.get_centroid();
654
655    //     //get all the automatic values we can get
656    //     let position = centroid
657    //         + na::Vector3::z_axis().scale(2.0 * scale)
658    //         + na::Vector3::y_axis().scale(0.5 * scale);
659    //     let near = (centroid - position).norm() * 0.01;
660    //     let far = (centroid - position).norm() * 1000.0; //far plane can be quite
661    // big. The near plane shouldn't be too tiny because it make the depth have very
662    // little precision
663
664    //     //add a pos lookat
665    //     scene
666    //         .world
667    //         .insert(cam.entity, (PosLookat::new(position, centroid),))
668    //         .unwrap();
669    //     //modify also the near and far
670    //     let mut cam_proj = scene.world.get::<&mut
671    // Projection>(cam.entity).unwrap();     cam_proj.near = near;
672    //     cam_proj.far = far;
673    // }
674}