Inderjit Gill 11 months ago
parent
commit
8645dc93d3
4 changed files with 73 additions and 25 deletions
  1. 29
    0
      Cargo.lock
  2. 1
    0
      Cargo.toml
  3. 41
    25
      src/main.rs
  4. 2
    0
      src/types.rs

+ 29
- 0
Cargo.lock View File

@@ -108,6 +108,14 @@ dependencies = [
108 108
 ]
109 109
 
110 110
 [[package]]
111
+name = "cloudabi"
112
+version = "0.0.3"
113
+source = "registry+https://github.com/rust-lang/crates.io-index"
114
+dependencies = [
115
+ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
116
+]
117
+
118
+[[package]]
111 119
 name = "color_quant"
112 120
 version = "1.0.1"
113 121
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -399,6 +407,23 @@ dependencies = [
399 407
 ]
400 408
 
401 409
 [[package]]
410
+name = "rand"
411
+version = "0.5.5"
412
+source = "registry+https://github.com/rust-lang/crates.io-index"
413
+dependencies = [
414
+ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
415
+ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
416
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
417
+ "rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
418
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
419
+]
420
+
421
+[[package]]
422
+name = "rand_core"
423
+version = "0.2.1"
424
+source = "registry+https://github.com/rust-lang/crates.io-index"
425
+
426
+[[package]]
402 427
 name = "ray-tracer"
403 428
 version = "0.1.0"
