Finalize tutorial
This commit is contained in:
parent
284167f7c1
commit
2ba85de59f
5 changed files with 170 additions and 67 deletions
40
Cargo.lock
generated
40
Cargo.lock
generated
|
@ -61,9 +61,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crossbeam-channel"
|
||||
version = "0.5.4"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53"
|
||||
checksum = "4c02a4d71819009c192cf4872265391563fd6a84c81ff2c0f2a7026ca4c1d85c"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
|
@ -82,26 +82,26 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.8"
|
||||
version = "0.9.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c"
|
||||
checksum = "07db9d94cbd326813772c968ccd25999e5f8ae22f4f8d1b11effa37ef6ce281d"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if",
|
||||
"crossbeam-utils",
|
||||
"lazy_static",
|
||||
"memoffset",
|
||||
"once_cell",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.8"
|
||||
version = "0.8.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38"
|
||||
checksum = "7d82ee10ce34d7bc12c2122495e7593a9c41347ecdd64185af4ecf72cb1a7f83"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"lazy_static",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -121,9 +121,9 @@ checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
|
|||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.6"
|
||||
version = "0.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
|
||||
checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
|
@ -161,12 +161,6 @@ version = "0.2.6"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9478aa10f73e7528198d75109c8be5cd7d15fb530238040148d5f9a22d4c5b3b"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.126"
|
||||
|
@ -214,9 +208,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "num-rational"
|
||||
version = "0.4.0"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d41702bd167c2df5520b384281bc111a4b5efcf7fbc4c9c222c815b07e0a6a6a"
|
||||
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
|
@ -242,6 +236,12 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225"
|
||||
|
||||
[[package]]
|
||||
name = "png"
|
||||
version = "0.17.5"
|
||||
|
@ -331,6 +331,6 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
|||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.10.2+wasi-snapshot-preview1"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
|
|
@ -5,34 +5,59 @@ pub struct Camera {
|
|||
lower_left_corner: Point3,
|
||||
horizontal: Vec3,
|
||||
vertical: Vec3,
|
||||
u: Vec3,
|
||||
v: Vec3,
|
||||
w: Vec3,
|
||||
lens_radius: f64,
|
||||
|
||||
}
|
||||
|
||||
impl Camera {
|
||||
pub fn new() -> Self {
|
||||
let aspect_ratio = 16.0 / 9.0;
|
||||
let viewport_height = 2.0;
|
||||
pub fn new(
|
||||
lookfrom: Point3,
|
||||
lookat: Point3,
|
||||
vup: Vec3,
|
||||
vfov: f64, // vertical field of view in degrees
|
||||
aspect_ratio: f64,
|
||||
aperture: f64,
|
||||
focus_dist: f64,
|
||||
) -> Self {
|
||||
let theta = vfov.to_radians();
|
||||
let h = (theta/2.0).tan();
|
||||
let viewport_height = 2.0*h;
|
||||
let viewport_width = aspect_ratio * viewport_height;
|
||||
let focal_length = 1.0;
|
||||
|
||||
let origin = Point3::new(0.0, 0.0, 0.0);
|
||||
let horizontal = Vec3::new(viewport_width, 0.0, 0.0);
|
||||
let vertical = Vec3::new(0.0, viewport_height, 0.0);
|
||||
let w = Vec3::unit_vector(lookfrom - lookat);
|
||||
let u = Vec3::unit_vector(Vec3::cross(vup, w));
|
||||
let v = Vec3::cross(w, u);
|
||||
|
||||
let origin = lookfrom;
|
||||
let horizontal = focus_dist * viewport_width * u;
|
||||
let vertical = focus_dist * viewport_height * v;
|
||||
let lower_left_corner = origin - horizontal/2.0 - vertical/2.0 - focus_dist*w;
|
||||
|
||||
let lens_radius = aperture / 2.0;
|
||||
|
||||
return Camera {
|
||||
origin,
|
||||
horizontal,
|
||||
vertical,
|
||||
lower_left_corner: origin
|
||||
- horizontal / 2.0
|
||||
- vertical / 2.0
|
||||
- Vec3::new(0.0, 0.0, focal_length),
|
||||
lower_left_corner,
|
||||
u,
|
||||
v,
|
||||
w,
|
||||
lens_radius,
|
||||
};
|
||||
}
|
||||
|
||||
pub fn get_ray(&self, u: f64, v: f64) -> Ray {
|
||||
Ray::new(
|
||||
self.origin,
|
||||
self.lower_left_corner + u * self.horizontal + v * self.vertical - self.origin,
|
||||
|
||||
let rd = self.lens_radius * Vec3::random_in_unit_disk();
|
||||
let offset = rd.x() * self.u + rd.y() * self.v;
|
||||
|
||||
return Ray::new(
|
||||
self.origin + offset,
|
||||
self.lower_left_corner + u * self.horizontal + v * self.vertical - self.origin - offset,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
130
src/main.rs
130
src/main.rs
|
@ -44,50 +44,92 @@ fn ray_color(r: &Ray, world: &HittableList, depth: u32) -> Color {
|
|||
return (1.0 - t) * Color::new(1.0, 1.0, 1.0) + t * Color::new(0.5, 0.7, 1.0);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// File
|
||||
let mut default_file = "image.ppm";
|
||||
|
||||
// Image
|
||||
let aspect_ratio = 16.0 / 9.0;
|
||||
let image_width = 1000;
|
||||
let image_height = (image_width as f64 / aspect_ratio) as u32;
|
||||
let samples_per_pixel = 100_u32;
|
||||
let max_depth = 50;
|
||||
|
||||
// World
|
||||
fn random_world() -> HittableList {
|
||||
let mut world = HittableList::new();
|
||||
|
||||
let material_ground = Arc::new(Lambertian::new(&Color::new(0.2, 0.3, 0.0)));
|
||||
let material_center = Arc::new(Lambertian::new(&Color::new(0.7, 0.1, 0.2)));
|
||||
let material_ground = Arc::new(Lambertian::new(&Color::new(0.1, 0.1, 0.1)));
|
||||
|
||||
//let material_center = Arc::new(Lambertian::new(&Color::new(0.7, 0.1, 0.2)));
|
||||
//let material_center = Arc::new(Dielectric::new(1.5));
|
||||
let material_blue = Arc::new(Lambertian::new(&Color::new(0.2, 0.1, 0.7)));
|
||||
let material_metal = Arc::new(Metal::new(&Color::new(0.8, 0.8, 0.8), 0.1));
|
||||
let material_metal_fuzz = Arc::new(Metal::new(&Color::new(0.8, 0.8, 0.8), 1.0));
|
||||
let material_mirror = Arc::new(Metal::new(&Color::new(0.8, 0.8, 0.8), 0.0));
|
||||
let material_dielectric = Arc::new(Dielectric::new(1.5));
|
||||
let material_light = Arc::new(Lambertian::new(&Color::new(2.0, 1.0, 0.0)));
|
||||
//let material_blue = Arc::new(Lambertian::new(&Color::new(0.2, 0.1, 0.7)));
|
||||
//let material_metal = Arc::new(Metal::new(&Color::new(0.8, 0.8, 0.8), 0.1));
|
||||
//let material_metal_fuzz = Arc::new(Metal::new(&Color::new(0.8, 0.8, 0.8), 1.0));
|
||||
//let material_mirror = Arc::new(Metal::new(&Color::new(0.8, 0.8, 0.8), 0.0));
|
||||
//let material_dielectric = Arc::new(Dielectric::new(1.5));
|
||||
//let material_light = Arc::new(Lambertian::new(&Color::new(2.0, 1.0, 0.0)));
|
||||
|
||||
|
||||
|
||||
|
||||
world.add(Box::<Sphere>::new(Sphere::new(
|
||||
Point3::new(0.0, -100.5, -1.0),
|
||||
100.0,
|
||||
Point3::new(0.0, -1000.0, 0.0),
|
||||
1000.0,
|
||||
material_ground.clone(),
|
||||
)));
|
||||
|
||||
(-6..5).into_iter().for_each(|a| {
|
||||
(-6..5).into_iter().for_each(|b| {
|
||||
let choose_mat = utility::random_f64();
|
||||
let center = Point3::new(a as f64 + 0.9 * utility::random_f64(), 0.2, b as f64 + 0.9 * utility::random_f64());
|
||||
if (center - Point3::new(4.0, 0.2, 0.0)).length() > 0.9 {
|
||||
if choose_mat < 0.8 { // diffuse
|
||||
let sphere_material = Arc::new(Lambertian::new(&(Color::random_f64() * Color::random_f64())));
|
||||
world.add(Box::<Sphere>::new(Sphere::new(
|
||||
center,
|
||||
0.2,
|
||||
sphere_material.clone()
|
||||
)));
|
||||
} else if choose_mat < 0.95 { // metal
|
||||
let sphere_material = Arc::new(Metal::new(&Color::random_rng(0.5, 1.0), utility::random_rng(0.0, 0.5)));
|
||||
world.add(Box::<Sphere>::new(Sphere::new(
|
||||
center,
|
||||
0.2,
|
||||
sphere_material.clone()
|
||||
)));
|
||||
} else { // glass
|
||||
let sphere_material = Arc::new(Dielectric::new(1.5));
|
||||
world.add(Box::<Sphere>::new(Sphere::new(
|
||||
center,
|
||||
0.2,
|
||||
sphere_material.clone()
|
||||
)));
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
let material1 = Arc::new(Dielectric::new(1.5));
|
||||
let material3 = Arc::new(Metal::new(&Color::new(0.7, 0.6, 0.5), 0.0));
|
||||
let material2 = Arc::new(Lambertian::new(&Color::new(0.4, 0.2, 0.1)));
|
||||
|
||||
world.add(Box::<Sphere>::new(Sphere::new(
|
||||
Point3::new(0.0, 0.0, -1.0),
|
||||
0.5,
|
||||
material_center.clone(),
|
||||
Point3::new(0.0, 1.0, 0.0),
|
||||
1.0,
|
||||
material2.clone(),
|
||||
)));
|
||||
|
||||
world.add(Box::<Sphere>::new(Sphere::new(
|
||||
Point3::new(-1.0, -0.15, -1.0),
|
||||
0.5,
|
||||
Point3::new(-4.0, 1.0, 0.0),
|
||||
1.0,
|
||||
material1.clone(),
|
||||
)));
|
||||
|
||||
world.add(Box::<Sphere>::new(Sphere::new(
|
||||
Point3::new(4.0, 1.0, 0.0),
|
||||
1.0,
|
||||
material3.clone(),
|
||||
)));
|
||||
|
||||
/*
|
||||
world.add(Box::<Sphere>::new(Sphere::new(
|
||||
Point3::new(-2.0*r, 0.1, -2.0),
|
||||
r,
|
||||
material_dielectric.clone(),
|
||||
)));
|
||||
world.add(Box::<Sphere>::new(Sphere::new(
|
||||
Point3::new(1.0, 0.0, -1.0),
|
||||
-0.4,
|
||||
Point3::new(r, 0.0, -1.0),
|
||||
r,
|
||||
material_dielectric.clone(),
|
||||
)));
|
||||
world.add(Box::<Sphere>::new(Sphere::new(
|
||||
|
@ -97,7 +139,7 @@ fn main() {
|
|||
)));
|
||||
world.add(Box::<Sphere>::new(Sphere::new(
|
||||
Point3::new(-0.5, 0.5, 1.0),
|
||||
1.0,
|
||||
0.4,
|
||||
material_blue.clone(),
|
||||
)));
|
||||
world.add(Box::<Sphere>::new(Sphere::new(
|
||||
|
@ -105,6 +147,8 @@ fn main() {
|
|||
0.3,
|
||||
material_light.clone(),
|
||||
)));
|
||||
*/
|
||||
|
||||
/*
|
||||
for i in -15..15 {
|
||||
for j in -15..15 {
|
||||
|
@ -113,8 +157,32 @@ fn main() {
|
|||
}
|
||||
*/
|
||||
|
||||
return world;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// File
|
||||
let mut default_file = "image.ppm";
|
||||
|
||||
// Image
|
||||
let aspect_ratio = 16.0 / 9.0;
|
||||
let image_width = 1920;
|
||||
let image_height = (image_width as f64 / aspect_ratio) as u32;
|
||||
let samples_per_pixel = 100_u32;
|
||||
let max_depth = 50;
|
||||
|
||||
let vfov = 20.0;
|
||||
let lookfrom = Point3::new(10.0, 10.0, 13.0);
|
||||
let lookat = Point3::new(0.0, 0.0, 0.0);
|
||||
let vup = Vec3::new(0.0, 1.0, 0.0);
|
||||
let dist_to_focus = 15.0;
|
||||
let aperture = 0.1;
|
||||
|
||||
// World
|
||||
let world = random_world();
|
||||
|
||||
// Camera
|
||||
let cam = Camera::new();
|
||||
let cam = Camera::new(lookfrom, lookat, vup, vfov, aspect_ratio, aperture, dist_to_focus);
|
||||
|
||||
// Render
|
||||
let args: Vec<String> = env::args().collect();
|
||||
|
|
|
@ -22,4 +22,4 @@ pub fn clamp(x: f64, min: f64, max: f64) -> f64 {
|
|||
return max;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
}
|
12
src/vec3.rs
12
src/vec3.rs
|
@ -83,7 +83,17 @@ impl Vec3 {
|
|||
let p = Vec3::random_rng(-1.0, 1.0);
|
||||
if p.length_squared() >= 1.0 {
|
||||
continue;
|
||||
};
|
||||
}
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn random_in_unit_disk() -> Self {
|
||||
loop {
|
||||
let p = Vec3::new(utility::random_rng(-1.0, 1.0), utility::random_rng(-1.0, 1.0), 0.0);
|
||||
if p.length_squared() >= 1.0 {
|
||||
continue;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue