rustic_zen/
lib.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5//! Photon Garden Raytracer Impementation.
6//!
7//! Rustic Zen renders artworks from a scene definition by simulating individual
8//! photons and tracing their path as they bounce through a 2D. space.
9//!
10//! Photons are generated by Lights and interact with Objects. Each interaction
11//! results in either the photon being absorbed, or being allowed to continue with
12//! a new direction, based on the rules defined by the Object's Material.
13//!
14//! # Example usage:
15//! ```
16//! extern crate rustic_zen;
17//! use rustic_zen::prelude::*;
18//! use rustic_zen::material::hqz_legacy;
19//! use std::sync::Arc;
20//!
21//! fn main() {
22//!     // Set up constants.
23//!     let width: f64 = 1920.0;
24//!     let height: f64 = 1080.0;
25//!
26//!     // Build a basic Material
27//!     let m = hqz_legacy(0.3, 0.3, 0.3);
28//!
29//!     // Build a basic Object
30//!     let o = Segment::line_from_points((0.0,(height * 0.75)), (width, (height * 0.75)), m);
31//!
32//!     // Build a basic Light
33//!     let l = Light::new((width / 2.0, height / 2.0), 1.0, 0.0, 0.0, (360.0, 0.0), Sampler::new_blackbody(5800.0));
34//!
35//!     // Construct a renderer object and add the light and object to it.
36//!     let s = Scene::new(width as usize, height as usize).with_object(o).with_light(l);
37//!
38//!     // Create an image to render into.
39//!     let mut i = Arc::new(Image::new(width as usize, height as usize));
40//!
41//!     // Render Image
42//!     println!("Tracing Rays");
43//!     let rays = s.render(RenderConstraint::TimeMS(1000), 1, &mut i);
44//!     // this call should probably be more like 5000 - 15000 ms and use your number of threads,
45//!     // but this example is run by various CI tools, and tests can't take too long.
46//!
47//!     // Output the Image as a Vec<u8>
48//!     println!("Serializing!");
49//!     let data = i.to_rgba8(rays, 0.7, 1.2);
50//!     
51//!     // Do Export to a PNG or whatever you want here.
52//! }
53//! ```
54//!
55#![warn(missing_docs)]
56pub mod geom;
57pub mod image;
58pub mod material;
59pub mod sampler;
60pub mod scene;
61
62/// This prelude contains everything to quickstart using Rustic Zen.
63pub mod prelude {
64    pub use crate::geom::{Point, Vector};
65    pub use crate::image::ExportImage;
66    pub use crate::material;
67    pub use crate::sampler::Sampler;
68    pub use crate::scene::{Light, RenderConstraint, Scene, Segment};
69
70    pub use crate::image::Image;
71    #[cfg(feature = "gpu")]
72    pub use crate::image::VulkanImage;
73
74    pub use rand::prelude::*;
75}
76
77mod ray;
78mod spectrum;
79
80#[cfg(test)]
81mod tests {
82    #[test]
83    fn it_works() {
84        assert_eq!(2 + 2, 4);
85    }
86
87    // For reading and opening files
88    use std::fs::File;
89    use std::io::BufWriter;
90    use std::path::Path;
91    use std::sync::Arc;
92    // To use encoder.set()
93    use png::HasParameters;
94
95    //Scene Parameters
96    use crate::image::ExportImage;
97    use crate::image::Image;
98    use crate::material::hqz_legacy_default;
99    use crate::sampler::Sampler;
100    use crate::scene::Light;
101    use crate::scene::RenderConstraint;
102    use crate::scene::Scene;
103    use crate::scene::Segment;
104
105    #[test]
106    fn png_test() {
107        let width = 1024.0;
108        let height = 1024.0;
109
110        let l = Light::new(
111            (512.0, 512.0),
112            1.0,
113            0.0,
114            0.0,
115            (360.0, 0.0),
116            Sampler::new_blackbody(6900.0),
117        );
118
119        let r = Scene::new(width as usize, height as usize).with_light(l);
120
121        let mut image = Arc::new(Image::new(width as usize, height as usize));
122
123        let rays = r.render(RenderConstraint::TimeMS(1000), 1, &mut image);
124
125        let data = image.to_rgba8(rays, 0.5, 0.5);
126        //let data = image.dumb_to_rgb8();
127
128        let path = Path::new(r"lib.png_test.png");
129        let file = File::create(path).unwrap();
130        let ref mut w = BufWriter::new(file);
131
132        let mut encoder = png::Encoder::new(w, 1024, 1024);
133        encoder.set(png::ColorType::RGBA).set(png::BitDepth::Eight);
134        let mut writer = encoder.write_header().unwrap();
135        writer.write_image_data(&data).unwrap(); // Save
136    }
137
138    #[test]
139    fn png_test_2() {
140        let width: f64 = 1024.0;
141        let height: f64 = 1024.0;
142
143        let o = Segment::line_from_points(
144            (0.0, height * 0.75),
145            (width, height * 0.75),
146            hqz_legacy_default(),
147        );
148
149        let l = Light::new(
150            (width / 2.0, height / 2.0),
151            1.0,
152            0.0,
153            0.0,
154            (360.0, 0.0),
155            Sampler::new_blackbody(6900.0),
156        );
157
158        let r = Scene::new(width as usize, height as usize)
159            .with_light(l)
160            .with_object(o);
161
162        let mut image = Arc::new(Image::new(width as usize, height as usize));
163
164        let rays = r.render(RenderConstraint::TimeMS(1000), 2, &mut image);
165
166        let data = image.to_rgba8(rays, 0.5, 0.5);
167
168        let path = Path::new(r"lib.png_test_2.png");
169        let file = File::create(path).unwrap();
170        let ref mut w = BufWriter::new(file);
171
172        let mut encoder = png::Encoder::new(w, 1024, 1024);
173        encoder.set(png::ColorType::RGBA).set(png::BitDepth::Eight);
174        let mut writer = encoder.write_header().unwrap();
175        writer.write_image_data(&data).unwrap(); // Save
176    }
177}