-
Notifications
You must be signed in to change notification settings - Fork 0
/
book2chap2.rs
126 lines (118 loc) · 4.21 KB
/
book2chap2.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
use super::camera::*;
use super::materials::*;
use super::rng::*;
use super::scene::*;
use super::sphere::*;
use super::types::*;
use crate::acceleration::BvhPartitionMethod;
use rand::distributions::Uniform;
pub fn book2_chap2_scene<'a>(nx: usize, ny: usize, rng: &mut RttRng) -> (Scene, Camera) {
// Clone the RNG for the moving sphere center1 calculations to keep the scene
// otherwise identical to chap12_scene.
let mut rng2 = rng.clone();
let mut scene = Scene::new();
scene.spheres.push(Sphere::from(StationarySphere {
center: Vec4f::new(0., -1000., 0., 0.),
radius: 1000.,
material: Box::new(Lambertian {
albedo: Vec4f::new(0.5, 0.5, 0.5, 1.),
}),
}));
for a in -11..11 {
for b in -11..11 {
let center = Vec4f::new(
a as f32 + 0.9 * rng.gen::<f32>(),
0.2,
b as f32 + 0.9 * rng.gen::<f32>(),
0.,
);
if (center - Vec4f::new(4., 0.2, 0., 0.)).mag() > 0.9 {
let choose_mat = rng.gen::<f32>();
let sphere = if choose_mat < 0.8 {
// Diffuse
let center0 = center;
let center1 = center0
+ Vec4f::new(0., rng2.sample(Uniform::new_inclusive(0., 0.5)), 0., 0.);
Sphere::new(
center0,
center1,
0.,
1.,
0.2,
Box::new(Lambertian {
albedo: Vec4f::new(
rng.gen::<f32>() * rng.gen::<f32>(),
rng.gen::<f32>() * rng.gen::<f32>(),
rng.gen::<f32>() * rng.gen::<f32>(),
1.,
),
}),
)
} else if choose_mat < 0.95 {
// Metal
Sphere::from(StationarySphere {
center,
radius: 0.2,
material: Box::new(Metal {
albedo: Vec4f::new(
0.5 * (1. + rng.gen::<f32>()),
0.5 * (1. + rng.gen::<f32>()),
0.5 * (1. + rng.gen::<f32>()),
1.,
),
fuzz: 0.5 * rng.gen::<f32>(),
}),
})
} else {
// Glass
Sphere::from(StationarySphere {
center,
radius: 0.2,
material: Box::new(Dielectric { ref_idx: 1.5 }),
})
};
scene.spheres.push(sphere);
}
}
}
scene.spheres.push(Sphere::from(StationarySphere {
center: Vec4f::new(0., 1., 0., 0.),
radius: 1.,
material: Box::new(Dielectric { ref_idx: 1.5 }),
}));
scene.spheres.push(Sphere::from(StationarySphere {
center: Vec4f::new(-4., 1., 0., 0.),
radius: 1.,
material: Box::new(Lambertian {
albedo: Vec4f::new(0.4, 0.2, 0.1, 1.),
}),
}));
scene.spheres.push(Sphere::from(StationarySphere {
center: Vec4f::new(4., 1., 0., 0.),
radius: 1.,
material: Box::new(Metal {
albedo: Vec4f::new(0.7, 0.6, 0.5, 1.),
fuzz: 0.,
}),
}));
scene.build_bvh(BvhPartitionMethod::Middle);
let look_from = Vec4f::new(13., 2., 3., 0.);
let look_at = Vec4f::new(0., 0., 0., 0.);
let up = Vec4f::new(0., 1., 0., 0.);
let fov = 20.;
let aspect = nx as f32 / ny as f32;
let aperture = 0.1;
let focus_dist = 10.;
let camera = Camera::from(CameraCreateInfo {
look_from,
look_at,
up,
fov,
aspect,
aperture,
focus_dist,
time0: 0.,
time1: 1.,
});
(scene, camera)
}