Skip to content

MartinKavik/ray_tracer

Repository files navigation

Raytracer on MoonZoon

Raytracer is implemented according to the tutorial Ray Tracing in One Weekend. It's a bit slow and single-threaded, but useful for learning.

MoonZoon is a Rust Fullstack Framework. It renders the HTML canvas and provides a server with auto-reloading for fast dev iteration loop.

Rendered image


How to start it

  1. Check you've installed Rust and wasm-pack:

    rustc -V # rustc 1.52.1 (9bc8c42bb 2021-05-09)
    wasm-pack -V # wasm-pack 0.9.1
    • Note: wasm-pack will be installed automatically in the future.
  2. Install mzoon to cargo_install_root:

    cargo install mzoon --git https://github.com/MoonZoon/MoonZoon --rev a6f5070 --root cargo_install_root --locked
    • Note: cargo install mzoon will be enough in the future. And there will be a faster way with pre-compiled binaries.
  3. Build and run:

    cargo_install_root/bin/mzoon start
    • Note: The app is much faster when built in the release mode (-r).

Problems in the tutorial

  1. Rotated image in some tutorial steps. Replace

    for j in 0..IMAGE_HEIGHT {
        eprintln!("Scanlines remaining: {}", IMAGE_HEIGHT - j - 1);

    with

    for j in (0..IMAGE_HEIGHT).rev() {
        eprintln!("Scanlines remaining: {}", j + 1);
  2. Missing Vec3 impl:

    impl Mul<Vec3> for Vec3 {
        type Output = Vec3;
    
        fn mul(self, other: Vec3) -> Vec3 {
            Vec3 {
                e: [self[0] * other[0], self[1] * other[1], self[2] * other[2]]
            }
        }
    }
  3. r0 * (1.0 - r0) corrected to r0 + (1.0 - r0):

    fn reflectance(cosine: f64, ref_idx: f64) -> f64 {
        // Use Schlick's approximation for reflectance
        let r0 = ((1.0 - ref_idx) / (1.0 + ref_idx)).powi(2);
        r0 + (1.0 - r0) * (1.0 - cosine).powi(5)
    }
  4. Change the value in const MAX_DEPTH: u64 = 5; to 50. (This and the previous correction fix black bubbles).

  5. There are some other problems in the tutorial but all of them should be easily fixed by the Rust compiler suggestions.


Notes

  • The random_scene function has been moved to scene.rs and renamed to scene.

  • The ray_color function has been moved to ray.rs as Ray::color.

  • main.rs rewritten to lib.rs.

  • There is an alternative raytracer described in the wasm-bindgen docs. I assume the raytracer is based on this tutorial: Writing a Raytracer in Rust.