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};
23pub struct PrePass {
27 command_buffer: CommandBuffer, }
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 self.add_model_matrix(scene);
43 self.add_vertex_normals(scene);
44 self.command_buffer.run_on(&mut scene.world); self.add_tangents(scene); 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 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); }
68
69 pub fn run(
70 &mut self,
71 gpu: &Gpu,
72 camera: &mut Camera,
73 scene: &mut Scene,
74 config: &mut Config,
77 ) {
78 self.begin_pass();
79
80 self.check_entity_names(scene); self.add_auto_components(gpu, scene);
87
88 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); }
101
102 self.add_shadow_maps(scene, gpu);
108
109 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 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 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 let insert_normals = |entity: Entity, verts: &Verts, faces: &Faces, command_buffer: &mut CommandBuffer| {
228 match (&verts.0, &faces.0) {
229 (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 (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 (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 _ => {
252 panic!(
253 "Mismatched backends between verts and faces tensors! Faces - {:?} Verts - {:?}",
254 &verts.0, &faces.0
255 );
256 }
257 }
258 };
259
260 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 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 (
283 DynamicTensorFloat2D::NdArray(verts_tensor),
284 DynamicTensorInt2D::NdArray(faces_tensor),
285 DynamicTensorFloat2D::NdArray(normals_tensor),
286 DynamicTensorFloat2D::NdArray(uvs_tensor),
287 ) => {
288 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 _ => {
316 panic!("Unsupported backend combination for tangents calculation!");
317 }
318 }
319 };
320
321 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 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 let mut query = scene.world.query::<(&Verts, &Faces)>().with::<&Renderable>().without::<&UVs>();
345 for (entity, (verts, _faces)) in query.iter() {
346 match &verts.0 {
348 DynamicTensorFloat2D::NdArray(verts_tensor) => {
349 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 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 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 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 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 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 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) {
426 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 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 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 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 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 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 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 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) {
509 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 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 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 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 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 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 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 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 if !scene.has_resource::<EnvironmentMapGpu>() {
591 let env = EnvironmentMapGpu::new_dummy(gpu.device(), gpu.queue());
592 scene.add_resource(env);
593 }
594 }
595
596 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 self.command_buffer.insert_one(
627 entity,
628 ShadowMap {
629 tex_depth,
630 },
632 );
633 }
634 }
635 }
636
637 fn end_pass_sanity_check(&mut self, scene: &mut Scene) {
638 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 }