Skip to content

はじめに ​

本稿は,Peter Shirleyらが出版した,以下の3つの本について,自己学習目的で作成している文書です。

  1. Ray Tracing in One Weekend (v3.2.3)(v.4.0.2)(日本語版)
  2. Ray Tracing: The Next Week (v3.2.3)(v.4.0.2)(日本語版)
  3. Ray Tracing: The Rest of Your Life (v3.2.3)(v.4.0.2)(日本語版)

『週末レイトレーシング』は実践的なプログラミング学習の題材としてよく知られています。原著はC++11(std::shared_ptrを使っている)の,あまりモダン寄りではない堅実なコーディングスタイルで書かれています。レイトレーシングやC++のよい学習教材として参照されているだけでなく,多言語への移植のベースとしても利用しやすいため,GolangやPythonなど人気の言語のほか,C++と同じシステムプログラミング言語で,学習曲線が急峻なことで知られるRust実装を試みた猛者が多い印象です。

本稿でもRustで再実装することにしました。さらに,WebAssemblyによりクライアントサイドで実行して,実行結果として得られるPPM画像をVitePress内にVueコンポーネントを使って表示することにしました。One Weekend(週末)という題名ですが,私にはおよそOne Weekendで終えることはできす,バナーにある「A Final Render(最後のシーン)」を出力するのに7ヶ月(30週)かかりました。

この試みはいくつかの壁を乗り越える必要がありました。そこで,別項としてWebAssemblyのVitePressでの取扱について説明することにしました。VueやViteについて調べるところから始め,WebAssemblyバイナリーとCanvasにより表示する設計とし,初めてグラデーション画像を表示できたときの喜びは今でも覚えています。

Rustを選んだ副産物のひとつは,WASMバイナリの軽量さです。第1週のすべてのデモを含む raytracing_demos_bg.wasm は,圧縮なしでわずか66KBに収まります。Rustのゼロコスト抽象化とwasm-packのリリースビルドが不要なコードを徹底的に除去するためで,RustとWebAssemblyの相性の良さを端的に示しています。昨今のネットワーク環境では,この程度のサイズはページ表示の妨げになりません。

本稿の構成 ​

0 技術 ​

raytracing_demos を VitePress から呼び出すために必要な技術を2本のページで解説します。1本目は Cargo ワークスペースの3層構成(common・r1XX-*・raytracing-demos)・クレートの命名規則・新デモを追加するときの手順・ビルド方法に加え,Rust から JavaScript へ PPM 文字列を受け渡す設計の意図を取り上げます。2本目は VitePress 上でその PPM 文字列を受け取り Canvas に描画する Vue コンポーネント PPMRenderer の実装を扱い,Vue のリアクティビティとの競合をどう回避したかも解説します。

1 週末レイトレーシング ​

書籍の進行に沿って第1週の全13章を扱います。原著は C++11 で書かれており,本稿の Rust 移植はその差異を読み解くことを学習のひとつの軸としています。具体的には,出力パラメータの代わりに Option<T> で戻り値を表現すること,shared_ptr の代わりに Arc<dyn Trait> を使うこと,純粋仮想関数をトレイトとして定義すること,演算子オーバーロード,式指向の制御構造,所有権・借用規則など,Rust らしいイディオムについて C++ との対比を交えながら説明しています。