crystal_ball 0.3.0

A path tracing library written in Rust.
Documentation
# 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/