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.
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
.
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");
}
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
strip = "symbols"
(requires nightly toolchain)[package]
[profile.dev] opt-level = 3
[profile.release]
panic = "abort"
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.