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, VisOutline, VisPoints, VisWireframe,
8 },
9 config::Config,
10 scene::Scene,
11};
12use easy_wgpu::{
13 gpu::Gpu,
14 texture::{TexParams, Texture},
15};
16use gloss_geometry::geom::{self, PerVertexNormalsWeightingType};
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.add_vis_outline(scene);
64 self.command_buffer.run_on(&mut scene.world); }
69
70 pub fn run(
71 &mut self,
72 gpu: &Gpu,
73 camera: &mut Camera,
74 scene: &mut Scene,
75 config: &mut Config,
78 ) {
79 self.begin_pass();
80
81 self.check_entity_names(scene); self.add_auto_components(gpu, scene);
88
89 if !config.is_concrete() && scene.nr_renderables() != 0 {
92 scene.make_concrete_config(config);
93 }
94 if config.is_concrete() && !config.is_consumed() {
95 let (width, height) = camera.get_target_res(scene);
96 scene.from_config(config, width, height);
97 self.add_auto_components(gpu, scene); }
102
103 self.add_shadow_maps(scene, gpu);
109
110 self.end_pass_sanity_check(scene);
122
123 self.end_pass(scene);
124 }
125
126 fn begin_pass(&self) {}
127
128 fn end_pass(&mut self, scene: &mut Scene) {
129 self.command_buffer.run_on(&mut scene.world);
130 }
131
132 fn check_entity_names(&mut self, scene: &mut Scene) {
133 let mut query = scene.world.query::<()>().without::<&Name>();
134 for (_entity, _comp) in query.iter() {
135 warn!("Entity does not have a name, please assign name to all of them");
136 }
137 }
138
139 fn add_vis_lines(&mut self, scene: &mut Scene) {
140 let mut query = scene.world.query::<Option<&Faces>>().with::<(&Verts, &Edges)>().without::<&VisLines>();
141 for (entity, faces) in query.iter() {
142 let show_lines = faces.is_none();
145
146 self.command_buffer.insert_one(
147 entity,
148 VisLines {
149 added_automatically: true,
150 show_lines,
151 ..Default::default()
152 },
153 );
154 }
155 }
156
157 fn add_vis_wireframe(&mut self, scene: &mut Scene) {
158 let mut query = scene.world.query::<()>().with::<(&Verts, &Faces)>().without::<&VisWireframe>();
159 for (entity, _comp) in query.iter() {
160 self.command_buffer.insert_one(
161 entity,
162 VisWireframe {
163 added_automatically: true,
164 ..Default::default()
165 },
166 );
167 }
168 }
169
170 fn add_vis_normals(&mut self, scene: &mut Scene) {
171 let mut query = scene.world.query::<()>().with::<(&Verts, &Normals)>().without::<&VisNormals>();
172 for (entity, _comp) in query.iter() {
173 self.command_buffer.insert_one(
174 entity,
175 VisNormals {
176 added_automatically: true,
177 ..Default::default()
178 },
179 );
180 }
181 }
182
183 fn add_vis_points(&mut self, scene: &mut Scene) {
184 let mut query = scene
185 .world
186 .query::<(Option<&Faces>, Option<&Edges>)>()
187 .with::<&Verts>()
188 .without::<&VisPoints>();
189 for (entity, (faces, edges)) in query.iter() {
190 let show_points = faces.is_none() && edges.is_none();
193
194 self.command_buffer.insert_one(
195 entity,
196 VisPoints {
197 added_automatically: true,
198 show_points,
199 ..Default::default()
200 },
201 );
202 }
203 }
204
205 fn add_vis_mesh(&mut self, scene: &mut Scene) {
206 let mut query = scene.world.query::<()>().with::<(&Verts, &Faces)>().without::<&VisMesh>();
207 for (entity, _comp) in query.iter() {
208 self.command_buffer.insert_one(
209 entity,
210 VisMesh {
211 added_automatically: true,
212 ..Default::default()
213 },
214 );
215 }
216 }
217
218 fn add_vis_outline(&mut self, scene: &mut Scene) {
219 let mut query = scene.world.query::<&Name>().with::<(&Verts, &Faces)>().without::<&VisOutline>();
220 for (entity, name) in query.iter() {
221 if name.0 == "floor" {
223 continue;
224 }
225 self.command_buffer.insert_one(
226 entity,
227 VisOutline {
228 added_automatically: true,
229 ..Default::default()
230 },
231 );
232 }
233 }
234
235 fn add_model_matrix(&mut self, scene: &mut Scene) {
236 let mut query = scene.world.query::<()>().with::<&Renderable>().without::<&ModelMatrix>();
237 for (entity, _comp) in query.iter() {
238 self.command_buffer.insert_one(entity, ModelMatrix::default());
239 }
240 }
241
242 fn add_vertex_normals(&mut self, scene: &mut Scene) {
243 let insert_normals = |entity: Entity, verts: &Verts, faces: &Faces, command_buffer: &mut CommandBuffer| {
246 match (&verts.0, &faces.0) {
247 (DynamicTensorFloat2D::NdArray(verts_tensor), DynamicTensorInt2D::NdArray(faces_tensor)) => {
249 let normals = geom::compute_per_vertex_normals(
250 &verts_tensor.to_nalgebra(),
251 &faces_tensor.to_nalgebra(),
252 &PerVertexNormalsWeightingType::Area,
253 );
254 let normals_tensor = DynamicTensorFloat2D::NdArray(normals.into_burn(&verts_tensor.device()));
255 command_buffer.insert_one(entity, Normals(normals_tensor));
256 }
257 (DynamicTensorFloat2D::Candle(verts_tensor), DynamicTensorInt2D::Candle(faces_tensor)) => {
260 let normals = geom::compute_per_vertex_normals_burn(verts_tensor, faces_tensor, &PerVertexNormalsWeightingType::Area);
261 let normals_tensor = DynamicTensorFloat2D::Candle(normals);
262 command_buffer.insert_one(entity, Normals(normals_tensor));
263 }
264 (DynamicTensorFloat2D::Wgpu(_), _) | (_, DynamicTensorInt2D::Wgpu(_)) => {
266 panic!("Wgpu backend is not supported for the prepass! Make sure normals are being added in smpl-rs");
267 }
268 _ => {
270 panic!(
271 "Mismatched backends between verts and faces tensors! Faces - {:?} Verts - {:?}",
272 &verts.0, &faces.0
273 );
274 }
275 }
276 };
277
278 let mut query = scene.world.query::<(&Verts, &Faces)>().with::<&Renderable>().without::<&Normals>();
280 for (entity, (verts, faces)) in query.iter() {
281 insert_normals(entity, verts, faces, &mut self.command_buffer);
282 }
283
284 let mut query = scene.world.query::<(&Verts, &Faces, &Normals)>().with::<&Renderable>();
289 for (entity, (verts, faces, normals)) in query.iter() {
290 if verts.0.nrows() != normals.0.nrows() {
291 insert_normals(entity, verts, faces, &mut self.command_buffer);
292 }
293 }
294 }
295 #[allow(clippy::too_many_lines)]
296 fn add_tangents(&mut self, scene: &mut Scene) {
297 let insert_tangents = |entity: Entity, verts: &Verts, faces: &Faces, normals: &Normals, uvs: &UVs, command_buffer: &mut CommandBuffer| {
298 match (&verts.0, &faces.0, &normals.0, &uvs.0) {
299 (
301 DynamicTensorFloat2D::NdArray(verts_tensor),
302 DynamicTensorInt2D::NdArray(faces_tensor),
303 DynamicTensorFloat2D::NdArray(normals_tensor),
304 DynamicTensorFloat2D::NdArray(uvs_tensor),
305 ) => {
306 let tangents = geom::compute_tangents(
308 &verts_tensor.to_nalgebra(),
309 &faces_tensor.to_nalgebra(),
310 &normals_tensor.to_nalgebra(),
311 &uvs_tensor.to_nalgebra(),
312 );
313 let tangents_tensor = DynamicTensorFloat2D::NdArray(tangents.into_burn(&verts_tensor.device()));
314 command_buffer.insert_one(entity, Tangents(tangents_tensor));
315 }
316 _ => {
334 panic!("Unsupported backend combination for tangents calculation!");
335 }
336 }
337 };
338
339 let mut query = scene
341 .world
342 .query::<(&Verts, &Faces, &Normals, &UVs)>()
343 .with::<&Renderable>()
344 .without::<&Tangents>();
345 for (entity, (verts, faces, normals, uvs)) in query.iter() {
346 insert_tangents(entity, verts, faces, normals, uvs, &mut self.command_buffer);
347 }
348
349 let mut query = scene.world.query::<(&Verts, &Faces, &Normals, &UVs, &Tangents)>().with::<&Renderable>();
354 for (entity, (verts, faces, normals, uvs, tangents)) in query.iter() {
355 if verts.0.nrows() != tangents.0.nrows() {
356 insert_tangents(entity, verts, faces, normals, uvs, &mut self.command_buffer);
357 }
358 }
359
360 let mut query = scene.world.query::<(&Verts, &Faces)>().with::<&Renderable>().without::<&UVs>();
363 for (entity, (verts, _faces)) in query.iter() {
364 match &verts.0 {
366 DynamicTensorFloat2D::NdArray(verts_tensor) => {
367 let tangents = geom::compute_dummy_tangents(verts_tensor.dims()[0], &verts_tensor.device());
369 let tangents_tensor = DynamicTensorFloat2D::NdArray(tangents);
370 self.command_buffer.insert_one(entity, Tangents(tangents_tensor));
371 }
372 DynamicTensorFloat2D::Candle(verts_tensor) => {
373 let tangents = geom::compute_dummy_tangents(verts_tensor.dims()[0], &verts_tensor.device());
375 let tangents_tensor = DynamicTensorFloat2D::Candle(tangents);
376 self.command_buffer.insert_one(entity, Tangents(tangents_tensor));
377 }
378 DynamicTensorFloat2D::Wgpu(verts_tensor) => {
379 let tangents = geom::compute_dummy_tangents(verts_tensor.dims()[0], &verts_tensor.device());
381 let tangents_tensor = DynamicTensorFloat2D::Wgpu(tangents);
382 self.command_buffer.insert_one(entity, Tangents(tangents_tensor));
383 }
384 }
385 }
386
387 let mut query = scene.world.query::<(&Verts, &Faces, &Tangents)>().with::<&Renderable>().without::<&UVs>();
390
391 for (entity, (verts, _faces, tangents)) in query.iter() {
392 if verts.0.nrows() != tangents.0.nrows() {
393 match &verts.0 {
394 DynamicTensorFloat2D::NdArray(verts_tensor) => {
395 let tangents = geom::compute_dummy_tangents(verts_tensor.dims()[0], &verts_tensor.device());
397 let tangents_tensor = DynamicTensorFloat2D::NdArray(tangents);
398 self.command_buffer.insert_one(entity, Tangents(tangents_tensor));
399 }
400 DynamicTensorFloat2D::Candle(verts_tensor) => {
401 let tangents = geom::compute_dummy_tangents(verts_tensor.dims()[0], &verts_tensor.device());
403 let tangents_tensor = DynamicTensorFloat2D::Candle(tangents);
404 self.command_buffer.insert_one(entity, Tangents(tangents_tensor));
405 }
406 DynamicTensorFloat2D::Wgpu(verts_tensor) => {
407 let tangents = geom::compute_dummy_tangents(verts_tensor.dims()[0], &verts_tensor.device());
409 let tangents_tensor = DynamicTensorFloat2D::Wgpu(tangents);
410 self.command_buffer.insert_one(entity, Tangents(tangents_tensor));
411 }
412 }
413 }
414 }
415 }
416
417 fn add_dummy_uvs(&mut self, scene: &mut Scene) {
444 let mut query = scene.world.query::<(&Verts, &Faces)>().with::<&Renderable>().without::<&UVs>();
446
447 for (entity, (verts, _faces)) in query.iter() {
448 match &verts.0 {
449 DynamicTensorFloat2D::NdArray(verts_tensor) => {
450 let uvs = geom::compute_dummy_uvs(verts_tensor.dims()[0], &verts_tensor.device());
452 let uvs_tensor = DynamicTensorFloat2D::NdArray(uvs);
453 self.command_buffer.insert_one(entity, UVs(uvs_tensor));
454 }
455 DynamicTensorFloat2D::Candle(verts_tensor) => {
456 let uvs = geom::compute_dummy_uvs(verts_tensor.dims()[0], &verts_tensor.device());
458 let uvs_tensor = DynamicTensorFloat2D::Candle(uvs);
459 self.command_buffer.insert_one(entity, UVs(uvs_tensor));
460 }
461 DynamicTensorFloat2D::Wgpu(verts_tensor) => {
462 let uvs = geom::compute_dummy_uvs(verts_tensor.dims()[0], &verts_tensor.device());
464 let uvs_tensor = DynamicTensorFloat2D::Wgpu(uvs);
465 self.command_buffer.insert_one(entity, UVs(uvs_tensor));
466 }
467 }
468 }
469
470 let mut query = scene.world.query::<(&Verts, &Faces, &UVs)>().with::<&Renderable>();
472
473 for (entity, (verts, _faces, uvs)) in query.iter() {
474 if verts.0.nrows() != uvs.0.nrows() {
475 match &verts.0 {
476 DynamicTensorFloat2D::NdArray(verts_tensor) => {
477 let uvs = geom::compute_dummy_uvs(verts_tensor.dims()[0], &verts_tensor.device());
479 let uvs_tensor = DynamicTensorFloat2D::NdArray(uvs);
480 self.command_buffer.insert_one(entity, UVs(uvs_tensor));
481 }
482 DynamicTensorFloat2D::Candle(verts_tensor) => {
483 let uvs = geom::compute_dummy_uvs(verts_tensor.dims()[0], &verts_tensor.device());
485 let uvs_tensor = DynamicTensorFloat2D::Candle(uvs);
486 self.command_buffer.insert_one(entity, UVs(uvs_tensor));
487 }
488 DynamicTensorFloat2D::Wgpu(verts_tensor) => {
489 let uvs = geom::compute_dummy_uvs(verts_tensor.dims()[0], &verts_tensor.device());
491 let uvs_tensor = DynamicTensorFloat2D::Wgpu(uvs);
492 self.command_buffer.insert_one(entity, UVs(uvs_tensor));
493 }
494 }
495 }
496 }
497 }
498
499 fn add_dummy_colors(&mut self, scene: &mut Scene) {
527 let mut query = scene.world.query::<&Verts>().with::<&Renderable>().without::<&Colors>();
529
530 for (entity, verts) in query.iter() {
531 match &verts.0 {
532 DynamicTensorFloat2D::NdArray(verts_tensor) => {
533 let colors = geom::compute_dummy_colors(verts_tensor.dims()[0], &verts_tensor.device());
535 let colors_tensor = DynamicTensorFloat2D::NdArray(colors);
536 self.command_buffer.insert_one(entity, Colors(colors_tensor));
537 }
538 DynamicTensorFloat2D::Candle(verts_tensor) => {
539 let colors = geom::compute_dummy_colors(verts_tensor.dims()[0], &verts_tensor.device());
541 let colors_tensor = DynamicTensorFloat2D::Candle(colors);
542 self.command_buffer.insert_one(entity, Colors(colors_tensor));
543 }
544 DynamicTensorFloat2D::Wgpu(verts_tensor) => {
545 let colors = geom::compute_dummy_colors(verts_tensor.dims()[0], &verts_tensor.device());
547 let colors_tensor = DynamicTensorFloat2D::Wgpu(colors);
548 self.command_buffer.insert_one(entity, Colors(colors_tensor));
549 }
550 }
551 }
552
553 let mut query = scene.world.query::<(&Verts, &Colors)>().with::<&Renderable>();
555
556 for (entity, (verts, colors)) in query.iter() {
557 if verts.0.nrows() != colors.0.nrows() {
558 match &verts.0 {
559 DynamicTensorFloat2D::NdArray(verts_tensor) => {
560 let colors = geom::compute_dummy_colors(verts_tensor.dims()[0], &verts_tensor.device());
562 let colors_tensor = DynamicTensorFloat2D::NdArray(colors);
563 self.command_buffer.insert_one(entity, Colors(colors_tensor));
564 }
565 DynamicTensorFloat2D::Candle(verts_tensor) => {
566 let colors = geom::compute_dummy_colors(verts_tensor.dims()[0], &verts_tensor.device());
568 let colors_tensor = DynamicTensorFloat2D::Candle(colors);
569 self.command_buffer.insert_one(entity, Colors(colors_tensor));
570 }
571 DynamicTensorFloat2D::Wgpu(verts_tensor) => {
572 let colors = geom::compute_dummy_colors(verts_tensor.dims()[0], &verts_tensor.device());
574 let colors_tensor = DynamicTensorFloat2D::Wgpu(colors);
575 self.command_buffer.insert_one(entity, Colors(colors_tensor));
576 }
577 }
578 }
579 }
580 }
581
582 fn add_dummy_diffuse_tex(&mut self, scene: &mut Scene, gpu: &Gpu) {
583 let mut query = scene.world.query::<()>().with::<&Renderable>().without::<&DiffuseTex>();
584 for (entity, _comp) in query.iter() {
585 let tex = Texture::create_default_texture(gpu.device(), gpu.queue());
586 self.command_buffer.insert_one(entity, DiffuseTex(tex));
587 }
588 }
589
590 fn add_dummy_normal_tex(&mut self, scene: &mut Scene, gpu: &Gpu) {
591 let mut query = scene.world.query::<()>().with::<&Renderable>().without::<&NormalTex>();
592 for (entity, _comp) in query.iter() {
593 let tex = Texture::create_default_texture(gpu.device(), gpu.queue());
594 self.command_buffer.insert_one(entity, NormalTex(tex));
595 }
596 }
597
598 fn add_dummy_roughness_tex(&mut self, scene: &mut Scene, gpu: &Gpu) {
599 let mut query = scene.world.query::<()>().with::<&Renderable>().without::<&RoughnessTex>();
600 for (entity, _comp) in query.iter() {
601 let tex = Texture::create_default_texture(gpu.device(), gpu.queue());
602 self.command_buffer.insert_one(entity, RoughnessTex(tex));
603 }
604 }
605
606 fn add_dummy_environment_map(&mut self, scene: &mut Scene, gpu: &Gpu) {
607 if !scene.has_resource::<EnvironmentMapGpu>() {
609 let env = EnvironmentMapGpu::new_dummy(gpu.device(), gpu.queue());
610 scene.add_resource(env);
611 }
612 }
613
614 fn add_shadow_maps(&mut self, scene: &mut Scene, gpu: &Gpu) {
617 let mut query = scene
618 .world
619 .query::<(&ShadowCaster, Changed<ShadowCaster>, Option<&ShadowMap>)>()
620 .with::<&LightEmit>();
621
622 for (entity, (shadow_caster, is_shadow_changed, shadow_map)) in query.iter() {
623 if is_shadow_changed || shadow_map.is_none() {
624 debug!(
625 "creating shadow map, because is_shadow_changed {} or shadow_map.is_none() {}",
626 is_shadow_changed,
627 shadow_map.is_none()
628 );
629 let tex_depth = easy_wgpu::texture::Texture::new(
630 gpu.device(),
631 shadow_caster.shadow_res,
632 shadow_caster.shadow_res,
633 wgpu::TextureFormat::Depth32Float,
634 wgpu::TextureUsages::RENDER_ATTACHMENT | wgpu::TextureUsages::TEXTURE_BINDING,
635 TexParams::default(),
636 );
637 self.command_buffer.insert_one(
645 entity,
646 ShadowMap {
647 tex_depth,
648 },
650 );
651 }
652 }
653 }
654
655 fn end_pass_sanity_check(&mut self, scene: &mut Scene) {
656 let mut query = scene.world.query::<(&Verts, &Colors)>();
659 for (_entity, (verts, colors)) in query.iter() {
660 assert!(
661 verts.0.shape() == colors.0.shape(),
662 "verts is {:?} and colors is{:?}",
663 verts.0.shape(),
664 colors.0.shape()
665 );
666 }
667 }
668
669 }