#cli #image #raytracer #raytracing #thread

app rustracer

a multi-threaded raytracer in pure rust

3 releases (stable)

Uses new Rust 2021

1.0.1 Jul 12, 2022
0.4.0 Jul 12, 2022

#1 in #rayon

GPL-3.0 license

285KB
6K SLoC


Logo

a multi-threaded raytracer in pure rust

CI Coverage CD
Version License

Prerequisites

Platform requirements

  • x86_64-unknown-linux-gnu (1)
  • x86_64-unknown-linux-musl

(1) note: glibc version >= 2.27

Build requirements

  • for users install cargo stable latest build system

  • for devels it's advisable to install the entire (stable latest) toolchain using rustup

    For unit tests coverage llvm-tools-preview is required as additional component coupled with
    cargo-llvm-cov for easily use LLVM source-based code coverage

    There is an handy makefile useful to:

    • preview documentation built with rustdoc
    • preview html code coverage analysys created with cargo-llvm-cov
    • create demo animations

Installation

From binary

Install from binary:

curl -sSf https://andros21.github.io/rustracer/install.sh | bash  (2)


click to show other installation options
## Install the latest version `gnu` variant in `~/.rustracer/bin`
export PREFIX='~/.rustracer/'
curl -sSf https://andros21.github.io/rustracer/install.sh | bash -s -- gnu

## Install the `0.4.0` version `musl` variant in `~/.rustracer/bin`
export PREFIX='~/.rustracer/'
curl -sSf https://andros21.github.io/rustracer/install.sh | bash -s -- musl 0.4.0

(2) note: will install latest musl release in ~/.local/bin

From source

Install from source code, a template could be:

cargo install rustracer  (3)


click to show other installation options
## Install the latest version using `Cargo.lock` in `~/.rustracer/bin`
export PREFIX='~/.rustracer/'
cargo install --locked --root $PREFIX rustracer

## Install the `0.4.0` version in `~/.rustracer/bin`
export VER='0.4.0'
export PREFIX='~/.rustracer/'
cargo install --root $PREFIX --version $VER rustracer

(3) note: will install latest release in ~/.cargo/bin

Usage

rustracer

subcommands description
rustracer-convert convert an hdr image into ldr image
rustracer-demo render a simple demo scene (example purpose)
rustracer-render render a scene from file (yaml formatted)
rustracer-completion generate shell completion script (hidden)

click to show rustracer -h
rustracer 1.0.1
a multi-threaded raytracer in pure rust

USAGE:
    rustracer <SUBCOMMAND>

OPTIONS:
    -h, --help       Print help information
    -V, --version    Print version information

SUBCOMMANDS:
    convert    Convert HDR (pfm) image to LDR (ff|png) image
    demo       Render a demo scene (hard-coded in main)
    render     Render a scene from file

rustracer-convert

Convert a pfm file to png:

rustracer convert image.pfm image.png

click to show rustracer-convert -h
rustracer-convert 1.0.1
Convert HDR (pfm) image to LDR (ff|png) image

USAGE:
    rustracer convert [OPTIONS] <HDR> <LDR>

ARGS:
    <HDR>    Input pfm image
    <LDR>    Output image [possible formats: ff, png]

OPTIONS:
    -f, --factor <FACTOR>    Normalization factor [default: 1.0]
    -g, --gamma <GAMMA>      Gamma parameter [default: 1.0]
    -h, --help               Print help information
    -v, --verbose            Print stdout information
    -V, --version            Print version information

rustracer-demo

Rendering demo scene:

rustracer demo --width 1920 --height 1080 --anti-aliasing 3 demo.png   (4)
rustracer-demo-png

demo.png: cpu Intel(R) Xeon(R) CPU E5520 @ 2.27GHz | threads 8 | time ~35s


demo scene 360 degree (see makefile):

make demo.gif  (4)
rustracer-demo-gif

demo.gif: cpu Intel(R) Xeon(R) CPU E5520 @ 2.27GHz | threads 8 | time ~15m


click to show rustracer-demo -h
rustracer-demo 1.0.1
Render a demo scene (hard-coded in main)

USAGE:
    rustracer demo [OPTIONS] <OUTPUT>

ARGS:
    <OUTPUT>    Output image [possible formats: ff, png]

