3D Gaussian Splatting(3DGS)は、複数枚の写真から、視点を自由に動かせるフォトリアルな3Dシーンを作る手法です。原理を一言でいえば、シーンを「位置・形・色・透明度を持つ楕円状のにじみ(3Dガウシアン)」の集まりで表し、それを画面へ塗り重ねて描き、写真との差から各ガウシアンを少しずつ直す、という繰り返しです。この記事では原理を表現・描画・最適化の3本柱に分け、原論文と公式実装に書かれた数値(既定のハイパーパラメータ、学習時間、FPS、メモリ)で中身を確かめていきます。
まとめ:3D Gaussian Splattingの原理は表現・描画・最適化の3本柱
- 表現:シーンを100万〜500万個規模の3Dガウシアン(位置・共分散・不透明度・球面調和関数の係数)で陽に持つ。ニューラルネットの重みには埋め込まない。
- 描画:各ガウシアンを2D画面に投影し、16×16ピクセルのタイルごとに深度順で半透明合成する。描画全体が微分可能。
- 最適化:描いた画像と写真の差(L1とD-SSIMを0.8対0.2で混ぜた損失)を勾配で戻し、足りない所は複製・分割、薄いガウシアンは剪定する。
- 結果:原論文の実測(A6000)では、Mip-NeRF360データセットで学習41分33秒・134fps。同じデータでMip-NeRF360は学習48時間・0.06fpsだった。代わりにモデルは734MBと重い。
- 使うときの注意:公式実装は研究・評価用途に限る非商用ライセンス。商用利用では権利者の事前許諾を得るか、Apache License 2.0のgsplatなど、用途を許諾する別実装やツールを選ぶ。
以下、3本柱の順に中身を見たあと、数値・比較・試し方へ進みます。
3D Gaussian Splattingの定義とNeRFとの違い
3D Gaussian Splattingは、INRIA(フランス国立情報学自動制御研究所)のGraphDecoチームなどによる論文「3D Gaussian Splatting for Real-Time Radiance Field Rendering」(Kerbl, Kopanas, Leimkühler, Drettakis/ACM Transactions on Graphics 42巻4号・SIGGRAPH 2023)で発表されました。論文の要旨が掲げる到達点は、1080pで30fps以上のリアルタイム新規視点合成です。
「splat(スプラット)」の意味と描画方法
splatは英語で「べちゃっと塗りつける・はねて飛び散る」という意味です。3DGSでは、点を座標だけの点ではなく広がりを持つ楕円状のにじみとして扱い、それを画面に塗り重ねて絵にします。ポリゴンの面を貼るのでも、光線を1本ずつ追うのでもなく「にじみを塗る」ことが技術名の由来です。splattingはWestoverらによる1980年代末から1990年代のボリューム描画研究にさかのぼり、Zwickerらは2001年にEWA Volume Splattingを発表しました。3DGSは3Dのにじみを2Dへ投影する計算もこの研究から借りています。
NeRFとの画像形成モデルの共通点と陽的表現の違い
NeRF(Neural Radiance Fields)は、空間の各点の色と密度をニューラルネットワークの重みとして暗黙的(implicit)に持ち、描画時はピクセルごとに光線を飛ばして線上の多数の点をネットワークに問い合わせます。3DGSはシーンを3Dガウシアンという離散的な部品として陽的(explicit)に持ち、それを2Dへ投影してα合成します。原論文は、この合成がNeRFと「同等の画像形成モデル」であると述べています。つまり何を計算しているかは同じで、違うのは計算の仕方です。光線上のサンプリングとネットワーク推論を、GPUのラスタライズと並べ替えに置き換えたことが、速度差の正体です。
原理①:3Dガウシアンの集合によるシーン表現
1つ目の柱は「シーンをどう持つか」です。1つのガウシアンが、空間のどこに、どんな形と向きで、どれだけの濃さと色で存在するかを担います。原論文で試したシーンは、最適化後に100万〜500万個のガウシアンになっています。
1つのガウシアンが持つパラメータとPLYの62属性
各ガウシアンは、位置(中心 μ)、共分散 Σ(楕円体の大きさと向き)、不透明度 α、球面調和関数の係数(色)を学習可能なパラメータとして持ちます。公式実装が学習結果を書き出すPLYファイルでは、既定のSH次数3の場合、1個あたり次の62個の値が並びます(scene/gaussian_model.py の construct_list_of_attributes)。
| 属性 | PLYの列名 | 個数 |
|---|---|---|
| 位置 | x, y, z | 3 |
| 法線(未使用・0で出力) | nx, ny, nz | 3 |
| 色の基本成分(SH 0次) | f_dc_0〜2 | 3 |
| 色の方向成分(SH 1〜3次) | f_rest_0〜44 | 45 |
| 不透明度 | opacity | 1 |
| スケール | scale_0〜2 | 3 |
| 回転(クォータニオン) | rot_0〜3 | 4 |
32ビット浮動小数で62個なので1ガウシアン248バイトです。100万個で約248MBになり、3DGSのファイルが数百MBに膨らむ理由がここから分かります。値の半分以上(48個)が色の係数である点も押さえておくと、後述する圧縮手法の狙いが理解しやすくなります。
共分散行列のスケール・回転への分解
共分散行列 Σ をそのまま勾配で更新すると、途中で共分散として成り立たない値(半正定値でない行列)に壊れます。そこで3DGSは Σ を、対角のスケール行列 S とクォータニオンから作る回転行列 R に分けて持ち、Σ = R S S^T R^T で組み立てます。学習で更新するのはスケール3個と回転4個だけで、Σ は毎回そこから作るため、常に正しい楕円体になります。原論文の比較では、向きを持てない等方的な球に制限すると細い構造が再現できず、画質が明確に落ちています。
見る方向で色を変える球面調和関数
金属のハイライトのように、実物は見る角度で色が変わります。3DGSは色を1つの値ではなく、視線方向を入れると色を返す球面調和関数(Spherical Harmonics, SH)の係数で持ちます。公式実装の既定は --sh_degree 3(RGB各16係数・計48個)です。学習は0次(方向によらない色)から始め、1,000反復ごとに次数を1つずつ上げます(train.py の oneupSHdegree)。原論文では、撮影方向に欠落がある場合にSHの0次成分である基本色が不適切な値になる問題を抑えるため、この段階的な導入を採用しています。
原理②:微分可能なタイルベースラスタライズによる描画
2つ目の柱は、速さと学習可能性の両方を支える「3Dガウシアンから画像を作る描画」です。投影や色の合成について勾配を計算しますが、深度ソートやカリングなどの離散的な判定まで微分するわけではありません。実装はCUDAで書かれた専用のラスタライザ(diff-gaussian-rasterization)で、描画と勾配計算を同じ仕組みの上で行います。
3Dガウシアンの2D画面への投影
中心はカメラ行列で画面座標に移します。広がりは、ビュー変換 W と射影変換を局所的に線形近似したヤコビアン J を使い、Σ' = J W Σ W^T J^T で2Dの共分散に変換します。3Dの楕円体が、画面上の2Dの楕円のにじみに潰れる計算です。
タイル分割・深度ソート・αブレンディングの式
画面を16×16ピクセルのタイルに分け、各ガウシアンを重なるタイルの数だけ複製し、「タイル番号+深度」をキーにGPUの基数ソートで一度に並べ替えます。並べ替えはピクセルごとではなく全体で1回なので、ここが高速化の要です。各ピクセルの色 C は、手前から順に
C = Σ_i c_i α_i Π_{j<i} (1 - α_j)
で足し合わせます。c_i はSHから求めた色、α_i は2Dに投影したガウシアンの値に不透明度を掛けたもの、Π(1 - α_j) は手前のガウシアンにどれだけ隠されたか(透過率)です。原論文の付録には数値を安定させる打ち切りの規則も書かれています。
αが1/255未満のガウシアンは合成しないαは0.99を上限に丸める- 累積の不透明度が0.9999を超える手前で、そのピクセルの合成を止める
3つ目の規則のおかげで、奥にある見えないガウシアンは計算されません。逆伝播では、前向きに蓄積した値を各 1 - α で割り戻して透過率を復元します。この除算の分母が0になることを防ぐのは、αを0.99以下にする2つ目の規則です。
原理③:勾配による最適化と密度の自動調整
3つ目の柱は「どうやって写真に近づけるか」です。描画が微分可能なので、写真との差を勾配降下でパラメータへ戻せます。
損失関数と学習ループ
学習では、撮影カメラの1つを選んで描画し、写真との差を損失として測り、位置・スケール・回転・不透明度・SH係数を更新します。損失は (1 - λ) L1 + λ L_D-SSIM で、λ の既定は0.2です(train.py では (1.0 - opt.lambda_dssim) * Ll1 + opt.lambda_dssim * (1.0 - ssim_value))。L1は画素ごとの色の差、D-SSIMは構造の見え方の差を測ります。既定の反復回数は30,000回で、7,000回と30,000回の時点で結果を保存します。
Adaptive Density Control(複製・分割・剪定)の既定値
SfMの点群から始めたガウシアンだけでは、細部が足りない所と無駄が多い所が出ます。そこで学習の途中にガウシアンを増減させます。判断材料は、画面上の位置に対する勾配の大きさです。勾配が大きい=その場所がまだ写真と合っていない、と見なします。
| 処理 | 条件(公式実装の既定値) | 動作 |
|---|---|---|
| 複製(clone) | 勾配≧0.0002 かつ 大きさ≦シーン範囲の1% | 同じガウシアンを1つ増やす |
| 分割(split) | 勾配≧0.0002 かつ 大きさ>シーン範囲の1% | 2個に分け、スケールを1/1.6にする |
| 剪定(prune) | 不透明度<0.005 など | 削除する |
| 不透明度リセット | 3,000反復ごと | 全ガウシアンの不透明度を0.01以下に下げる |
| 実施の範囲 | 600〜14,900反復・100反復ごと | 15,000反復以降は増減しない |
小さいガウシアンで足りない所は「数を増やす」、大きすぎて細部を潰している所は「細かく割る」という使い分けです。不透明度リセットは、カメラ付近に浮いた余計なガウシアン(floater)を一度薄くし、本当に必要なものだけが学習で濃く戻るようにして剪定に回す仕掛けです。3,000反復を過ぎると、画面上で半径20ピクセルを超える、またはシーン範囲の10%より大きいガウシアンも剪定の対象になります(train.py と gaussian_model.py の densify_and_prune)。
SfM(COLMAP)による初期化
出発点のガウシアンはランダムではなく、SfM(Structure from Motion)の疎な点群から作ります。COLMAPで撮影画像からカメラ位置と点群を推定し、各点を初期ガウシアンとして置きます(不透明度の初期値は0.1)。SfMによる初期配置は学習に役立ちます。ただし、必要なのは対応するカメラ情報であり、別の方法で推定・取得した情報を入力できれば、COLMAPで位置推定できない画像でも学習の対象にできます。
原論文の実測値で見る速さと重さ
原論文のTable 1から、Mip-NeRF360データセット(屋内外9シーン)の結果を抜き出しました。原論文によれば、Mip-NeRF360以外の手法はすべてA6000で計測しています。Mip-NeRF360の画質は元論文からの転記で、学習時間はA100を4基積んだノードで12時間かけたものを1基換算した値です。
| 手法 | PSNR | 学習時間 | FPS | メモリ |
|---|---|---|---|---|
| Plenoxels | 23.08 | 25分49秒 | 6.79 | 2.1GB |
| Instant-NGP(Base) | 25.30 | 5分37秒 | 11.7 | 13MB |
| Instant-NGP(Big) | 25.59 | 7分30秒 | 9.43 | 48MB |
| Mip-NeRF360 | 27.69 | 48時間 | 0.06 | 8.6MB |
| 3DGS(7,000反復) | 25.60 | 6分25秒 | 160 | 523MB |
| 3DGS(30,000反復) | 27.21 | 41分33秒 | 134 | 734MB |
読み取れることは3つあります。まず画質(PSNR)はMip-NeRF360とほぼ同等で、描画は約2,000倍速い。次に、7,000反復で止めてもInstant-NGP(Big)並みの画質が6分台で得られる。最後に、メモリはMip-NeRF360(8.6MB)の約85倍、Instant-NGP(Big・48MB)の約15倍の734MBです。原論文も「NeRF系よりメモリ消費が大きく、大きなシーンの学習ではGPUメモリのピークが20GBを超える」と限界を認めています。Tanks&Templesでは30,000反復で26分54秒・154fps・411MBでした。
点群・メッシュ・NeRFとの比較と不得意な場面
以下は典型的な用途の比較です。描画速度は実装・データ量・解像度・GPUに、計測精度は取得方法と尺度合わせに依存するため、表の評価は一律の性能保証ではありません。
3D表現の描画特性と計測・編集適性の比較
| 表現 | シーンの持ち方 | 描画速度 | 見た目の再現 | 寸法計測・編集 |
|---|---|---|---|---|
| 3DGS | 3Dガウシアンの集合 | リアルタイム | 高い | 不向き |
| 点群 | 色付きの点 | 点数次第 | 隙間が見える | 計測に向く |
| メッシュ | 三角形の面 | 速い | テクスチャ次第 | 向く |
| NeRF | ネットワークの重み | 遅い | 高い | 不向き |
3DGSとNeRFは見た目の再現を主目的とし、メッシュのような明示的な表面を直接持ちません。実寸尺度の有無は入力や尺度合わせに依存し、計測精度は別途検証が必要です。図面やCADに渡すなら、点群からメッシュを作る流れのほうが目的に合います(手順は点群データのCAD化の記事で扱っています)。
3DGSの採用を見送るべき場面
次の条件に当てはまるなら、3DGSは第一候補から外します。
- 鏡・ガラス・水面など、反射や屈折が強い被写体が主役(SHによる方向別の色では表しきれず破綻しやすい)
- 撮影の視点が偏っている・枚数が少ない(撮っていない角度にfloaterが出る)
- Webやモバイルでそのまま配信したい(1ガウシアン248バイトのままでは数百MBになるので、圧縮が前提になる)
- 寸法を測る・CADで編集する(面を持たないため、メッシュ再構成を選ぶ)
- 非商用の公式実装を、権利者の個別許諾なしに商用製品へ組み込もうとしている(商用利用を認める別実装を選べば、3DGS自体は候補にできる)
公式実装で原理を確かめる手順
原理を手元で確かめるなら、論文と同じコードである公式実装(graphdeco-inria/gaussian-splatting)を動かすのが近道です。
必要な環境と非商用ライセンス
READMEが挙げる学習の要件は、Compute Capability 7.0以上のCUDA対応GPU、論文と同じ品質まで学習するなら24GBのVRAM、PyTorch拡張をビルドするC++コンパイラとCUDA SDK 11(作者は11.8を使用)です。VRAMの消費は最適化中のガウシアン数で決まり、学習とともに増えます。READMEのFAQは、VRAMが足りない場合に --densify_grad_threshold や --densification_interval を大きくする、--densify_until_iter を小さくする(画質は下がる)、7,000反復で止める、といった対処を挙げています。学習済みシーンを見るだけのビューアは、VRAM 4GBが推奨です。
注意したいのはライセンスです。リポジトリの LICENSE.md(Gaussian-Splatting License)は、Inriaとマックス・プランク情報学研究所が権利を持ち、研究目的の利用者に「non-commercially」、つまり研究・評価目的に限って使用を認めるものです。企業内の研究・評価も許諾対象に含まれます。商用利用では、権利者から事前に明示的な許諾を得るか、商用利用を認める別実装・ツールを選びます。たとえばnerfstudioプロジェクトのラスタライズライブラリ gsplat はApache License 2.0で公開されています(PyPIの最新版は2025年7月4日の1.5.3)。
convert.pyからtrain.pyまでの流れ
撮影した画像を <location>/input に置き、COLMAPでカメラ位置を推定してから学習します。以下のコマンドでは、入力パスを自分の環境に合わせ、評価用の2行にある実行IDのプレースホルダーを山括弧ごと実際の出力先IDへ置き換えてください。
git clone https://github.com/graphdeco-inria/gaussian-splatting --recursive
cd gaussian-splatting
conda env create --file environment.yml
conda activate gaussian_splatting
# COLMAPで歪み補正済み画像とSfM点群を作る(COLMAPとImageMagickにパスを通しておく)
python convert.py -s /data/scene --resize
# 学習(既定は30,000反復。--eval で学習用と評価用に分ける)
python train.py -s /data/scene --eval
# 評価画像の書き出しと指標の計算
python render.py -m ./output/<実行ID>
python metrics.py -m ./output/<実行ID>
カメラモデルは SIMPLE_PINHOLE か PINHOLE である必要があり、convert.py がその形式に変換します。2024年10月の更新で、学習の高速化、深度による正則化、アンチエイリアス、露出補正が公式実装に取り込まれました。学習済みモデルは、Windows向けのSIBRビューアや、PLYを読めるブラウザ向けビューアで開けます。
派生手法とデータ形式の広がり
2023年の発表以降、原理の弱点を補う派生手法と、配布用のデータ形式が出そろってきました。
原理の弱点を補う主な派生手法
派生手法の多くは、3本柱のどれか1つを差し替えたものとして読めます。
| 手法 | 発表 | 差し替えた柱 | 狙い |
|---|---|---|---|
| Mip-Splatting | CVPR 2024(Best Student Paper) | 描画 | 拡大・縮小時のエイリアスを抑える |
| 2D Gaussian Splatting | SIGGRAPH 2024 | 表現 | 平たい円盤で面の形状を正確に取る |
| 3DGRT(NVIDIA) | SIGGRAPH Asia 2024 | 描画 | ラスタライズをレイトレーシングに置換 |
| 3DGUT(NVIDIA) | CVPR 2025(Oral) | 描画 | 投影の線形近似をやめ非線形カメラに対応 |
原理②で見た投影 Σ' = J W Σ W^T J^T は、射影をヤコビアンで線形近似するEWA splattingの式です。魚眼レンズのように歪みの大きいカメラではこの近似が崩れるため、3DGUTはここをUnscented Transformに置き換え、反射や屈折に要る二次レイにも対応しました。3DGRTはガウシアンの粒子にBVH(境界ボリューム階層)を組み、画素ごとにレイを飛ばします。NVIDIAによるこの2手法は、反射・屈折や特殊なカメラへの対応を狙って描画処理を変えたものです。
PLYからSPZ・glTFへ進むデータ形式
公式実装のPLYは、既定のSH次数3ではヘッダーを除いて1ガウシアン248バイトです。大規模なシーンを配布する場合は、転送量に応じて圧縮を検討します。Niantic Labsが公開したSPZ(MITライセンス)は、READMEで「対応するPLYより通常約10分の1に小さく、見た目の差はわずか」と説明されている圧縮形式です。
標準化も進みました。Khronos Groupは2026年2月3日にglTFの拡張 KHR_gaussian_splatting のリリース候補を発表し、仕様のREADMEでは、2026年10月28日の確認時点で状態が「Complete, Ratified by the Khronos Group」とされています。この拡張は位置・回転・スケール・不透明度・球面調和関数を点プリミティブの属性として持たせるもので、原理①で見たパラメータがそのまま標準の形になりました。対応していないビューアでは疎な点群として表示される、という逃げ道も仕様に組み込まれています。glTFを読める Three.js のようなWeb向け3Dライブラリやゲームエンジンへの持ち込みは、この拡張への対応状況を見て判断するのが確実です。
よくある質問
3D Gaussian Splattingの原理を数式なしで一言でいうと?
「色と大きさと透明度を持つ無数のにじみを空間に置き、画面に塗り重ねて絵にし、写真との差でにじみを直していく」技術です。塗る・比べる・直すの繰り返しが原理の核で、足りない所ではにじみを増やし、要らないものは消します。
「splat」とはどういう意味?
英語で「べちゃっと塗りつける・はねて飛び散る」という意味です。点を面や線ではなく広がったにじみとして画面に塗り重ねる描画方法を指し、その塗り方がそのまま技術名になっています。
NeRFと3D Gaussian Splattingはどちらを使うべき?
リアルタイムで動かしたい、ゲームエンジンやWebで見せたいなら3DGSです。原論文の測定では、ほぼ同じ画質でMip-NeRF360の0.06fpsに対し134fpsでした。保存容量を小さくしたい(Mip-NeRF360の8.6MBに対し3DGSは734MB)なら、NeRF系に分があります。
3DGSを動かすにはどんなGPUが必要?
公式実装で学習するには、Compute Capability 7.0以上のNVIDIA製GPUが必要で、論文と同じ品質まで学習するならVRAM 24GBが目安です。学習済みシーンを見るだけならビューアの推奨はVRAM 4GBで、要求はずっと軽くなります。
2D Gaussian Splattingとの違いは?
表現の柱が違います。3DGSは3軸に広がる楕円体で、見た目の再現と描画速度を優先します。SIGGRAPH 2024で発表された2D Gaussian Splattingは、ガウシアンを厚みのない円盤にして物体の表面に沿わせ、形状(メッシュ)を正確に取り出すことを優先します。見せるためなら3DGS、形を取り出したいなら2DGSが目安です。