レンダリングの概要
微分可能レンダリングは、コンピュータビジョンにおいて比較的新しい刺激的な研究分野であり、2D 画像のピクセルをシーンの 3D プロパティに関連付けることで、2D と 3D のギャップを埋めます。
例えば、ニューラルネットワークによって予測された 3D 形状から画像をレンダリングすることにより、参照画像との 2D 損失を計算することが可能です。レンダリングステップを逆にすることで、ピクセルからの 2D 損失をメッシュ頂点の位置などの形状の 3D プロパティに関連付けることができ、明示的な 3D 教師データなしで 3D 形状を学習させることができます。
私たちは微分可能レンダリングのための既存のコードベースを徹底的に調査し、以下のことがわかりました。
- レンダリングパイプラインは、相互運用して微分可能である必要がある 7 つ以上の個別のコンポーネントを持つ複雑なものです。
- 一般的な既存のアプローチ [1, 2] は、主要なコンポーネントの多くを理解にかなりの専門知識を必要とする大規模な CUDA カーネルにバンドルした同じコア実装に基づいており、拡張の範囲が限られています。
- 既存のメソッドは、バッチ処理をサポートしていないか、バッチ内のメッシュが同じ数の頂点と面を持つことを前提としています。
- 既存のプロジェクトは CUDA 実装のみを提供しているため、GPU なしでは使用できません。
異なるアプローチを試すために、使いやすく拡張が容易で、異種バッチ処理をサポートするモジュール式の実装が必要でした。既存の研究 [1, 2] からインスピレーションを得て、PyTorch、C++、CUDA で並列実装された、新しいモジュール式の微分可能レンダラーを作成しました。また、包括的なドキュメントとテストを提供し、この分野の研究をさらに進めることを目的としています。
私たちの実装は、レンダリングのラスタライズとシェーディングのステップを分離します。コアとなるラスタライズステップ([2]に基づく)は、いくつかの変数を返し、CUDA で最適化された実装を備えています。パイプラインの残りの部分は PyTorch のみで実装されており、カスタマイズと拡張が容易な設計になっています。このアプローチにより、PyTorch3D 微分可能レンダラーはライブラリとしてインポートできます。
始めましょう
実装の詳細とレンダラーの使用方法については、レンダラーの使い始めを参照してください。アーキテクチャの概要と座標変換の規則も含まれています。
技術レポート
レンダラーの設計、主要な機能、ベンチマークの詳細な説明については、ArXiv の PyTorch3D 技術レポートを参照してください:PyTorch3D を使用した 3D 深層学習の高速化。pulsar バックエンドについては、こちらをご覧ください:球ベースの表現を用いたニューラルレンダリングのための高速微分可能レイトレーシング。
注:CUDA メモリ使用量
技術レポートの主な比較対象は SoftRasterizer [2] です。SoftRasterizer の順方向 CUDA カーネルは、1 つの (N, H, W, 4)
FloatTensor のみを出力しますが、PyTorch3D ラスタライザの順方向 CUDA カーネルは 4 つのテンソルを出力します。
pix_to_face
、LongTensor(N, H, W, K)
zbuf
、FloatTensor(N, H, W, K)
dist
、FloatTensor(N, H, W, K)
bary_coords
、FloatTensor(N, H, W, K, 3)
ここで、**N** はバッチサイズ、**H/W** は画像の高さ/幅、**K** はピクセルあたりの面数です。PyTorch3D の逆方向パスは、zbuf
、dist
、bary_coords
の勾配を返します。
ラスタライズから中間変数を返すことには、メモリコストが伴います。順方向パスと逆方向パスのメモリ使用量の理論的な下限は、次のように計算できます。
# Assume 4 bytes per float, and 8 bytes for long
memory_forward_pass = ((N * H * W * K) * 2 + (N * H * W * K * 3)) * 4 + (N * H * W * K) * 8
memory_backward_pass = ((N * H * W * K) * 2 + (N * H * W * K * 3)) * 4
total_memory = memory_forward_pass + memory_backward_pass
= (N * H * W * K) * (5 * 4 * 2 + 8)
= (N * H * W * K) * 48
ラスタライズ出力のピクセルあたりの面ごとに 48 バイトが必要です。メモリ使用量の範囲内に収まるように、バッチサイズ(**N**)、画像サイズ(**H/W**)、ピクセルあたりの面数(**K**)を変更できます。たとえば、バッチサイズを固定した状態で、画像サイズを大きくする場合は、ピクセルあたりの面数を減らしてみてください。
参考文献
[1] Kato et al, 'Neural 3D Mesh Renderer', CVPR 2018
[2] Liu et al, 'Soft Rasterizer: A Differentiable Renderer for Image-based 3D Reasoning', ICCV 2019
[3] Loper et al, 'OpenDR: An Approximate Differentiable Renderer', ECCV 2014
[4] De La Gorce et al, 'Model-based 3D Hand Pose Estimation from Monocular Video', PAMI 2011
[5] Li et al, 'Differentiable Monte Carlo Ray Tracing through Edge Sampling', SIGGRAPH Asia 2018
[6] Yifan et al, 'Differentiable Surface Splatting for Point-based Geometry Processing', SIGGRAPH Asia 2019
[7] Loubet et al, 'Reparameterizing Discontinuous Integrands for Differentiable Rendering', SIGGRAPH Asia 2019
[8] Chen et al, 'Learning to Predict 3D Objects with an Interpolation-based Differentiable Renderer', NeurIPS 2019