rustic-zen 0.3.0

Photon-Garden raytracer for creating artistic renderings
Documentation
extern crate png;
extern crate rand;
extern crate rustic_zen;

use std::fs::File;
use std::io::BufWriter;
use std::path::Path;
use std::sync::Arc;
use std::time;
// To use encoder.set()
use png::HasParameters;

use rand::Rng;
//Scene Parameters
use rustic_zen::prelude::*;

fn laser<R: Rng>(angle: f64, wavelength: f64) -> Light<R> {
    Light::new(
        (180.0, 80.0),
        1.0,
        (2.0, 0.0),
        (360.0, 0.0),
        angle,
        wavelength,
    )
}

#[cfg(feature = "gpu")]
fn main() {
    //Initialising scene!
    let now = time::Instant::now();
    let width: f64 = 1920.0 * 1.0;
    let height: f64 = 1080.0 * 1.0;
    let rays = 1000_000; //(width * height).round() as usize;
    let mut image = Arc::new(VulkanImage::new(width as usize, height as usize));

    let wall_m = material::hqz_legacy(1.0, 0.0, 0.0);
    let floor_m = material::hqz_legacy(0.1, 0.3, 0.5);

    let top = Segment::line_from_points((0.0, 0.0), (width, 0.0), wall_m.clone());

    let bottom = Segment::line_from_points((0.0, height), (width, height), wall_m.clone());

    let left = Segment::line_from_points((0.0, 0.0), (0.0, height), wall_m.clone());

    let right = Segment::line_from_points((width, 0.0), (width, height), wall_m.clone());

    let floor = Segment::line_from_points(
        (0.0, height * 0.72),
        (width, ((height * 0.72) + 70.0, (height * 0.72) - 20.0)),
        floor_m,
    );

    let r = Scene::new(width as usize, height as usize)
        .with_light(laser(30.0, 694.0))
        .with_light(laser(31.0, 676.0))
        .with_light(laser(32.0, 647.0))
        .with_light(laser(33.0, 635.0))
        .with_light(laser(34.0, 633.0))
        .with_light(laser(35.0, 628.0))
        .with_light(laser(36.0, 612.0))
        .with_light(laser(37.0, 594.0))
        .with_light(laser(38.0, 578.0))
        .with_light(laser(39.0, 568.0))
        .with_light(laser(40.0, 543.0))
        .with_light(laser(41.0, 532.0))
        .with_light(laser(42.0, 530.0))
        .with_light(laser(43.0, 514.0))
        .with_light(laser(44.0, 511.0))
        .with_light(laser(45.0, 501.0))
        .with_light(laser(46.0, 496.0))
        .with_light(laser(47.0, 488.0))
        .with_light(laser(48.0, 475.0))
        .with_light(laser(49.0, 458.0))
        .with_light(laser(50.0, 442.0))
        .with_light(laser(51.0, 428.0))
        .with_light(laser(52.0, 416.0))
        .with_object(floor)
        .with_object(top)
        .with_object(bottom)
        .with_object(left)
        .with_object(right);
    let setup = now.elapsed();

    println!("Tracing {} rays, on the GPU!\n", rays);
    let now = time::Instant::now();
    let rays = r.render(RenderConstraint::Count(rays), 24, &mut image);
    let tracing = now.elapsed();

    //Downsampling Image!
    let now: time::Instant = time::Instant::now();
    let data = image.to_rgba8(rays, 0.7, 1.0 / 2.2); //1.0/2.2
    let downsampling = now.elapsed();

    //Saving!
    let path = Path::new("laser-rainbow-gpu.png");
    let file = File::create(path).unwrap();
    let ref mut w = BufWriter::new(file);

    let mut encoder = png::Encoder::new(w, width as u32, height as u32);
    encoder.set(png::ColorType::RGBA).set(png::BitDepth::Eight);
    let mut writer = encoder.write_header().unwrap();
    writer.write_image_data(&data).unwrap();

    println!("\nTiming Summary:");
    println!("  Setup:        {}ms", setup.as_millis());
    println!("  Tracing:      {}ms", tracing.as_millis());
    println!("  Downsampling: {}ms\n", downsampling.as_millis());

    println!(
        "{} rays in {}ms: {}rays/s",
        rays,
        tracing.as_millis(),
        rays as f32 / (tracing.as_millis() as f32 / 1000.0)
    );
}

#[cfg(not(feature = "gpu"))]
fn main() {
    println!("Demo unavailable with GPU feature disabled")
}