crystal_ball

Crystal Ball is a path tracing library written in Rust. It uses rayon for parallelization and can save the rendered image in various formats thanks to the image crate.

Features

Usage

Getting Started

Create a new project:

cargo init [project-name] cd [project-name]

Add crystal_ball = 0.1.0 to the [dependencies] section of the Cargo.toml file.

Replace the content of src/main.rs with the following minimal example:

```rust use std::path::Path;

use crystal_ball::prelude::*;

fn main() { let objects = vec![ Sphere::new() .withcenter(Vec3::new(0.0, 0.0, -1.0)) .withradius(0.5) .withmaterial(Material::Diffuse { color: Color::new(1.0, 0.45, 0.31), }), Sphere::new() .withcenter(Vec3::new(0.0, -100.5, -1.0)) .withradius(100.0) .withmaterial(Material::Diffuse { color: Color::new(0.7, 0.7, 0.7), }), ]; let scene = Scene::new() .withcamera(Camera::new()) .withobjects(objects); let engine = RenderEngine::new(32, 8); // Samples and max bounces let mut image = engine.render(&scene); image .write(Path::new("output/example_render.png")) .expect("Error writing rendered image"); } ```

Compile and run the project using cargo run --release.

Denoising

Crystal ball can optionally denoise rendered images using the Rust bindings for OpenImageDenoise.

To use this feature you need to install OpenImageDenoise and set the environment variable OIDN_DIR to the root directory of the OpenImageDenoise installation.

Enable the oidn feature in your Cargo.toml:

toml [dependencies.crystal_ball] version = "0.1.0" features = ["oidn"]

Now you can use the denoise method in your Rust code.

rust fn main() { // ... let mut image = engine.render(&scene); image .denoise() .write(Path::new("output/example_render.png")) .expect("Error writing rendered image"); }

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.

```toml

Required by strip = "symbols" (requires nightly toolchain)

cargo-features = ["strip"]

[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 ```

With this in place you can quickly compile using cargo run. To get full optimization use cargo run --release.

To massively reduce the size of the executable, you can use strip = symbols, provided you have the strip cargo feature (cargo-features = ["strip"]). However, this requires the nightly toolchain.

References/Resources