Reality Capture · 3D Gaussian Splatting (Kerbl et al. 2023)

写真から3Dが立ち上がる3D Gaussian Splatting

何十枚もの実写写真から、写実的な3Dシーンを丸ごと再構成し、 それをブラウザ上でぬるぬると動かせる技術があります。 その名は 3D Gaussian Splatting(ガウシアンスプラッティング)。 その中身は、ポリゴンでもボクセルでもなく、 空間に浮かぶ数十万個の「ぼやけた楕円」=3Dガウシアンの重ね合わせ。 まずは下のビューアで自由に触ってから、一粒のガウシアンの正体、 それを描くスプラッティング、写真から作り出す微分可能レンダリングの順にたどります。

まず、さわってみる ↓
Section 1

まず、さわってみる

回して、ズームして、表示モードを切り替えてみよう

下に映っているのは、実写写真から丸ごと再構成した3Dシーンを、 ブラウザ上でリアルタイム描画したものです。まずは理屈ぬきで動かしてみてください。 ドラッグで回転・ホイールでズーム・右ドラッグで平行移動。 右上のツールバーでシーンや表示モードを切り替えられます。

ヒント: 右上で 通常/輪郭/フラット を切り替え、⚙(設定)で サイズ表示数を動かしてみてください。 なめらかに見える表面が、実は無数の小さな楕円の集まりだと分かります。 ✨再構成で点群→フル解像の復元アニメーションも再生できます。

3つの表示モードは、この教材の要点をそのまま見せてくれます。

Section 2

何を見ているのか — 点でも面でもない「ガウシアンの雲」

ビューアに映るのは、写真でもポリゴンでもない

3Dの形をコンピュータで表す方法は、これまで大きく2つでした。 ひとつはメッシュ(ポリゴン) — 三角形を貼り合わせて「硬い面」を作る方法(RhinoやBlenderの世界)。 もうひとつは点群 — レーザースキャンで得られる、大きさを持たない無数の点の集まりです。

3D Gaussian Splatting は、そのどちらでもない第三の表現を使います。 シーンを数十万〜数百万個の「3Dガウシアン」で埋めるのです。 1個のガウシアンは、空間に浮かぶ楕円体状のぼやけた色のかたまり — エアブラシでふわっと吹いた色の粒、と思ってください。 中心がいちばん濃く、外へいくほど滑らかに透明へ消えていきます。

面でも点でもない、この「ふわふわした粒」を空間に重ねると、 重なり合った粒どうしが溶け合って、連続した写実的な表面に見えます。 本当にそんなことが起きるのか、下のおもちゃで確かめてみましょう。

はじめに見えるのは、写真からカメラ位置を推定するとき(SfM)に得られるような、 まばらな色つきの点群です。▶ 点群からを押す(またはスライダーを動かす)と、 各点が3Dガウシアンにふくらみ、すき間だらけだった点の集まりが溶け合って 連続した面に変わります。実際の学習(Section 5)も、点群を種に粒を置くところから始まります。

ヒント:モデルを金属の球・ガラスの球・水面(池)に切り替えて 回してみてください。ハイライトや照り返しが見る方向に合わせて動きます — 粒の色が「見る方向の関数」(視線依存色)だからです。焼き込みに切り替えると、 撮影時の色が表面に貼り付いたままになります(フォトグラメトリのテクスチャ相当)。 ⌖ 撮影視点へで戻ると両者は一致。マットなりんごの木では 切り替えてもほとんど差が出ないことも確かめてください。 点の数スライダーで点群を間引くと、点が足りない場所は粒をふくらませても かたちが崩れます — 実際の学習で粒を増やす(Section 5 の自動密度調整)理由です。

次のセクションで、この一粒がどんな数値でできているかを見ていきます。

Section 3

一粒のガウシアン — 位置・かたち・色・不透明度

4つの部品だけで、1個の粒が決まる

1個の3Dガウシアンは、たった4種類の情報で完全に決まります。

  • 位置 μ — その粒が空間のどこにあるか(中心座標 x, y, z)。
  • かたち Σ(共分散) — 楕円体の「向き」と「各軸の伸び」。丸い粒にも、細長い粒にも、平たい円盤にもなる。
  • — 見る方向によって少し変わる色(視線依存。金属の反射などを表せる。Section 2 のデモの金属の球・水面で体感できます)。
  • 不透明度 α — その粒がどれだけ濃い(不透明)か。

鍵になるのはかたち Σ です。共分散行列 Σ は、次のように分解できます。

Σ = R S Sᵀ Rᵀ  (S = 各軸の伸び/スケール, R = 向き/回転)

