Patterns

Chapter 10

まあ Procedual Texture のことだよね。

Pattern trait

基本的には Shape trait の時と変わらない。

pub trait Pattern: Debug {
    fn transform(&self) -> &Transform;
    fn transform_mut(&mut self) -> &mut Transform;

    fn pattern_at(&self, p: &Point3D) -> Color;
    fn pattern_at_shape(&self, shape: &dyn Shape, p: &Point3D) -> Color {
        let local_p = shape.transform().inv() * p;
        let pattern_p = self.transform().inv() * &local_p;
        self.pattern_at(&pattern_p)
    }
}

この Pattern trait を実装した。

pattern_at() が Pattern の計算を行う場所で、Pattern 座標系内の点 p における Color を返すように実装する。それ以外は Shape のローカル座標系と Pattern 座標系間の変換がらみ。

Pattern を所有するのは Material。複数の Material で 1 つの Pattern を共有しても問題ないから Rc を使うことも考えたけれど、とりあえずは Shape のときと同じ Box にしておいた。なので、Box を使っていることに根拠はなく、あとで Rc なりに変更するかもしれない。
というか、複数の Shape で Material を共有してしまっても良いよネ。

pub struct Material {
    pub color: Color,
    pub ambient: FLOAT,
    pub diffuse: FLOAT,
    pub specular: FLOAT,
    pub shininess: FLOAT,
    pub reflective: FLOAT,
    pub transparency: FLOAT,
    pub refractive_index: FLOAT,
    /// パターン。None の場合は使用しない。
    pattern: Option<Box<dyn Pattern>>,

Pattern は使用しない場合もあるため、Option にしている。

あとは各パターンに応じた色の計算を実装してやるだけでほぼ完了。

f:id:mtXTJocj:20201228175736p:plain

結果

f:id:mtXTJocj:20201229173046p:plain