Module rustic_zen::material

source ·
Expand description

Materials in Rustic Zen are defined as closures that act on a single ray when intersecting wtth an object.

For object safety these closures are stored in a std::sync::Arc which can then be cloned to as many users as needed. As there is a constant generic type assosiated with the material, R it is usually easiest to implement the Arc inside a generator function that yeilds the Arc and accepts a type argument.

§Examples:

§Create a trivial shader and assign it to several Segments

use rustic_zen::prelude::*;
use std::sync::Arc;

// This shader will fire all incoming rays in the direction of the surface normal.
// This is actually surprisingly useful for testing normals.
fn always_normal<R>() -> material::Material<R> {
    Arc::new(move |_, normal: &Vector, _, _, _: &mut R| {
        Some(normal.clone())
    })
}

let m = always_normal(); // R fixed to a concrete type here by the `Scene` below

let s = Segment::line_from_points((0.0, 0.0), (10.0, 10.0), m.clone());
let s2 = Segment::line_from_points((10.0, 10.0), (20.0, 0.0), m);

// you may get unknown type for <R> if you do not add all your segments to a scene.
let _ = Scene::new(100, 100).with_object(s).with_object(s2);

§Create a more useful shader that refects 50% of incoming light and apply it to several Segments:

use rustic_zen::prelude::*;
use std::sync::Arc;

// This shader will reflect half of the rays and absorb the other half
fn mirror<R: Rng + 'static>() -> material::Material<R> {
    let s = Sampler::<f64, R>::new_range(0.0, 1.0);
    Arc::new(move |direction: &Vector, normal: &Vector, _, _, rng: &mut R| {
        if s.sample(rng) < 0.5 {
            None
        } else {
            Some(direction.reflect(normal))   
        }
    })
}

let m = mirror(); // R fixed to a concrete type here by the `Scene` below

let s = Segment::line_from_points((0.0, 0.0), (10.0, 10.0), m.clone());
let s2 = Segment::line_from_points((10.0, 10.0), (20.0, 0.0), m);

// you may get unknown type for <R> if you do not add all your segments to a scene.
let _ = Scene::new(100, 100).with_object(s).with_object(s2);

Admittedly this could probably be less clunky.

Creating more imaginative shaders is left as an exersize for the reader.

Functions§

  • Reference / Legacy implementation of Material trait.
  • Default Settings for hqz_legacy, makes a fast and predictable testing shader where needed.

Type Aliases§