OPTIONS:
    -a, --algorithm <ALGORITHM>            Rendering algorithm [default: pathtracer]
                                           [possible values: onoff, flat, pathtracer]
        --angle-deg <ANGLE_DEG>            View angle (in degrees) [default: 0.0]
        --anti-aliasing <ANTI_ALIASING>    Anti-aliasing level [default: 1]
    -f, --factor <FACTOR>                  Normalization factor [default: 1.0]
    -g, --gamma <GAMMA>                    Gamma parameter [default: 1.0]
    -h, --help                             Print help information
        --height <HEIGHT>                  Image height [default: 480]
        --init-seq <INIT_SEQ>              Identifier of the random sequence (positive number)
                                           [default: 54]
        --init-state <INIT_STATE>          Initial random seed (positive number) [default: 42]
    -m, --max-depth <MAX_DEPTH>            Maximum depth [default: 3]
    -n, --num-of-rays <NUM_OF_RAYS>        Number of rays [default: 10]
        --orthogonal                       Use orthogonal camera instead of perspective camera
        --output-pfm                       Output also hdr image
    -v, --verbose                          Print stdout information
    -V, --version                          Print version information
        --width <WIDTH>                    Image width [default: 640]

(4) note: all available threads are used, set RAYON_NUM_THREADS to override


rustracer-render

Rendering demo scene from scene file examples/demo.yml:

rustracer render --anti-aliasing 3 examples/demo.yml demo.png  (5)

you can use this example scene to learn how to write your custom scene, ready to be rendered!

But let's unleash the power of a scene encoded in data-serialization language such as yaml
Well repetitive scenes could be nightmare to be written, but for these (and more) there is cue

Let's try to render a 3D fractal, a sphere-flake, but without manually write a yaml scene file
we can automatic generate it from examples/flake.cue

cue eval flake.cue -e "flake" -f flake.cue.yml   # generate yml from cue
cat flake.cue.yml | sed "s/'//g" > flake.yml     # little tweaks
wc -l flake.cue flake.yml                        # compare lines number
   92 flake.cue                                  # .
 2750 flake.yml                                  # .

so with this trick we've been able to condense a scene info from 2750 to 92 lines, x30 shrink! 😎
and the generated flake.yml can be simple parsed

rustracer render --width 1280 --height 720 --anti-aliasing 3 flake.yml flake.png  (5)
rustracer-flake

flake.png: cpu Intel(R) Xeon(R) CPU E5520 @ 2.27GHz | threads 8 | time ~7h


click to show rustracer-render -h
rustracer-render 1.0.1
Render a scene from file (yaml formatted)

USAGE:
    rustracer render [OPTIONS] <INPUT> <OUTPUT>

ARGS:
    <INPUT>     Input scene file
    <OUTPUT>    Output image [possible formats: ff, png]

OPTIONS:
    -a, --algorithm <ALGORITHM>            Rendering algorithm [default: pathtracer]
                                           [possible values: onoff, flat, pathtracer]
        --angle-deg <ANGLE_DEG>            View angle (in degrees) [default: 0.0]
        --anti-aliasing <ANTI_ALIASING>    Anti-aliasing level [default: 1]
    -f, --factor <FACTOR>                  Normalization factor [default: 1.0]
    -g, --gamma <GAMMA>                    Gamma parameter [default: 1.0]
    -h, --help                             Print help information
        --height <HEIGHT>                  Image height [default: 480]
        --init-seq <INIT_SEQ>              Identifier of the random sequence (positive number)
                                           [default: 54]
        --init-state <INIT_STATE>          Initial random seed (positive number) [default: 42]
    -m, --max-depth <MAX_DEPTH>            Maximum depth [default: 3]
    -n, --num-of-rays <NUM_OF_RAYS>        Number of rays [default: 10]
        --output-pfm                       Output also hdr image
    -v, --verbose                          Print stdout information
    -V, --version                          Print version information
        --width <WIDTH>                    Image width [default: 640]

(5) note: all available threads are used, set RAYON_NUM_THREADS to override


rustracer-completion

Simple generate completion script for bash shell (same for fish and zsh):

rustracer completion bash (6)

note: close-open your shell, and here we go, tab completions now available!


click to show rustracer-completion -h
rustracer-completion 1.0.1
Generate shell completion script

USAGE:
    rustracer completion [OPTIONS] <SHELL>

ARGS:
    <SHELL>    Shell to generate script for [possible values: bash, fish, zsh]

OPTIONS:
    -h, --help               Print help information
    -o, --output <OUTPUT>    Specify output script file
    -V, --version            Print version information

(6) note: bash>4.1 and bash-complete>2.9


Acknowledgements

  • pytracer - a simple raytracer in pure Python

Dependencies

~5–12MB
~218K SLoC