Skip to main content

solstrale/
lib.rs

1#![warn(missing_docs)]
2//! A WGPU-based GPU Monte Carlo path tracing library, with features like:
3//!
4//! ### Core Engine
5//! * Global illumination
6//! * Caustics
7//! * Reflection
8//! * Refraction
9//! * Soft shadows
10//! * Bump mapping
11//! * Light attenuation
12//!
13//! ### Performance & Loading
14//! * Loading of obj models with included materials
15//! * Multithreaded BVH creation using Rayon to greatly speed up rendering
16//!
17//! ### Post-Processing
18//! Custom GPU-accelerated filters implemented as compute shaders via [WGPU](https://wgpu.rs/):
19//! * Bloom filter
20//! * Saturation filter
21//!
22//! ## Example:
23//! ```rust
24//! # use std::sync::mpsc::channel;
25//! # use std::thread;
26//! # use image::RgbImage;
27//! # use solstrale::camera::CameraConfig;
28//! # use solstrale::geo::vec3::Vec3;
29//! # use solstrale::hittable::{Bvh, Sphere, Hittable, Hittables};
30//! # use solstrale::material::{DiffuseLight, Lambertian};
31//! # use solstrale::material::texture::SolidColor;
32//! # use solstrale::ray_trace;
33//! # use solstrale::renderer::{RenderConfig, Scene};
34//! # use solstrale::util::wgpu_util::get_wgpu_device_and_queue;
35//! let camera = CameraConfig {
36//!     vertical_fov_degrees: 20.,
37//!     aperture_size: 0.1,
38//!     look_from: Vec3::new(0., 0., 4.),
39//!     look_at: Vec3::new(0., 0., 0.),
40//!     up: Vec3::new(0., 1., 0.),
41//! };
42//! let mut world: Vec<Hittables> = Vec::new();
43//! let yellow = Lambertian::new(SolidColor::new(1., 1., 0.).into(), None);
44//! let light = DiffuseLight::new(10., 10., 10., None);
45//! world.push(Sphere::new(Vec3::new(0., 0., 0.), 0.5, yellow.into()).into());
46//!
47//! let scene = Scene {
48//!     world: Bvh::new(world).into(),
49//!     camera,
50//!     background_color: Vec3::new(0.2, 0.3, 0.5),
51//!     render_config: RenderConfig::default(),
52//! };
53//!
54//! let (device, queue) = get_wgpu_device_and_queue();
55//!
56//! let (output_sender, output_receiver) = channel();
57//! let (_, camera_config_receiver) = channel();
58//! let (_, abort_receiver) = channel();
59//!
60//! thread::spawn(move || {
61//!     ray_trace(scene, &output_sender, &camera_config_receiver, &abort_receiver, &device, &queue, false).unwrap();
62//! });
63//!
64//! for render_output in output_receiver {
65//!     let _buffer = render_output.output_buffer;
66//! }
67//! ```
68//!
69//! ## Example output
70//! ![bedroom2](https://github.com/DanielPettersson/solstrale-rust/assets/3603911/a78e4a85-2acb-409f-b7f4-4f6c5afb797e)
71//! ![conference](https://github.com/DanielPettersson/solstrale-rust/assets/3603911/8c88c777-0b85-4854-bd14-10a999bb3f78)
72//! ![happy](https://github.com/DanielPettersson/solstrale-rust/assets/3603911/c5357792-a3dc-42f9-8230-320140f9c30e)
73//! ![sponza-bump2](https://github.com/DanielPettersson/solstrale-rust/assets/3603911/0ab79ed9-cddf-46b1-84e7-03cef35f5600)
74
75//! ## Credits
76//! The ray tracing is inspired by the excellent [Ray Tracing in One Weekend Book Series](https://github.com/RayTracing/raytracing.github.io) by Peter Shirley
77
78use crate::renderer::{RenderProgress, Scene};
79use renderer::Renderer;
80use std::error::Error;
81use std::sync::mpsc::{Receiver, Sender};
82
83pub mod camera;
84pub mod geo;
85pub mod hittable;
86pub mod loader;
87pub mod material;
88pub mod post;
89pub mod renderer;
90pub mod util;
91
92/// Executes the ray tracing with the given [`Scene`] and reports [`RenderProgress`] on
93/// the output [`Sender`]. Listens to abort [`Receiver`] for aborting a started ray trace operation
94///
95/// # Arguments
96/// * `scene` - A scene describing how, and what should be rendered
97/// * `output` - Channel where render progress will be sent
98/// * `camera_config` - Channel to send updated camera configurations
99/// * `abort` - Channel to send abort signals to the renderer
100/// * `idle` - If true, the renderer will keep listening for camera updates after finishing the initial samples
101pub fn ray_trace<'a>(
102    scene: Scene,
103    output: &'a Sender<RenderProgress>,
104    camera_config: &'a Receiver<crate::camera::CameraConfig>,
105    abort: &'a Receiver<bool>,
106    device: &wgpu::Device,
107    queue: &wgpu::Queue,
108    idle: bool,
109) -> Result<(), Box<dyn Error>> {
110    Renderer::new(scene, device, queue)?.render(output, camera_config, abort, idle)
111}