#raytracing #raytracer #ray-tracing #path-tracer

smallpt

A small ray/pathtracer in Rust, inspired by Kevin Beason’s educational 99-lines ray/pathtracer (http://www.kevinbeason.com/smallpt/)

15 releases

0.2.1 Jul 3, 2018
0.2.0 Jul 3, 2018
0.1.12 Jun 24, 2018

#18 in Rendering

Download history 53/week @ 2018-07-18 20/week @ 2018-07-25 46/week @ 2018-08-01 80/week @ 2018-08-08 123/week @ 2018-08-15 39/week @ 2018-08-22 3/week @ 2018-08-29 6/week @ 2018-09-05 20/week @ 2018-09-12 3/week @ 2018-09-19 35/week @ 2018-09-26 18/week @ 2018-10-03 5/week @ 2018-10-10

190 downloads per month

MIT license

1MB
568 lines

license Crates.io Build Status

A Rust implementation of a small ray/pathtracer.

Inspired by Kevin Beason's educational 99-line raytracer/pathtracer.

alt text

Supports:

  • Ray-to-Sphere
  • Ray-to-Plane
  • Ray-to-Rectangle
  • Ray-to-Triangle (slow, no acceleration yet. Soon)

Usage

# Cargo.toml
[dependencies]
smallpt = "0.2.0"

Example

extern crate smallpt;
use smallpt::*;

let mut scene = Scene::init();

// Spheres
// Mirror
scene.add(Box::new(Sphere::new(
    16.5,
    Vec3::new(27.0, 16.5, 47.0),
    Material::new(Vec3::zero(), Vec3::new(1.0, 1.0, 1.0), BSDF::Mirror),
)));

// Glass
scene.add(Box::new(Sphere::new(
    16.5,
    Vec3::new(73.0, 16.5, 78.0),
    Material::new(Vec3::zero(), Vec3::new(1.0, 1.0, 1.0), BSDF::Glass),
)));

// Planes
// Bottom
scene.add(Box::new(Plane::new(
    Vec3::new(0.0, 0.0, 0.0),
    Vec3::new(0.0, 1.0, 0.0),
    Material::new(Vec3::zero(), Vec3::new(0.75, 0.75, 0.75), BSDF::Diffuse),
)));

// Left
scene.add(Box::new(Plane::new(
    Vec3::new(1.0, 0.0, 0.0),
    Vec3::new(1.0, 0.0, 0.0),
    Material::new(Vec3::zero(), Vec3::new(0.75, 0.25, 0.25), BSDF::Diffuse),
)));

// Right
scene.add(Box::new(Plane::new(
    Vec3::new(99.0, 0.0, 0.0),
    Vec3::new(-1.0, 0.0, 0.0),
    Material::new(Vec3::zero(), Vec3::new(0.25, 0.25, 0.75), BSDF::Diffuse),
)));

// Front
scene.add(Box::new(Plane::new(
    Vec3::new(0.0, 0.0, 0.0),
    Vec3::new(0.0, 0.0, 1.0),
    Material::new(Vec3::zero(), Vec3::new(0.75, 0.75, 0.75), BSDF::Diffuse),
)));

// Back
scene.add(Box::new(Plane::new(
    Vec3::new(0.0, 0.0, 170.0),
    Vec3::new(0.0, 0.0, -1.0),
    Material::new(Vec3::zero(), Vec3::zero(), BSDF::Diffuse),
)));

// Top
scene.add(Box::new(Plane::new(
    Vec3::new(0.0, 81.6, 0.0),
    Vec3::new(0.0, -1.0, 0.0),
    Material::new(Vec3::zero(), Vec3::new(0.75, 0.75, 0.75), BSDF::Diffuse),
)));

// Light (emissive rectangle)
scene.add(Box::new(Rectangle::new(
    Vec3::new(50.0, 81.5, 50.0),
    Vec3::new(0.0, -1.0, 0.0),
    Vec3::new(1.0, 0.0, 0.0),
    Vec3::new(0.0, 0.0, 1.0),
    33.0,
    33.0,
    Material::new(Vec3::new(12.0, 12.0, 12.0), Vec3::zero(), BSDF::Diffuse),
)));

// Light (emissive rectangle)
scene.add(Box::new(Rectangle::new(
    Vec3::new(50.0, 81.5, 50.0),
    Vec3::new(0.0, -1.0, 0.0),
    Vec3::new(1.0, 0.0, 0.0),
    Vec3::new(0.0, 0.0, 1.0),
    33.0,
    33.0,
    Material::new(Vec3::new(12.0, 12.0, 12.0), Vec3::zero(), BSDF::Diffuse),
)));    

let aperture = 0.5135;
let camera_origin = Vec3::new(50.0, 50.0, 300.0);
let camera_direction = Vec3::new(0.0, -0.05, -1.0).normalize();
let camera_right = Vec3::new(width as f32 * aperture / height as f32, 0.0, 0.0);
let camera_up = camera_right.cross(camera_direction).normalize() * aperture;

let camera = Camera::new(camera_origin, camera_direction, camera_right, camera_up);

// Render
let num_samples = 16;
let width = 512;
let height = 512;
let mut num_rays = 0;
let mut backbuffer = vec![Vec3::zero(); width * height];   
trace(&scene, &camera, width, height, num_samples, &mut backbuffer, &mut num_rays);

Status

Code is still quite in flux, being refined on a weekly basis. More simplification and changes coming soon.

Dependencies

~3MB
~62K SLoC