つまり「基準の丸い球を、S で各軸方向に引き伸ばしR で回転させた楕円体」というだけの話です。 高校で習う分散・共分散の3次元版で、統計の「ばらつきの楕円」がそのまま3Dの粒のかたちになっています。 そして中心から離れるほど濃度がガウス関数(釣鐘型)で滑らかに落ちる — このなめらかな減衰こそが、粒どうしを溶け合わせて連続面に見せる正体です。

冒頭のビューアの輪郭モードは、各ガウシアンのこの楕円の境界線(2σ)を描いて見せてくれます。 大きく平たい楕円が壁や地面の下地を、小さな楕円が細かい模様を担当しているのが分かります。

下にいるのは一粒だけのガウシアンです。スライダーが S(各軸の伸び)R(回転)そのもの — 動かして、ひとつの球が円盤にも棒にもなることを確かめてください。 いちばん下の視線依存スライダーは、4部品の「色」が持つ 見る方向で変わる成分(球面調和関数)です。

ヒント:プリセットの円盤は壁や床の下地を受け持つ粒、 は枝や手すりのようなエッジを受け持つ粒のかたちです。 フラットに切り替えると「なめらかな減衰」を切った姿も見られます。 視線依存を上げて回転させると、同じ一粒なのに見る角度で色が変わります — 本物の3DGSはこれを球面調和関数の係数として粒ごとに学習し、Section 2 の金属や水面の ハイライトはこの成分でできています。

Section 4

どうやって描くか — スプラッティング

3Dの粒を画面に「叩きつけて」重ねる

splat とは「(絵の具などを)ぴちゃっと叩きつける」という意味。 3Dガウシアンをカメラの画面にぴちゃっと投げつけ、2Dの楕円のシミとして重ねていくので スプラッティングと呼ばれます。ビューアは毎フレーム、実行中まさにこれをやっています。

  1. 深度ソート — カメラから見て、すべてのガウシアンを奥→手前の順に並べ替える。半透明を正しく重ねるために順序が要る(Web Worker で並列処理)。
  2. 2Dへ射影 — 3Dの楕円体 Σ を、いまの視点から見た画面上の2D楕円 Σ′ に変換する。Σ′ = J W Σ Wᵀ Jᵀ(W=視点変換, J=透視投影の近似)。この計算を全粒ぶん頂点シェーダが並列に行う。
  3. α合成 — 奥から手前へ、各楕円を不透明度 α で塗り重ねる。手前の粒が濃いほど、奥は透ける。C = Σ cᵢ αᵢ Π(1−αⱼ)

メッシュのラスタライズ(面を三角形として塗る)や、レイトレーシング(画素ごとに光線を飛ばす)とは違い、 3DGSは半透明の楕円を大量に重ねるのが本質です。 ポイントは、この処理にニューラルネットワークが要らないこと。 粒のパラメータがそのまま数値で並んでいる「明示的な表現」なので、 GPUが素直に流し込め、数十万粒でも毎秒60コマで描けます。

Section 5

どうやって作るか — 微分可能レンダリングによる学習

写真との「差」を頼りに、数十万粒を自動で育てる

では、この数十万個の粒のパラメータは、誰がどうやって決めるのでしょう。 手で置くのは不可能です。答えは写真から自動で学習すること。

  1. 撮影と位置推定 — 対象を色々な角度から数十〜数百枚撮る。各写真がどこから撮られたか(カメラ位置)を SfM(COLMAP 等)で推定し、ざっくりした点群を得る。
  2. 粒を置いて描く — その点群を種にガウシアンを配置し、いまのパラメータでスプラッティング描画する。
  3. 写真と見比べて直す — 描いた画像と実際の写真の差(誤差)を測り、「どの粒をどう動かせば差が減るか」を微分可能レンダリングで逆算し、全粒を少しずつ修正する。
  4. 粒を増やす・減らす — 足りない所は粒を分割・複製し、無駄な粒は削除する(自動密度調整)。これを数万回くり返す。

ポイントは、描画(Section 4)の全工程が微分可能に組まれていること。 だから「出力画像の誤差」を各ガウシアンの位置・かたち・色・αまで逆伝播(勾配降下)でき、 ニューラルネットの学習と同じ要領で、粒の集合そのものを最適化できます。 学習が終われば、あとは軽い描画(Section 4)を繰り返すだけ — このビューアが読み込んでいる .splat ファイルは、その学習済みの粒たちです。

…と言われても、「微分」の一言で身構えた人がいるかもしれません。でも、ここで使っている意味は ひとつだけ。「パラメータを少し動かしたら、誤差はどっち向きに・どれくらい変わる?」という 坂の傾きのことです。傾きが分かれば、誤差が減る方向へ一歩ずつ下ればいい。 それを全部のパラメータで繰り返すのが勾配降下=学習です。下で実際にやってみましょう。

粒をひとつだけ、写真(目標)に合わせてみます。右のカーブが「誤差の風景」。 ボールのいる場所の傾きが微分で、矢印は「そっちへ動かせば誤差が減る」という道しるべです。

