2020年にNeRF (Neural Radiance Fields)が登場して以降、多数視点画像からRadiance Fieldsを復元して自由視点映像を作成するNovel View Synthesisタスクの研究が盛ん。
NeRFの欠点
Novel View Synthesisタスクのブレイクスルーとなり自由視点映像の作成方法として注目されたNeRFだが、シーン表現にニューラルネットワークの仕組みを利用している構造上、コンテンツ制作用途には不都合な以下の欠点があった。
- 編集が困難
- レンダリング処理が重い
編集が困難
NeRFのシーン表現はニューラルネットワークに重みとして埋め込まれた連続関数であり、明示的なジオメトリ情報を保持していない。そのため、シーン内の不要オブジェクトを削除するなど、画像レタッチのような局所的な編集が難しい。
ニューラルネットワークの一部の重みを編集するだけではNeRFシーンを表現する連続関数が破綻してしまうため、編集範囲の大小に関わらず、NeRFのシーン表現を加工するにはシーン全体の連続関数を再構築する必要がある。
レンダリング処理が重い
NeRFのレンダリングは計算量が多くリアルタイムに処理できない。
NeRFのレンダリングには、レンダリング画像1ピクセルにつき複数回のサンプリングが必要となり、1点サンプリングする度にニューラルネットワーク計算を要する。レンダリング解像度を上げるためには計算量がさらに増加することになる。
また、NeRFの最適化(ニューラルネットワークの学習)処理はレンダリング処理を内包しているため、このレンダリング処理の重さが最適化処理の重さにも影響している。
NeRFのレンダリングの高速化
NeRFのレンダリング処理を高速化する改善手法は多数提案されたが、レンダリング品質と処理速度はトレードオフの関係で、リアルタイム(10~15fps程度)にレンダリングするには解像度を落としてシーン構成も限定する必要があった。
3D Gaussian Splatting
3D Gaussian SplattingはSIGGRAPH 2023で発表された論文 3D Gaussian Splatting for Real-Time Radiance Field Renderingで提案されたNovel View Synthesis手法。
GitHubで公式のソースコードも公開されている↓
https://github.com/graphdeco-inria/gaussian-splatting
スポンサーリンク
3D Gaussian Splattingの特徴
NeRFがニューラルネットワークでRadiance Fieldsを表現していたのに対し、3D Gaussian SplattingはGaussian(ガウス分布)を3D空間上に離散的に多数配置してRadiance Fieldsを近似する。
ここで使われるGaussianとは3次元のガウス分布のことで、輪郭がぼやけた半透明の楕円体のようなもの。
このGaussianの位置や色(Radiance、不透明度)、広がり度合い(スケール・回転による変形)、配置する数(配置密度)を微分可能レンダリングによって最適化して3Dシーンを作成する。
3D空間上に明示的にGaussianを多数配置する離散的なデータ構造は、3D点群にパラメータを追加して拡張したものとも言え、シーン上の物体の疎密に応じたデータ量・計算量で効率的にシーンを表現できる。点群と同様に離散的なデータなので部分的な編集も容易。
NeRFがニューラルネットワークで陰関数的にRadiance Fieldsを表現していたのに対して、3D Gaussian Splattingは陽にデータを配置してRadiance Fieldsを表現していると言える。
3D Gaussian Splattingは従来のNeRF手法と同等以上のレンダリング品質を保ちながら処理時間を大幅に短縮し、1080p解像度で30fps以上のリアルタイムレンダリングを実現した。
レンダリング処理が高速なため、Webブラウザ上でインタラクティブにグリグリ視点を動かせる高品質な3D自由視点コンテンツも作成できる。
では、3D Gaussian Splattingを実現する仕組みについて詳しく見ていこう。
3D Gaussian Splattingの全体像
NeRFと同様に、3D Gaussian Splattingも多視点画像群とSfM(Structure from Motion)で得た情報を入力とした最適化処理のイテレーションによってシーン表現を作成する。どちらも材料となる入力データがSfMの品質に依存している。
相違点は、NeRFが多視点画像群とSfMから得られるカメラパラメータ群(レンズ情報、位置・姿勢)のみを使用していたのに対し、3D Gaussian Splattingは多視点画像群とSfMで得られるカメラパラメータ群に加えて、SfMで得られる疎な3D点群も使用する点。
多視点画像群、カメラパラメータ群、3D点群を入力とした3D Gaussian Splattingの最適化処理は以下の図のようになる↓
入力 SfM Points:SfMで得た3D点群 Camera Parameters:SfMで得たカメラパラメータ群(多視点画像群の各画像と対応) Images:多視点画像群 処理 Initialization:SfM点群位置を初期配置に使用し、Gaussian群の各パラメータを初期化する Projection:各カメラパラメータに従ってGaussian群を投影する Differentiable Tile Rasterizer:Gaussian群を2D画像へレンダリングする Loss Function:元の多視点画像群とレンダリング画像群の誤差を算出する Adaptive Density Control:Gaussian群の配置密度を調整する 矢印 黒矢印:処理の流れ 青矢印:誤差勾配の流れ(誤差逆伝播)
InitializationでSfM点群の位置をGaussian群の初期配置とし、Projectionでカメラパラメータ群を使ってGaussian群を投影、Differentiable Tile Rasterizerで2D画像をレンダリングする。
Loss Functionで元の多視点画像群とレンダリング画像の誤差を算出し、その誤差勾配を用いてGaussian群の位置、回転、スケール、色を最適化していく。加えて、Adaptive Density ControlによってGaussian群の配置密度も調整する。
では、それぞれの処理の詳細を順に見て行こう。
Initialization
Initializationでは、最適化ループ開始時のGaussian群の初期値をセットする。
ここで、3D Gaussian Splattingで使われるGaussian(3次元のガウス分布)の定義と、1つのGaussianが保持するパラメータについて解説する。
Gaussian(3次元のガウス分布)の定義
3D Gaussian Splattingで使われるGaussian(3次元のガウス分布)の形状は以下の式で定義される↓
x:3次元空間上の任意の点の位置座標
Σ:Gaussianの変形(スケール/回転)を制御する共分散行列
この式は、3次元空間上の原点をGaussianの中心(平均)とした場合の点xへの影響度(密度や濃度)を表している。xが原点に近いほど影響度が強くなり、xと原点の位置関係に応じた影響度の強さが共分散行列Σで制御される。
この分布(形状)の定義をベースとして、さらにレンダリングに必要な各種パラメータが追加される。
Gaussianが持つパラメータ
1つのGaussianが持つパラメータの定義は以下となる↓
p:中心位置座標 Σ:変形(スケール/回転)を制御する共分散行列 c:視線依存の色(Radiance) 𝛼:不透明度 |
Gaussianが保持する視線依存の色cと不透明度𝛼の値に、定義式による影響度がかけ合わさって1つGaussian(輪郭がぼやけた楕円体)がレンダリングされる。
だが、実装上は共分散行列Σがスケールベクトルsと回転Quaternion qに分解され、視線依存の色cは球面調和関数の係数として保持される。
スポンサーリンク
Radianceを球面調和関数で近似する
球面調和関数(Spherical Harmonics)は、CGのレンダリング分野で古くから環境マップなど球面状の輝度分布やRadianceの圧縮近似手法として使われてきた。
フーリエ級数と同じように、球面調和関数は基底に係数かけた項の足し算で球面上の値の分布を近似することができ、より高い次数の項を考慮するほど複雑な値の分布を表現できる。(Unityの球面調和関数の実装は次数l=2までを考慮している)
3D Gaussian Splattingでは球面調和関数の次数l=3までを考慮する実装となっている。
次数l=3まで考慮する場合、次数l=0の項が1個の係数、次数l=1の項が3個の係数、次数l=2の項が5個の係数、次数l=3の項が7個の係数で合計16個の変数となる。色を表す場合はRGB各色に対してこれら変数が必要となるため、Radianceを保持するための変数は合計で48個。
次数l=0の項の係数は視線方向に依存しないベース色を表現し、次数l=1~3の項の係数が視線方向に依存して変化する成分を表現する。(逆に言うと、次数l=3までで表現できないほど鋭い反射は再現されない)
Gaussianが持つ実装上のパラメータ
ということで、1つのGaussianが保持する実装上のパラメータは以下となる↓
p:中心位置座標 s:スケールを制御するベクトル q:回転を制御するQuaternion R:Radianceの赤成分を表す球面調和関数の係数(ベース色 + 15係数) G:Radianceの緑成分を表す球面調和関数の係数(ベース色 + 15係数) B:Radianceの青成分を表す球面調和関数の係数(ベース色 + 15係数) 𝛼:不透明度(0~1) |
Initializationでは、SfMで得た疎な3D点群の位置座標をそのままGaussianの中心位置座標とし、スケール、回転、Radiance、不透明度をデフォルト値で初期化する。
Projection
Projectionでは、SfMで得たカメラパラメータを使って各Gaussianをカメラが見た2D平面へ投影し、3次元のGaussianを2次元の楕円へ近似(Splatting)する。ここでレンダリングの視線方向が定まるので描画するSplatの色が定まる。
Differentiable Tile Rasterizer
Differentiable Tile Rasterizerでは、Projectionで得られた2DのSplats(半透明の楕円群)をピクセルへラスタライズして最終的な画像をレンダリングする。
半透明のSplat(楕円)の重なりを正しく描画するには、まず奥行き順にソートする必要がある。そして、大量にあるSplat(楕円)を効率的にソートするために、レンダリング画像を複数のタイル(論文中では16×16)に分割して並列に処理する。各タイルに対して「どのSplatが寄与するか」を判定し、不要な処理はスキップする。
CGのリアルタイムレンダリングに馴染みのある人ならお分かりかと思うが、3D Gaussian Splattingのレンダリングで最も重いのはこの半透明物体を描画するためのソート処理である。
このソート処理で使われる位置座標は各Gaussianの中心座標が元であるため、Gaussianの向きと大きさによってはGaussian同士の交差を正しく捉えられないが、論文ではGaussianの大きさがレンダリング画像1ピクセルと同程度であればこの問題は無視できるとしている。
ソート後のSplatsの重なりを積分してレンダリング画像1ピクセルの色を算出する。
Loss Function
元の画像とレンダリング画像の誤差を求める損失関数には、画像の同一ピクセル間の絶対値誤差を評価するL1 Lossと、画像同士の構造的な類似性を評価するSSIM(Structural Similarity Index Measure)を微分可能にしたD-SSIM Lossを組み合わせた以下式が使われる↓
論文ではλ=0.2としている。
この損失関数で求めた誤差を逆伝播させて最適化を行う。
Adaptive Density Control
最適化処理が進むと、Gaussianの位置、スケールや回転、不透明度の値が変化し、シーン構成に対してGaussianの配置密度に偏りが生じる。Adaptive Density Controlでは、Gaussianの大きさと配置密度の偏りを適応的に調節する。
シーン上の領域について、その領域を表現するのに本来必要な情報に対してGaussianが小さ過ぎる状態をUnder-Reconstruction、逆に本来必要な情報に対してGaussianが大き過ぎる状態をOver-Reconstructionとして、それぞれの場合でGaussianを複製(Clone)または分割(Split)することでシーン表現に適した配置を実現する。
Under-Reconstruction:小さく少な過ぎるGaussianを複製(Clone)し、最適化を経て領域を表現する
Over-Reconstruction:大き過ぎるGaussianを分割(Split)し、最適化を経て領域を表現する
最適化処理を安定させる工夫
安定的に最適化処理を進めるにはある程度ノウハウが必要らしく、論文ではウォームアップ「目標のレンダリング解像度の1/4の低解像度から開始して250イテレーションごとに2倍の解像度へアップサンプリング」や、球面調和関数の0次の項の係数のみで最適化した後に1000回のイテレーションごとに上の次数の項の係数を最適化対象に追加していく方法を取ったとのこと。
その後の発展手法
3D Gaussian Splattingの登場以降、その仕組みを利用した派生手法が多数登場している。Awesome 3D Gaussian Splatting Resourcesを眺めるとその応用範囲の広さが分かる。
3D Gaussian Splattingを手軽に試せるツール
3D Gaussian SplattingはNeRFよりも従来のCGレンダリングの仕組みに近いこともあり、手法が発表されてからさほど時間を置かず対応したライブラリやツールが多数登場した。
3D Gaussian Splattingのシーンを作成できるライブラリとしてはgsplat、ツールとしてはデスクトップアプリのPostshotやスマホアプリのScaniverseが無料で使えてお手軽。
編集には、Webブラウザで使用できるsupersplatというオープンソースのツールもある。
作成した3D Gaussian SplattingシーンはUnityやUnreal Engineでレンダリングする方法が複数ある。
本記事に掲載したgif画像はUnityGaussianSplattingを利用してレンダリングした動画を元に作成した。
作成したシーンの保存には点群等で使われるPLYなどの汎用フォーマットを一部拡張したファイル形式が使用されてきたが、最近ScaniverseのNianticがSPZという専用のファイルフォーマットを発表した。
参考図書
今のところ、3D Gaussian Splattingの解説が日本語で読める書籍は以下2冊↓
ツールを使ったコンテンツ制作の指南書が出ている辺りに需要の高さがうかがえる。
感想
Radiance Fieldsのレンダリング処理の高速化を目指すと、結局既存のGPUの仕組みに則った方法に近づいていく。3D Gaussian Splattingは既存のCGレンダリングの仕組みに近い分NeRFよりも理解しやすかった。
微分可能レンダリングによる最適化は、grand truth画像とレンダリング画像を比較して近づける仕組みであるため、最適化時に使用するレンダラの表現力が作成されるシーンにかなりダイレクトに反映される。
ゲームエンジンでも動作プラットフォーム(使用するグラフィックスAPI)の違いによってレンダリングに結果に差異が出ることを考えると、3D Gaussian Splattingシーンの作成に使用するレンダラと、作成済みシーンをコンテンツとして表示する際のレンダラはなるべく同じにしないと品質のコントロールができなさそう。
スマホやWebブラウザで表示するコンテンツを想定する場合は、最適化処理の段階で最も表現力の低いレンダラを使用するとか。
この点があまり問題になっていないのは、今のところそこまで繊細な表現を追求する段階では無いからだろうか。これはRadiance Fieldsを高速にレンダリングできる仕組みが実現されたからこそ浮かび上がってくる問題ではある。
NeRFの時にも感じたが、3D Gaussian SplattingはCV分野とCG分野を横断するような隣接領域の技術なので、書籍やネットの解説記事の書き手がどちらの分野の専門家かによって、もう一方の分野の解像度が落ちて雑になる印象を受ける。(それは自分にも言える)
スポンサーリンク
コメント