404 429
 dependencies = [
@@ -408,6 +433,7 @@ dependencies = [
408 433
  "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
409 434
  "image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
410 435
  "log 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
436
+ "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
411 437
 ]
412 438
 
413 439
 [[package]]
@@ -611,6 +637,7 @@ dependencies = [
611 637
 "checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3"
612 638
 "checksum cgmath 0.16.1 (registry+https://github.com/rust-lang/crates.io-index)" = "64a4b57c8f4e3a2e9ac07e0f6abc9c24b6fc9e1b54c3478cfb598f3d0023e51c"
613 639
 "checksum clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b957d88f4b6a63b9d70d5f454ac8011819c6efa7727858f458ab71c756ce2d3e"
640
+"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
614 641
 "checksum color_quant 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd"
615 642
 "checksum crossbeam-deque 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f739f8c5363aca78cfb059edf753d8f0d36908c348f3d8d1503f03d8b75d9cf3"
616 643
 "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
@@ -646,6 +673,8 @@ dependencies = [
646 673
 "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0"
647 674
 "checksum quote 0.6.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ed7d650913520df631972f21e104a4fa2f9c82a14afc65d17b388a2e29731e7c"
648 675
 "checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd"
676
+"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
677
+"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2"
649 678
 "checksum rayon 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "df7a791f788cb4c516f0e091301a29c2b71ef680db5e644a7d68835c8ae6dbfa"
650 679
 "checksum rayon-core 1.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b055d1e92aba6877574d8fe604a63c8b5df60f60e5982bf7ccbb1338ea527356"
651 680
 "checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"

+ 1
- 0
Cargo.toml View File

@@ -10,3 +10,4 @@ failure = "0.1.2"
10 10
 clap = "2.32.0"
11 11
 image = "0.19.0"
12 12
 cgmath = "0.16.1"
13
+rand = "0.5.5"

+ 41
- 25
src/main.rs View File

@@ -9,6 +9,9 @@ extern crate image;
9 9
 //#[macro_use]
10 10
 extern crate cgmath;
11 11
 extern crate log;
12
+extern crate rand;
13
+
14
+use rand::prelude::*;
12 15
 
13 16
 mod error;
14 17
 mod ray;
@@ -74,8 +77,6 @@ fn main() -> Result<()> {
74 77
         return Err(RayTracerError::CommandLineParsingError);
75 78
     }
76 79
 
77
-    ray_trace_main(width, height)?;
78
-
79 80
     // cargo run -- -w 100 -h 120 -o foo.png
80 81
 
81 82
     let img = ray_trace_main(width, height)?;
@@ -90,22 +91,28 @@ fn ray_trace_main(width: u32, height: u32) -> Result<(RgbaImage)> {
90 91
     // create the combined image
91 92
     let mut img: RgbaImage = ImageBuffer::new(width, height);
92 93
 
93
-    let lower_left_corner = V3::new(-2.0, -1.0, -1.0);
94
-    let horizontal = V3::new(4.0, 0.0, 0.0);
95
-    let vertical = V3::new(0.0, 2.0, 0.0);
96
-    let origin = V3::new(0.0, 0.0, 0.0);
94
+    let ns = 100;
97 95
 
98 96
     let mut world = HitableList::new();
99 97
     world.add_sphere(Sphere::new(V3::new(0.0, 0.0, -1.0), 0.5));
100 98
     world.add_sphere(Sphere::new(V3::new(0.0, -100.5, -1.0), 100.0));
101 99
 
100
+    let cam = Camera::new();
101
+
102 102
     for y in 0..height {
103 103
         for x in 0..width {
104
-            let u = x as f32 / width as f32;
105
-            let v = y as f32 / height as f32;
106 104
 
107
-            let r = Ray::new(origin, lower_left_corner + u * horizontal + v * vertical);
108
-            let col = colour(&r, &world);
105
+            let mut col = V3::new(0.0, 0.0, 0.0);
106
+
107
+            for _ in 0..ns {
108
+                let u = ((x as S) + random::<S>()) / width as S;
109
+                let v = ((y as S) + random::<S>()) / height as S;
110
+
111
+                let r = cam.get_ray(u, v);
112
+                col = col + colour(&r, &world);
113
+            }
114
+
115
+            col /= ns as S;
109 116
 
110 117
             // ray tracing origin is in lower left, image buffer origin is in top left
111 118
             // so vertically flip image
@@ -127,20 +134,6 @@ fn rgba_from_v3(v: V3) -> Rgba<u8> {
127 134
     }
128 135
 }
129 136
 
130
-fn hit_sphere(center: V3, radius: S, r: &Ray) -> S {
131
-    let oc = r.origin() - center;
132
-    let a = r.direction().dot(r.direction());
133
-    let b = 2.0 * oc.dot(r.direction());
134
-    let c = oc.dot(oc) - radius * radius;
135
-    let discriminant = b*b - 4.0*a*c;
136
-
137
-    if discriminant < 0.0 {
138
-        -1.0
139
-    } else {
140
-        (-b - discriminant.sqrt()) / (2.0 * a)
141
-    }
142
-}
143
-
144 137
 #[derive(Debug, Clone, Copy)]
145 138
 struct HitRecord {
146 139
     t: S,
@@ -235,8 +228,31 @@ impl Hitable for HitableList {
235 228
     }
236 229
 }
237 230
 
231
+struct Camera {
232
+    lower_left_corner: V3,
233
+    horizontal: V3,
234
+    vertical: V3,
235
+    origin: V3,
236
+}
237
+
238
+impl Camera {
239
+    fn new() -> Self {
240
+        Camera {
241
+            lower_left_corner: V3::new(-2.0, -1.0, -1.0),
242
+            horizontal: V3::new(4.0, 0.0, 0.0),
243
+            vertical: V3::new(0.0, 2.0, 0.0),
244
+            origin: V3::new(0.0, 0.0, 0.0),
245
+        }
246
+    }
247
+
248
+    pub fn get_ray(&self, u: S, v: S) -> Ray {
249
+        Ray::new(self.origin,
250
+                 self.lower_left_corner + u * self.horizontal + v * self.vertical - self.origin)
251
+    }
252
+}
253
+
238 254
 fn colour(ray: &Ray, world: &Hitable) -> V3 {
239
-    if let Some(hit_record) = world.hit(ray, 0.0, 10000.0) {
255
+    if let Some(hit_record) = world.hit(ray, 0.0, S_MAX) {
240 256
         0.5 * V3::new(hit_record.normal.x + 1.0,
241 257
                       hit_record.normal.y + 1.0,
242 258
                       hit_record.normal.z + 1.0)

+ 2
- 0
src/types.rs View File

@@ -1,6 +1,8 @@
1
+use std::f32;
1 2
 use cgmath::*;
2 3
 
3 4
 // scalar
4 5
 pub type S = f32;
6
+pub const S_MAX: S = f32::MAX;
5 7
 
6 8
 pub type V3 = Vector3<S>;

Loading…
Cancel
Save