-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.rs
136 lines (119 loc) · 4.06 KB
/
main.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
127
128
129
130
131
132
133
134
135
136
// Chapter 11 Closing Challenge:
//
// Implement non-shadow-casting materials, so that a view from air into water
// is possible, without the water surface casting a shadow over the objects below.
use rand::prelude::*;
use rand_xoshiro::Xoshiro256StarStar;
use rust_rtc::colors::{color, colori, Color};
use rust_rtc::lights::point_light;
use rust_rtc::materials::{default_material, RefractiveIndex};
use rust_rtc::patterns::checkers_pattern;
use rust_rtc::shapes::{plane, sphere};
use rust_rtc::transformations::{rotation_x, scaling, translation, view_transform};
use rust_rtc::tuples::{point, vector, Point};
use rust_rtc::utils;
use rust_rtc::utils::RenderOptions;
use rust_rtc::world::world;
use std::f64::consts::PI;
use std::process::ExitCode;
fn main() -> ExitCode {
let cli = utils::parse_args();
let mut w = world();
let mut wall = plane();
wall.set_transform(&rotation_x(PI / 2.0).then(&translation(0.0, 0.5, 10.0)));
wall.material = default_material();
wall.material.color = color(1.0, 0.9, 0.9);
wall.material.ambient = 0.8;
wall.material.diffuse = 0.2;
wall.material.specular = 0.0;
wall.material.reflective = 0.2;
wall.material.set_pattern(&checkers_pattern(
&color(0.15, 0.15, 0.15),
&color(0.85, 0.85, 0.85),
));
w.add_object(wall);
// depth of the water
let water_depth = 2.5;
let mut floor = plane();
floor.set_transform(&translation(0.0, -water_depth, 0.0));
floor.material = default_material();
floor.material.color = colori(77, 63, 38);
floor.material.ambient = 0.1;
floor.material.diffuse = 0.9;
floor.material.specular = 0.0;
floor.material.reflective = 0.0;
w.add_object(floor);
struct Pebble {
position: Point,
size: f64,
color: Color,
}
let mut rng = Xoshiro256StarStar::seed_from_u64(0);
let num_pebbles = 500;
let spread = 25.0;
// Pebbles
for i in 0..num_pebbles {
let grey_level = {
let v = rng.gen();
Color::new(v, v, v)
};
let size = 0.1 + rng.gen::<f64>() / 10.0;
let pebble = Pebble {
position: point(
spread * (rng.gen::<f64>() - 0.5),
-size * rng.gen::<f64>(),
spread * (rng.gen::<f64>() - 0.5),
),
size,
color: grey_level
+ Color::new(
rng.gen::<f64>() / 10.0,
rng.gen::<f64>() / 10.0,
rng.gen::<f64>() / 10.0,
),
};
let mut object = sphere(i);
object.set_transform(
&scaling(pebble.size, pebble.size, pebble.size).then(&translation(
pebble.position.x(),
-water_depth + pebble.position.y(),
pebble.position.z(),
)),
);
object.material.color = pebble.color;
object.material.specular = 0.2;
object.material.shininess = 10.0;
object.material.reflective = 0.0;
w.add_object(object);
}
// Water plane - casts no shadow
let mut water = plane();
water.material = default_material();
water.material.color = color(0.0, 0.1, 0.2);
water.material.ambient = 0.2;
water.material.diffuse = 0.6;
water.material.specular = 0.0;
water.material.shininess = 100.0;
water.material.reflective = 0.7;
water.material.transparency = 1.0;
water.material.refractive_index = RefractiveIndex::WATER;
water.material.casts_shadow = false;
w.add_object(water);
w.add_light(point_light(point(5.0, 10.0, -8.0), color(0.9, 0.9, 0.9)));
let options = RenderOptions {
camera_transform: view_transform(
&point(4.0, 4.0, -8.0),
&point(0.0, 0.0, 0.0),
&vector(0.0, 1.0, 0.0),
)
.then(&translation(0.0, 0.0, 2.0)),
..Default::default()
};
ExitCode::from(match utils::render_world(&w, options, &cli.common) {
Ok(_) => 0,
Err(e) => {
eprintln!("Write {}: {}", cli.common.render.output, e);
1
}
})
}