ヒント:青い粒(またはボール)をドラッグして、誤差 E と傾きの関係をつかんでください。 1歩下るθ ← θ − η·dE/dθ をそのまま1回実行するボタン。 自動で下るで谷底(誤差ほぼ0)まで転がります。タブで「位置」以外に 「大きさ」「濃さ」の坂も試せます — どのパラメータでもやることは同じです。

本物の学習は、いまの「1パラメータの坂下り」を数十万粒 × 全パラメータで一斉に行います。 下はそのミニチュア版 — 数十個の2Dガウシアンが、勾配降下だけで1枚の「写真」に 近づいていく学習の様子です。「差=誤差」の画面が黒く消えていくのを見てください。

ヒント:誤差カーブに時々入る「+16粒」の線は、誤差の大きい場所に粒を足す 自動密度調整(上の手順4)です。輪郭を押すと、粒がどう変形して 写真を分担しているかが見えます。ここでは2D画像1枚へのフィットですが、本物は同じことを 3Dの粒 × 数十〜数百枚の写真に対して行っている、という違いだけです。

Section 6

建築・デザインでの意味

現況を「撮って、歩ける3D」にする

3DGSは、建築のリアリティキャプチャ(現況記録)の道具として急速に使われ始めています。 スマホや一眼で敷地・既存建物・街並みを撮るだけで、写実的でその場を歩き回れる3Dが手に入る。 従来のフォトグラメトリ(写真からメッシュを起こす)より速く・きれいで・軽いため、 現況プレゼン、VRウォークスルー、デジタルツインの下地として相性が良いのです。

一方で、メッシュとは性質が異なるため使い分けが要ります。

観点フォトグラメトリ(メッシュ)3D Gaussian Splatting
表現三角形の面ぼやけた楕円の集合
見た目面はきれいだが細部・透明物が苦手写実的(毛・植栽・反射に強い)
編集・寸法面があり計測・加工しやすい面がなく編集・寸法取りは不得手
描画軽い(普通のポリゴン)軽い(専用ビューア)
向く用途設計・解析・製造に渡す現況記録・プレゼン・体験

表の「見た目 — 反射に強い」の理由は、Section 3 の4部品のうちのにあります。 3DGSの粒は「見る方向によって変わる色」(球面調和関数)を写真から学習できるのに対し、 フォトグラメトリは表面の各点に1色を焼き込むしかありません。 Section 2 のデモで金属の球や水面に切り替え、視線依存 ⇄ 焼き込みを 比べると、この差がそのまま見えます。焼き込みは「撮った角度から見る分には正しいが、 視点を変えると嘘になる」— マットな被写体なら差が出ないので、 つやのない街並みの記録ならフォトグラメトリでも十分、という使い分けにつながります。

Section 7

考えてみよう

仕組みの「なぜ」に、原理で答えられるか

Q1. ガウシアンはなぜ「ぼやけて」いる必要がある? 硬い楕円ではダメ?

ぼやけ(ガウス関数によるなめらかな減衰)があるから、隣り合う粒が境目なく溶け合い連続した面に見えます。 冒頭のビューアのフラットモードは減衰を切った硬い楕円で、結果はモザイク状。 この対比が「なめらかな減衰こそが連続面の正体」だと示しています。学習が滑らかに進む(微分しやすい)利点もあります。

Q2. NeRFと3D Gaussian Splattingは何が違う? どちらも写真から3Dを作るのに。

表現が正反対です。NeRFはシーンをニューラルネット(暗黙関数)で表し、 画素ごとに何度もネットへ問い合わせるため描画が重い。 3DGSガウシアンの集合(明示表現)を直接描くので、同等画質を桁違いに速く出せます。 どちらも多視点写真+微分可能レンダリングで学習する点は共通です。

Q3. なぜ毎フレーム、全部の粒を深度ソートし直すの? 重そうなのに。

粒は半透明で、α合成は重ねる順序で結果が変わる(奥から手前へ、が正しい)ためです。 視点が動けば奥行きの順番も変わるので、毎フレーム並べ替えが要ります。 だからこそ専用のソート(このデモでは Web Worker で並列化)が実装の要になります。 不透明なメッシュのZバッファなら順不同で描けるのと対照的です。

Q4. 現場をスキャンして「測れる3D」が欲しい。3DGSとメッシュ、どちらを使う?

寸法を取ったり設計・BIMに渡すなら、面のあるメッシュ(フォトグラメトリ)が向きます。 3DGSは面を持たない粒の雲なので、計測・加工には不向き。 一方、写実的に見せる・その場を体験させる用途なら3DGSが速くてきれいです。 「測る・作る=メッシュ/見せる・歩く=3DGS」で選ぶのが基本です(Section 6)。