- OpenGL・Vulkan・Metal・DirectXの内部動作を理解するため、外部グラフィックライブラリなしでソフトウェアレンダラーをゼロから実装する
- 三角形メッシュとテクスチャで構成された3Dモデルを画像に変換し、GUIやGPUアプリケーションの実装は扱わない
- 完成コードは約500行で、学生は通常10〜20時間かけて動作するレンダラーを作り始める
- RGB・RGBA・グレースケールをサポートするTGA処理クラスと単一ピクセルの設定機能だけが与えられ、線分や三角形の描画は自分で実装する必要がある
- 完成コードをコピーするのではなく自分で書くことで、レンダリングの概念を理解し、3Dライブラリの内部動作も把握できる
レンダリングパイプラインを自分で作るプロセス
- 最新の3Dグラフィックライブラリの構造を緩やかになぞりながら、レンダリングパイプラインの動作原理を学ぶ
- GPUアプリケーションの書き方ではなく、ソフトウェアレンダラーで内部動作を再現する
- 入力は三角形メッシュとテクスチャで構成された3Dモデルで、出力はレンダリングされた画像
- グラフィックインターフェースなしに、プログラムが画像ファイルを生成する
- 外部依存を減らすため、シンプルな画像形式であるTGAを使用する
- 最初に提供される機能は、画像の読み込み・保存とピクセル1つの色設定だけ
- 線分や三角形を描く組み込み関数はなく、すべて自分で書く必要がある
- 最初の例では、
64x64のRGBフレームバッファを作成し、3つの座標のピクセルを白に設定してからframebuffer.tgaとして保存する
コードのビルドと実行
git clone https://github.com/ssloy/tinyrenderer.git &&
cd tinyrenderer &&
cmake -Bbuild &&
cmake --build build -j &&
build/tinyrenderer obj/diablo3_pose/diablo3_pose.obj obj/floor.obj
- 実行結果は**
framebuffer.tga**に保存される
- 完成コードは約500行だが、自分で実装するプロセスが概念理解に不可欠なため、提供コードをそのまま使う方法は推奨されない
1件のコメント
Hacker News のコメント
https://github.com/kshitijl/tinyrenderer-rs
リポジトリには、開発過程や笑える視覚的バグを収めたスクリーンショットが多い。レンダリングの原理だけでなく、現代のCPUは非常に高速で、シングルスレッドCPUレンダラー でも派手な特殊効果のあるインタラクティブな3Dゲームを動かせるという点を大いに学んだ
LLM以前だったので少なくとも2か月かかり、その大半はコンピュータグラフィックスの数学を理解し、Cのセグメンテーションフォルトを追跡することに費やした
このGitHubの講義ノートのほうが、概念を復習するにはよかった。リポジトリのコードスタイルは好みではなく、旧式のラスタライザーも過度に単純で非効率だが、それでもFoleyの本よりは読みやすいと思う
版が変わるにつれて使用言語もPascalからC、CとC++へと発展し、最新版にはC#も少し入っている。新しい概念はいくつも抜けているが、それでも 価値ある内容 は多いと思う
錐台クリッピングはローカルタイル内の点選択で処理でき、プリミティブ合成は逆変換したクリッピング矩形を重心座標系で扱うほうが簡単だ。倍精度や固定小数点で丸め誤差を制御でき、核心となる難点は新しい頂点のZと1/Zの値を再生成することだ。遅延属性合成ラスタライザーなら、残りは自然にパイプラインを通過し、OpenSWR.orgのオープンソース実装で例を見ることができる
最大の心理的障壁は、射影空間と同次座標になじみがないことだ。クリップ空間の6つの平面は
x = ±w、y = ±w、z = ±wと単純で、各多角形の辺を順にたどりながら両端点の内外を判定し、境界との交点の位置と頂点属性を線形補間すればよい。この処理をすべての平面に順番に適用すると、三角形は最大9頂点の凸多角形になり、簡単に再三角形分割できる。アウトコード(outcode) を事前計算すれば、完全に内側または外側にある三角形のクリッピングをスキップできる論文: https://dl.acm.org/doi/10.1145/360767.360802
固定パイプライン形式を保てば、かなり単純な描画関数でも驚くほど多くの三角形を処理できる