RustでRayTracingの並列化

1 min読了の目安(約1100字TECH技術記事

Rustで作ったRayTracingは遅いので、並列化しようと思いました。

まずは、ただ画像を出力するだけのプログラムの並列化を試みました。

勉強になったところは、rayonとitertoolsを使うときは、par_bridgeしてcollectするぐらいでした。

コードをのせておきますね。

use itertools::iproduct;
use rayon::prelude::*;
use rayon::iter::ParallelBridge;

#[derive(Copy, Clone)]
pub struct Vec3<T: Copy> {
    pub x: T,
    pub y: T,
    pub z: T
}

fn pixel_color(r: f64, g: f64, b: f64) -> Vec3<u32>
{
    const scale: f64 = 255.99;
    return Vec3 {x: (scale * r) as u32, y: (scale * g) as u32, z:(scale * b) as u32}
}

fn main() {
    const w: u32 = 256;
    const h: u32 = 256;

    let mut image: Vec<(u32, u32, Vec3<u32>)> = iproduct!(0..w, 0..h).par_bridge().map(|(i, j)| {
        let r = i as f64/(w - 1) as f64;
        let g = j as f64/(h - 1) as f64;
        let b = 0.25f64;

        (i, h - j, pixel_color(r, g, b))
    }).collect();

    image.sort_by(|a, b| a.0.cmp(&b.0));
    image.sort_by(|a, b| a.1.cmp(&b.1));

    println!("P3\n {} {} \n255", w, h);

    for (i, j, p) in image {
        println!("{} {} {}", p.x, p.y, p.z);
    }
}