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}