circle/
circle.rs

1use lumo::tracer::*;
2use lumo::*;
3
4// s = v = 1.0. h in radians
5fn hsv_to_rgb(h: Float) -> Color {
6    let f = |n: Float| {
7        let k = (n + h / (PI / 3.0)) % 6.0;
8        1.0 - k.min(4.0 - k).min(1.0).max(0.0)
9    };
10
11    let rgb = Vec3::new(f(5.0), f(3.0), f(1.0)) * 255.0;
12
13    Color::new(rgb.x as u8, rgb.y as u8, rgb.z as u8)
14}
15
16fn main() -> Result<(), std::io::Error> {
17    let camera = Camera::perspective(
18        Vec3::new(0.0, 1.5, 1.5),
19        Vec3::ZERO,
20        Vec3::new(0.0, 1.0, -1.0),
21        90.0,
22        0.0,
23        0.0,
24        1024,
25        768,
26    );
27
28    let mut scene = Scene::default();
29    let ground = -0.2;
30
31    // ground
32    scene.add(Plane::new(
33        ground * Vec3::Y,
34        Vec3::Y,
35        Material::metallic(Texture::Solid(Color::new(150, 40, 39)), 0.009999),
36    ));
37
38    let r = 0.2;
39    scene.add_light(Sphere::new(
40        Vec3::new(0.0, ground + r + 0.1, 0.0),
41        r,
42        Material::Light(Texture::Solid(Color::WHITE)),
43    ));
44
45    let circle_s = 8;
46    let offset = PI / circle_s as Float;
47
48    for i in 0..circle_s {
49        let theta = (i as Float / circle_s as Float) * 2.0 * PI + offset;
50        let x = theta.cos();
51        let y = ground + r;
52        let z = theta.sin();
53
54        scene.add(Sphere::new(
55            Vec3::new(x, y, z),
56            r,
57            Material::specular(Texture::Solid(hsv_to_rgb(theta - offset)), 0.2),
58        ));
59    }
60
61    scene.set_medium(
62        Medium::new(
63            Vec3::new(0.002, 0.003, 0.0001),
64            Vec3::new(0.175, 0.125, 0.11),
65            0.9,
66        )
67    );
68
69    let renderer = Renderer::new(scene, camera);
70    renderer.render().save("circle.png")?;
71
72    Ok(())
73}