# Crystal Ball [![Latest Version](https://img.shields.io/crates/v/crystal_ball.svg)](https://crates.io/crates/crystal_ball) [![API Documentation](https://docs.rs/crystal_ball/badge.svg)](https://docs.rs/crystal_ball) *Crystal Ball* is a path tracing library written in Rust. It uses [rayon](https://github.com/rayon-rs/rayon) for parallelization and can save the rendered image in various formats thanks to the [image](https://github.com/image-rs/image) crate. Note that Crystal Ball is a hobby project and will most likely see a lot of API changes in future versions. ![](demo.png) ## Features - Multithreaded CPU rendering - Save rendered images in [various formats](https://github.com/image-rs/image#supported-image-formats) - Environment textures - General purpose PBR material - Shapes: spheres and triangle meshes - Easily create your own textures, materials, and shapes - Load [glTF](https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html) files - Depth of field - Bounding Volume Hierarchies - Optional denoising using [Open Image Denoise](https://www.openimagedenoise.org/) ## Usage ### Basic Example A [basic example](examples/basic) rendering two spheres. ```rust use std::default::Default; use std::sync::Arc; use crystal_ball::prelude::*; fn main() -> Result<(), Error> { let objects = vec![ Object::new( Arc::new(Sphere::new()), Arc::new(PbrMaterial { base_color: Color::new(1.0, 0.45, 0.31), ..Default::default() }), ), Object::new( Arc::new( Sphere::new() .translate(Vec3::new(0.0, -101.0, 0.0)) .scale_xyz(Vec3::splat(100.0)), ), Arc::new(PbrMaterial::default()), ), ]; let scene = Scene { objects, camera: Camera::default().translate(Vec3::new(0.0, 0.0, 5.0)), ..Default::default() }; let engine = RenderEngine::default(); let image = engine.render(&scene); image.write("basic.png")?; Ok(()) } ``` This produces the following image: ![](examples/basic/render.png) There are many other examples showcasing Crystal Ball's capabilities, demonstrating how to use the different features. ### Coordinate System Crystal Ball uses a right-handed coordinate system where - +X points right - +Y points up - +Z points to the screen ### Denoising Crystal ball can optionally denoise rendered images using the [Rust bindings](https://github.com/Twinklebear/oidn-rs) for [Open Image Denoise](https://www.openimagedenoise.org/). To use this feature you need to [install Open Image Denoise](https://www.openimagedenoise.org/downloads.html) and set the environment variable `OIDN_DIR` to the root directory of the Open Image Denoise installation. Enable the `oidn` feature in your `Cargo.toml`: ```toml [dependencies.crystal_ball] version = "0.3.0" features = ["oidn"] ``` Now you can use the denoise method in your Rust code. ```rust fn main() -> Result<(), Error> { // ... let mut image = engine.render(&scene); image.denoise()?; image.write("image_denoised.png")?; } ``` ## Optimization The performance of your path tracing code will benefit greatly from compiler optimizations, at the cost of longer compile times. To easily switch between quick compilation and highly optimized code generation, you can put the following lines into your `Cargo.toml`. For a detailed explanation of what this does, see the [Cargo Book](https://doc.rust-lang.org/cargo/reference/profiles.html#profile-settings). ```toml [package] # ... [profile.dev] opt-level = 3 [profile.release] # Reduce binary size #panic = "abort" #strip = "symbols" # Improve performance but increase compile time lto = "fat" codegen-units = 1 ``` ## Feature Flags ### Optional Features | Name | description | |--------|-------------------------------------------------------------------------------| | `oidn` | Image denoising using [Open Image Denoise](https://www.openimagedenoise.org/) | ## References/Resources - https://raytracing.github.io/books/RayTracingInOneWeekend.html - https://github.com/ekzhang/rpt - https://tavianator.com/2014/ray_triangle.html - https://www.scratchapixel.com/lessons/3d-basic-rendering/ray-tracing-rendering-a-triangle/moller-trumbore-ray-triangle-intersection - https://en.wikipedia.org/wiki/Möller–Trumbore_intersection_algorithm - https://pbrt.org/ - https://www.rs-pbrt.org/