1pub mod brdf;
9pub mod debug;
10pub mod ibl;
11
12pub mod shader;
13
14#[cfg(test)]
15mod test {
16 use crate::{
17 atlas::AtlasImage,
18 geometry::Vertex,
19 glam::{Vec3, Vec4},
20 test::BlockOnFuture,
21 };
22
23 #[test]
24 fn pbr_metallic_roughness_spheres() {
30 let ss = 600;
31 let ctx = crate::context::Context::headless(ss, ss).block();
32 let stage = ctx.new_stage();
33
34 let radius = 0.5;
35 let ss = ss as f32;
36 let projection = crate::camera::perspective(ss, ss);
37 let k = 7;
38 let diameter = 2.0 * radius;
39 let spacing = radius * 0.25;
40 let len = (k - 1) as f32 * (diameter + spacing);
41 let half = len / 2.0;
42 let view = crate::camera::look_at(
43 Vec3::new(half, half, 1.6 * len),
44 Vec3::new(half, half, 0.0),
45 Vec3::Y,
46 );
47 let _camera = stage
48 .new_camera()
49 .with_projection_and_view(projection, view);
50
51 let geometry = stage.new_vertices({
52 let mut icosphere = icosahedron::Polyhedron::new_isocahedron(radius, 5);
53 icosphere.compute_triangle_normals();
54 let icosahedron::Polyhedron {
55 positions,
56 normals,
57 cells,
58 ..
59 } = icosphere;
60 log::info!("icosphere created on CPU");
61
62 let to_vertex = |ndx: &usize| -> Vertex {
63 let p: [f32; 3] = positions[*ndx].0.into();
64 let n: [f32; 3] = normals[*ndx].0.into();
65 Vertex::default().with_position(p).with_normal(n)
66 };
67 cells
68 .iter()
69 .flat_map(|icosahedron::Triangle { a, b, c }| {
70 let p0 = to_vertex(a);
71 let p1 = to_vertex(b);
72 let p2 = to_vertex(c);
73 vec![p0, p1, p2]
74 })
75 .collect::<Vec<_>>()
76 });
77 let mut spheres = vec![];
78 for i in 0..k {
79 let roughness = i as f32 / (k - 1) as f32;
80 let x = (diameter + spacing) * i as f32;
81 for j in 0..k {
82 let metallic = j as f32 / (k - 1) as f32;
83 let y = (diameter + spacing) * j as f32;
84
85 let rez = stage
86 .new_primitive()
87 .with_material(
88 stage
89 .new_material()
90 .with_albedo_factor(Vec4::new(1.0, 1.0, 1.0, 1.0))
91 .with_metallic_factor(metallic)
92 .with_roughness_factor(roughness),
93 )
94 .with_transform(stage.new_transform().with_translation(Vec3::new(x, y, 0.0)))
95 .with_vertices(&geometry);
96 spheres.push(rez);
97 }
98 }
99
100 let hdr_image = AtlasImage::from_hdr_path("../../img/hdr/resting_place.hdr").unwrap();
101 let skybox = crate::skybox::Skybox::new(&ctx, hdr_image);
102 stage.use_skybox(&skybox);
103
104 let ibl = stage.new_ibl(&skybox);
105 stage.use_ibl(&ibl);
106
107 let frame = ctx.get_next_frame().unwrap();
108 stage.render(&frame.view());
109 let img = frame.read_image().block().unwrap();
110 img_diff::assert_img_eq("pbr/metallic_roughness_spheres.png", img);
111 }
112}