Blog教程式综述 · 2023.08 — 2026.05
把一亿个 Gaussian 塞进几兆
2023 年 8 月 Kerbl 等人发布 3D Gaussian Splatting 时,一个场景在硬盘上往往
1.4 GB。三年后,同一类场景能压到 3 MB 而几乎看不出区别——
三个数量级。本文从头到尾讲清楚是怎么做到的、为什么有效,以及不同方法之间的关键区别。
预设读者:略懂 NeRF、SDF、机器学习、微积分、线性代数。没碰过 3DGS 也不要紧——
预备知识自带补课。
约 45 篇论文 · 6 个交互 demo · 多段可读伪代码 · 最后更新 2026-05-19
PART I预备知识
§1.13D 高斯到底是什么
先把 radiance field 这词从脑子里赶出去。Splatting 语境下的 "3D Gaussian"
就是一团飘在空间中的各向异性彩色绒球。数学上:
G(x)=exp(−21(x−μ)⊤Σ−1(x−μ))
其中 μ∈R3 是中心,Σ∈R3×3 是对称正定的协方差,
告诉你这团绒球被拉伸成什么形状、转到哪个朝向。协方差永远参数化成
Σ=RSS⊤R⊤:R 是单位四元数对应的旋转矩阵(4 floats),
S 是对角的各向异性 scale(3 floats)。这样优化的永远是 q 和 s,
最后构造出来的 Σ 结构上就一定对称正定,避免训练崩溃。
拖动旋转相机 · 拖滑块改形状
线框是 2σ 等密度面——高斯密度衰减到峰值 e−2 的位置。彩色斑点是它真正被渲染(splat)出来的样子。
§1.2"Splatting" 是怎么回事
要把一个 3D Gaussian 画到屏幕上,不需要 ray marching,也不要求根。走捷径:
- 把 3D 中心 μ 投影到屏幕得到 2D 点;
- 把 3D 协方差 Σ 线性化投影到屏幕得到 2D 协方差 Σ′,这是 EWA splatting 的标准做法;
- 得到一个有指数衰减的 2D 椭圆,画进 framebuffer,alpha 混合。
所谓 "splat" 就是第 3 步——Gaussian 像一坨湿颜料被 溅 到屏幕上。比起 NeRF 那种沿射线 64–256 次 MLP 查询,这便宜得离谱,所以 3DGS 能在消费级显卡上跑 100+ FPS。
一个像素的最终颜色,是所有覆盖这个像素的 Gaussian 按深度从后往前排序后,做经典的 Porter-Duff "over" 合成:
Cpixel=i∑ciαij<i∏(1−αj)
这就是 1980 年代图形学的 alpha 合成公式。αi 既包含 Gaussian 自身存储的不透明度,也包含它在这个像素位置上的 2D 足迹。
§1.3球谐函数(Spherical Harmonics)二分钟
3DGS 渲染出来很像真照片——你转相机时高光会跟着移动——是因为每个 Gaussian 存的不是一种颜色,而是一个关于视角方向的函数:“俯视时我是亮白的,侧视时我是暗灰的。”这个函数定义在单位球面 S2 上。
球面上怎么压缩函数?跟圆上(Fourier 级数)、直线上(Taylor 级数)一回事:选个基,展开。球面上的天然基就是球谐函数 Yℓm——它们是球面 Laplace 算子的特征函数。展开到 degree L,一共 (L+1)2 个基函数:
原版 3DGS 用 degree 3,单个 Gaussian 仅颜色就要 48 个系数。这就是文件里的那头大象。
§1.4训练循环
压缩方法挂载在训练流程的不同阶段。30 行伪代码看清整个循环:
python
def train_3dgs(cameras, photos, iters=30000):
G = init_from_sfm_points() # 从稀疏点云起步 / start from SfM points
optimizer = Adam(G.parameters())
for step in range(iters):
cam, photo = sample(cameras, photos)
rendered = rasterize(G, cam) # splatting pipeline
loss = L1(rendered, photo) + λ * D_SSIM(rendered, photo)
loss.backward()
optimizer.step()
# --- adaptive density control(魔法所在 / where the magic is) ---
if step % 100 == 0 and step < warmup_iters:
clone_high_gradient_gaussians(G)
split_oversized_gaussians(G)
prune_low_opacity_gaussians(G)
return G # ~3M Gaussians, ~700 MB on disk
三件事要记住:
- 全程都是梯度下降。每个 Gaussian 的位置、scale、四元数、opacity、SH 系数都是 Adam 优化的可学参数。
- Adaptive density control 会在训练期间动态地增长种群——梯度大的 clone/split,opacity 低的 prune。最终的 3M 数量是学出来的。
- 光栅化对 3D 参数可导。梯度能从像素一路传到 3D Gaussian 的位置和形状——这是整套机制的工程关键。
压缩方法接入这个循环的三个口子:
- 训练时:改 density control 规则(Mini-Splatting, Taming-3DGS)或加 rate-aware loss(HAC, ContextGS);
- 训练后:剪枝 / 量化 / 重编码 .ply(LightGaussian 第三阶段、MesonGS、FlexGaussian);
- 推理时前馈:一个预训练网络一次性压任何场景,不重训(FCGS)。
§1.5一个 .ply 里到底有什么
Inria 2023 的原版代码把场景存成 .ply——是的,90 年代的那个点云格式,借尸还魂。打开一个真正的 3DGS .ply,header 长这样:
text
ply
format binary_little_endian 1.0
element vertex 3019823 # ~3M Gaussians
property float x
property float y
property float z # position (3 floats)
property float nx
property float ny
property float nz # unused normal — always zero
property float f_dc_0
property float f_dc_1
property float f_dc_2 # SH degree 0 ("DC" mean color)
property float f_rest_0
property float f_rest_1
...
property float f_rest_44 # SH degree 1-3 (45 floats = 15 bands × RGB)
property float opacity # pre-sigmoid logit, 1 float
property float scale_0
property float scale_1
property float scale_2 # log-scale (3 floats)
property float rot_0
property float rot_1
property float rot_2
property float rot_3 # quaternion (4 floats)
end_header
<raw binary, 62 floats × 4 bytes × 3M Gaussians ≈ 750 MB>
连“废东西”都是真的——那三个 normal 永远是 0(.ply 旧约定),白白吃掉 ~36 MB。几个值得注意的格式细节:
- opacity 存的是 logit,不是 [0,1] 里的概率。要取 α 得过 sigmoid。这样优化平滑,且 logit 可以放心 clip。
- scale 存的是 log。实际 σ 是
exp(scale_i)。同样为了优化友好,且强制非负。
- SH 拆成 DC + rest。DC 是 degree 0(沿所有视角的平均色),rest 是 45 个高频系数。
字节都花到哪儿了
字节都花在 SH 上。
为什么会有这么多冗余?
不是格式蠢,而是 750 MB 里藏着几种不同口味的冗余,每个 family 都擅长抓其中一种:
几乎所有现代方法都把 2–3 种冗余一起挖。一篇压缩论文的“艺术”在于:选哪些冗余,按什么顺序。
组合自己的压缩配方
注意:右侧的 PSNR 是玩具启发式,不是真 PSNR。但定性走势是对的——剪枝伤几何、量化伤平滑度、SH 截断伤高光、彼此约略乘。真实方法各种花式手段就是避开每个失败模式。
PART II全景
§2.1六个旋钮 · 总体分类
3DGS.zip 综述和 IEEE 2025 综述都点明了一个微妙但有用的区分:
两者可以同时用——大部分 SOTA 都是两者并行。下面六个旋钮把正交的杠杆分开讲,方便你想清楚怎么组合。
六个旋钮简述
① Pruning — “扔掉没用的”。最直接。训练后常能扔掉 80-90% 还几乎无损,得益于 adaptive density control 通常过头。问题在于怎么打分:opacity、ray hit、Hessian 行列式、view-frustum maxα⋅τ……纯 pruning 一般能换 5-10×。
② Quantization — “每个数少几个比特”。Float32 对几乎所有属性都 overkill。三种风味:scalar / vector (VQ) / 学到的 latent。一般能在 pruning 之上再换 5-10×。
③ SH attack — “75% 子问题”。SH 占文件的 3/4,三个子策略——每个 Gaussian 自适应 degree、distillation 到低 degree、整个换成 hash grid / SG / 因子分解。每招都是高杠杆。
④ Anchors — “从稀疏 anchor 解码出密集 Gaussian”。Scaffold-GS 的开山之举:稀疏 anchor + 小 MLP 在推理时生成邻近的 Gaussian。这是文献里最具结构性的改写,绝大多数 SOTA 都建立在 Scaffold-GS 之上。
⑤ Entropy coding — “按惊讶程度花比特”。Shannon 的老想法,结合学到的概率先验(hash-grid hyperprior、自回归 context、SH 的 Laplace 闭式分布……)。和 Anchor 联手是当前 SOTA。
⑥ Industry formats — “用现成的”。SOG / SOGS(图像编码器)、SPZ(quantize + gzip)、glTF KHR_gaussian_splatting(Khronos 2026 标准)。研究方法和工业部署的桥梁。
哪些组合真的赢
§2.2大小–质量 Pareto 一张图
在切进每个 family 之前,先看全景:Mip-NeRF 360 上每个方法的位置。横轴是文件大小(log scale,越左越好),纵轴是 PSNR(越上越好)。悬浮看名字:
悬浮显示
几个观察点:原版 3DGS 坐在 ~734 MB / 27.4 dB;HAC++、ContextGS、CodecGS 在 3-10 MB 还能匹配甚至超过 baseline——70-100× 已经“现役”;SOG/SOGS 略大一点但是工业部署版;FCGS 一族在右边角,付出大小代价换“不用每场景重训”。
PART III剪枝 Pruning
§3.1剪枝(Pruning)—— 哪些 Gaussian 可以直接删
原版 3DGS 在训练时会不断增长 Gaussian 数量:哪里梯度大就 clone 或 split,故意“宁多勿少”,期待 opacity 阈值把无用的清理掉。问题是没清理干净——最终的 3M Gaussian 里只有一小部分真的扛着画面,其余的太暗、太小、或者藏在别的后面。
压缩问题就简化成打分函数的设计。
不同打分函数下扔掉了什么
“随机”几乎立刻就把轮廓打废了,opacity 单独则会先丢高频。真正好的打分函数试图在不算 Hessian 的前提下逼近 Hessian。
LightGaussian— Unbounded Compression for 3DGS
原版 .ply 太大;既要剪、又要把剩下的 SH 颜色压扁。
关键想法 三阶段流水线:
(1) global significance 打分剪枝——按 opacity × hit count × volume 给每个 Gaussian 一个分数,砍掉低分;
(2) SH 蒸馏——以全 SH 模型为 teacher,用 pseudo-view 训一个 degree 3→2 的 student;
(3) VecTree 量化——Morton-order octree on positions、K=8192 codebook on lowest-significance SH、float16 on geometry。
体积归一化(除以 90 分位数)是关键创新:没有它,背景那种“覆盖很多 ray 但没编码任何细节”的大 blob 会主导分数。
大小 727 → 42 MB (Mip-NeRF 360, ∼17×)PSNR 29.13 → 28.45 (−0.68 dB)FPS 139 → 215canonical 三段式:剪 → 蒸馏 → 量化。后续几乎每篇都是在和它对比。
Mini-Splatting— Representing Scenes with a Constrained Number of Gaussians
很多 Gaussian 长得太大,在高频区域抹成一片,但 density control 已经罢工了。
关键想法 不是剪,而是重新分布。三段式:
- Blur split:屏幕投影超过阈值就强制 split——这些就是高频区里的“花猫”。
- Depth re-initialization:射线-椭球求交得到稠密深度,从深度点重新撒 Gaussian 填几何洞。
- Probabilistic simplification:按 blending weight 概率保留,比硬阈值更好地保住覆盖统计。
3.35M → 0.49M Gaussians (∼7×)PSNR 27.47 → 27.34Mini-Splatting-D 变体在 Mip-NeRF 360 的 SSIM/LPIPS 上甚至超过 Zip-NeRF——更少的 Gaussian,更好的渲染。
RadSplat— Radiance Field-Informed Gaussian Splatting
用噪声照片做监督,Gaussian 会浪费容量去拟合噪声。
关键想法 先训一个 Zip-NeRF 作为 teacher 兼初始化,再训 Gaussians 拟合 teacher 的“干净渲染”,最后用“max-contribution” 剪枝。
Max(不是 sum!)是关键:“只从一侧能看到”的 Gaussian 不应被惩罚——那一侧也许就是它存在的全部理由。score h(pi)=maxrαirτir,其中 τ 是从前面累积的透过率。
Mip-NeRF 360 PSNR 28.14 (vs 3DGS 27.20)3.16M → 0.37M Gaussians (lightweight)907 FPS唯一一个在大幅剪枝的同时提升了 PSNR 的方法。“NeRF 当 teacher”自此变成标准技巧。
Trimming the Fat— Efficient Compression of 3D Gaussian Splats
想用 3DGS 已经在算的信号做剪枝,不额外开销。
关键想法 双信号:保留当 ∣α∣ 和 ∣∇α∣ 都大于 γ 分位数时才留。低 opacity = 不可见;低梯度 = loss 不再关心它。两者都低意味着完全无用。迭代剪 + 短期 fine-tune。
734 → 119 MB at γ=0.5 (∼6×)激进模式 ∼50×600 FPS几乎免费的剪枝(两个信号都本来就有)。文献里最便宜的默认 baseline。
PUP 3D-GS— Principled Uncertainty Pruning
opacity heuristic 不知道“这个 Gaussian 对 loss surface 究竟多重要”。
关键想法 直接计算每个 Gaussian 关于空间参数的 L2 loss 的 Hessian 的 log-determinant。高分意味着 loss 在那个 Gaussian 周围“很陡”——它确实重要。Ui=logdet(∇x,sIG⋅∇x,sIG⊤)。在收敛模型上这等价于 Fisher information 限制到空间参数。一次性剪 90%,再短期 fine-tune。
PSNR 26.67 @ 90% prune (vs LightGaussian 26.28)746 → 74.65 → 14.44 MB (+VecTree, ∼51×)204 FPS理论上最干净的打分——直接来自二阶优化。代价是 per-Gaussian Hessian 计算比 opacity 贵。
Taming 3DGS— High-Quality Radiance Fields with Limited Resources
既然密度控制总过头,能不能预防过头,而不是事后剪?
关键想法 训练时就带预算地控制密度。综合 score = 位置梯度×50 + opacity×100 + blending weight×50 + 距中心×50 + view saliency×10 + scale×25 + pixel coverage×0.1 + depth×5。每轮只让 top-score 的 Gaussian clone/split,直到用户给定的预算。Gaussian 数量从不爆炸。
0.63M Gaussians vs 3.31M baseline (∼5×)PSNR 27.31 vs 27.46训练时间 11 min vs 43 min“预防性医疗”而非“事后开刀”。教学上很重要:压缩可以从训练时就开始。
GaussianSpa— Sparse 3D Gaussian Splatting via Optimization-based Pruning
关键想法 把“Gaussian 数量”当成稀疏优化问题——加一个 ℓ0-like 罚项约束“存在性”,ADMM 风格交替优化。10-15× 压缩、几乎无 quality loss。
Mip-NeRF 360 ~17 MB / 27.4 dB把经典稀疏优化机器(LASSO、ADMM)搬到 3DGS。“压缩 ≡ℓ0 正则化”是个统一框架。
PART IV量化 Quantization
§4.1量化(Quantization)—— 每个数少花几个比特
把连续(或高比特)值映射到更小的离散字母表,就是量化。3DGS 上有四种风味:
Compact3D (Navaneet)— Compressing Gaussian Splat Radiance Fields
⚠ 命名混乱:这篇不是 Lee 等人的 Compact-3DGS,也不是 Liu 等人的 CompGS。
关键想法 在 SH 系数和协方差上做 K-means 矢量量化(QAT,训练后期重跑 K-means)。两个 codebook:4096 codes for color (SH), 16384 codes for covariance (scale+rotation)。位置和 opacity 不 量化——太敏感。Index 按 Morton 顺序排序后 RLE。
相邻 Gaussian 落在同一 cluster 的概率高,于是 RLE 自然有长 run。
Mip-NeRF 360 778 → 19 MB (∼41×)PSNR 27.42 → 27.122.5× faster rendering
Compact-3DGS (Lee)— Compact 3D Gaussian Representation for Radiance Field
SH 占 75% 文件——能不能整个换成共享神经场?
关键想法 完全抛弃 SH。view-dependent color 从 共享 Instant-NGP 风格 hash grid 查询:以 Gaussian 位置 + 视角方向送入小 MLP 得到 RGB。scale & rotation 用 Residual VQ 级联 codebook;opacity 用 8-bit scalar;hash-grid 参数用 8-bit + Huffman。
RVQ:256-code codebook 抓粗几何,第二个 256-code 抓残差……4 级 = 32 bit,但表达力等价于 2564≈4 G 条目的单 codebook。
>25× compression on Mip-NeRF 360~28–48 MB 取决于配置文献里结构最激进的量化论文。“用 hash grid 共享 appearance”这条思路改变了之后所有人怎么看 SH。
EAGLES— Efficient Accelerated 3D Gaussians with Lightweight Encodings
关键想法 不是量化原始属性,而是量化一个学到的 latent,再用小 MLP 解码回属性。 SH color → 16-D latent;rotation → 8-D;opacity → 1-D。position、scale、SH-DC 不动(太敏感)。forward 时 round 到整数,用 straight-through estimator 让梯度通过。
类比:VQ 是字典查找,EAGLES 是 autoencoder——用小 MLP 换“低比特 latent 仍能覆盖整个属性流形”。
Mip-NeRF 360 PSNR 27.15 (−0.3 dB)量化属性: 211 → 6 MB (∼35×)整体场景 10–20×
Compressed 3DGS (Niedermayr)— Sensitivity-Aware Vector Quantization
关键想法 标准 K-means 把每个维度等权重对待,但引起渲染明显变化的属性槽位应该更靠近 codebook entry。用 sensitivity = 渲染对参数的梯度,做敏感度加权 K-means,然后 QAT。
最高 31× 压缩 (avg 26×)Bicycle: 1.5 GB → 47 MBTruck: 600 MB → 21 MB∼4× faster rendering敏感度加权 = importance sampling 的自然推广。RadSplat 加权 Gaussian,这篇加权属性槽位。
MesonGS— Post-training Compression of 3D Gaussians via Eulerian + RAHT
关键想法 从 MPEG 点云压缩(G-PCC)那边借工具——RAHT 小波变换、四元数→欧拉角(3 数字代替 4)、块标量量化 + 短期 fine-tune。
RAHT (Region Adaptive Hierarchical Transform) 是点云编码标准里的层级小波——把空间相关的属性集中到 DC + 低熵 AC,跟 JPEG 的 DCT 思路一致,只是适配在不规则点云上。
Mip-NeRF 360: 641.7 → 27.6 MB (23.2×)PSNR 28.98 → 28.61 (−0.37)T&T: 421.9 → 17.0 MB, PSNR drop −0.04把 3DGS 接上成熟的点云压缩世界——跨领域借力的好例子。
NSVQ— Noise-Substituted Vector Quantization
关键想法 训练 codebook 时不用 straight-through estimator,而是在前向注入和量化等价的噪声作为代理。梯度自然流过,推理时换回真正的量化。
这是一个小但重要的训练 trick:经典 VQ 训练有先有鸡蛋还是先有鸡的问题(梯度过不了 arg-min);STE 有偏;matched-noise 无偏且实际表现强很多。
最高 45× model-size reduction
Reduced-3DGS— Reducing the Memory Footprint of 3D Gaussian Splatting
关键想法 每个 Gaussian 拥有自己的 SH degree(0/1/2/3)。哑光墙上的只需 degree 0(一个 RGB triple),高光上的保留 degree 3。然后对残余系数做 codebook 量化。
∼27× 总压缩PSNR drop: 0.21 dB“不是所有像素都该分到相同比特”的最干净教学例子。后面 anchor 和 SH 章里都会再见。
FlexGaussian— Training-free, On-device 3DGS Compression
关键想法 给一个刚训练好的 3DGS 文件,几秒内压完,不用 fine-tune。属性自适应剪枝 + INT8/INT4 channel-wise 混合精度量化 + 在线适配。手机可部署。
最高 96.4% 压缩<1 dB PSNR drop文献里最快的“实战编码器”——秒级出可用文件。Capture-then-share 场景的关键。
PART V球谐压缩 SH
§5.1球谐压缩 —— 75% 子问题
回忆:每个 Gaussian 48 个 SH 系数(16 bands×3 RGB),3M 个 Gaussian 加起来 ~570 MB——~75% 的文件。在 SH 上做任何工作都有 4-5 倍的杠杆。
有意思的是大多数系数都接近 0。大部分表面接近漫反射——degree 0 就够了。只有高光和视角依赖反射才真的需要高 band。
高 band SH 系数严重集中在 0 附近——天然适合熵编码或激进剪枝。
五条策略,按激进程度递增:
- Per-Gaussian degree adaptation — 每个 Gaussian 自己的 degree
- SH distillation — 高 degree teacher 蒸馏到低 degree student
- 用 neural field 替代 SH — 整个换成共享 hash grid
- 换基 — 用 Spherical Gaussian lobe / 因子分解
- 对 SH 做参数化熵编码 — 直接利用 Laplace 结构
Strategy 1: Reduced-3DGS
已在 PART IV 详细介绍。要点:每个 Gaussian 自适应 degree 0/1/2/3 + codebook 量化剩余。∼27× 总压缩,PSNR 仅降 0.21 dB。
Strategy 2: LightGaussian SH distillation
已在 PART III 详细介绍。SH 蒸馏部分:以全 SH 模型为 teacher,pseudo-view jitter 训一个低 degree student。学生学着用低 band 系数“假装”高 band 的高光效果。
跟 Hinton 等人 2015 经典知识蒸馏一回事——只是换到 view-dependent appearance 上。
Strategy 3: Compact-3DGS (Lee) — SH → hash grid
已在 PART IV 详细介绍。要点:完全抛弃 SH,view-dependent color 从共享 hash grid 查询 + 小 MLP 解码。每 Gaussian SH 成本:0 floats。共享成本:~30 MB hash grid + ~100 KB MLP,摊到几百万 Gaussian 上。
本质上 = NeRF appearance + 3DGS geometry。两个世界融合最干净的一例。
GES— Generalized Exponential Splatting
关键想法 偷换 primitive:把 exp(−x2) 换成 exp(−∣x∣β),β 可学。锐边能用更少 primitive 表示 → 间接省 SH。
严格说这不是 SH 压缩,是“primitive design 改了之后 SH 总量随之减少”。常和 SH 方法一起讨论但更属于 compaction 维度。
Mip-NeRF 360: 734 → 377 MB186 FPS vs 134
F-3DGS— Factorized 3D Gaussian Splatting
关键想法 把 (NGaussian×Nattr) 大矩阵当成低秩,CP 分解(rank ∼16)从几个轴向因子向量恢复每个 Gaussian 的属性。
TensoRF 一脉的延续——3D tensor 可分解成 1D 向量外积之和。3DGS 的 tensor 是 "Gaussian × attribute",rank 远小于两个维度。
~4–7 MB 每个场景
SG-Splatting— Spherical Gaussian lobes
关键想法 用 ~10 个 Spherical Gaussian lobe 替换 48 个 SH 系数。一个 SG 是 exp(λ(d⋅μ−1)) —— 球面上以 μ 为中心、λ 为锐度的方向性 Gaussian。
SH 是全局基(每个 band 在整个球面上有支撑),SG 是局部基(只在中心方向附近“亮”)。对典型场景外观(少量高光 + 大部分漫反射),SG 是更紧凑的表示。
2000 年代图形学(Tsai & Shih 2006)就用 SG 做 precomputed radiance transfer,3DGS 时代被重新发掘。
48 → 10 颜色参数 (∼5×)
EntropyGS— Parametric Entropy Coding
关键想法 把 SH AC 系数的直方图画出来——几乎完美的 Laplace 分布。那就拟合 Laplace,按这个先验做 arithmetic coding。不需要 context model、不需要 MLP——就一个闭式分布。
其它属性(rotation、scale、opacity)用 Gaussian mixture。per-Gaussian 分布参数估计后驱动 arithmetic coder。
∼30× rate reduction10× model size解码快 (无神经网)教学宝藏:100 年前的统计学还在管用,不是所有事都要神经网络。
PART VI锚点法 Anchors
§6.1锚点法 —— 存稀疏,渲染时生成密集
在 3DGS 场景里走一遭,会发现一个明显事实:相邻 Gaussian 的属性高度相似——咖啡桌面被几百个 Gaussian 覆盖,它们都想说同一件事:“我棕色、扁平、哑光。” 每个 Gaussian 都存满 59 floats 是天大的浪费。
那能不能改成:把属性存在稀疏 anchor 点上(voxel 网格),渲染时让一个小 MLP 现场生成邻近的 Gaussian?这就是 Scaffold-GS 的赌注——也是整个领域的转折点。
Scaffold-GS— Structured 3D Gaussians for View-Adaptive Rendering
每个 Gaussian 独立漂浮,冗余巨大;且对视角/光照变化脆弱。
关键想法 不存每个 Gaussian。在 voxel 网格上撒稀疏 anchor,每个 anchor 携带一个 feature vector(如 32-D)和 k 个可学 offset 向量(如 k=10)。渲染时,MLP 接 (anchor feature, view direction, view distance) → 预测 k 个 neural Gaussian 在 anchor_pos + offset_i 处的 opacity、颜色(替代 SH 直接出 RGB)、scale、rotation。anchor 沿训练动态 grow/prune。
磁盘存:anchor 位置 + feature + 缩放因子 + k 个 offset + MLP 权重(几百 KB)。推理生成:每个 Gaussian 的所有属性。
View-dependent trick: MLP 直接吃 view direction,不再需要 SH。这也是为什么 Scaffold-GS 经常 PSNR 还更高——MLP 能表达比 degree-3 SH 更平滑的视角依赖。
Mip-NeRF 360: 734 → 156 MB (∼5×)PSNR: 27.4 → 27.50 (更高!)Deep Blending: 676 → 66 MB原版 3DGS 之后最重要的一篇。不是压缩论文,是重新定义了“3DGS 场景是什么”。之后几乎每篇 SOTA(HAC, HAC++, ContextGS, CompGS, GaussianForest)都在 Scaffold-GS backbone 上。
Octree-GS— LOD-Structured 3D Gaussians
关键想法 把 Scaffold-GS anchor 放进 octree,按视距动态决定走多深。远处只解码粗 LOD。每层 anchor 沿 cumulative LOD 累加渲染;可学的 per-anchor LOD bias 补强高频区域。
Mip-NeRF 360 PSNR 28.05Deep Blending: 30.49 / 112 MBanchor compression 与“超大场景可扩展渲染”的桥。size 与 Scaffold-GS 接近,主要赢在不同视距下的渲染一致性。
GaussianForest— Hierarchical-Hybrid 3DGS
关键想法 把 Gaussian 组织成森林(树):叶存快变属性(position, opacity)显式;内部节点持共享 feature,MLP 解码出多个叶子的慢变属性(rotation, scale, color)。
教学陈述:变化剧烈的存进来,变化平缓的共享。
Mip-NeRF 360: 827 → 85 MB (GF-Large), PSNR 27.45Deep Blending: 701 → 98 MB
IGS / Implicit-GS— Multi-level Tri-plane
关键想法 用多分辨率 tri-plane(三个 2D feature grid)代替 per-Gaussian 属性;小 MLP 按位置查询解码。tri-plane 是 2D 平滑场,设计上就能被现成图像编码器良好压缩。位置点云另行重排做无损压缩。
“anchor → tiny MLP → Gaussian” 模板的灵活性体现——anchor 可以是点、voxel、hash 桶、tri-plane 采样点、tree 节点。
CompGS (Liu)— Compressed Gaussian Splatting via Hybrid Primitives
关键想法 两类 primitive:少量 anchor primitive 持完整几何,大量 coupled primitive 只存从 anchor 预测出的小残差。Rate-distortion loss λR+D + hyperprior Gaussian entropy model 驱动量化。
视频编码的精确类比:anchor = I-frame,coupled = P-frame,只存 delta。
压缩比: 45–175×Mip-NeRF 360 ~17 MB / 27.26 PSNRPlayroom: 550 → 5 MB
Smol-GS— Compact Splat via Octree Positional Encoding
关键想法 围绕octree positional encoding + 学到的 per-splat feature 构建紧凑表示。坐标递归 voxel 层级;feature 经熵编码。Mip-NeRF 360 上 4.87 MB / 27.61 PSNR——2025 年末最紧凑之一。
PART VII熵编码 Entropy
§7.1熵编码 —— SOTA 所在
如果量化是“把每个数 round 到几比特”,熵编码是“按 surprise 付钱”。和 anchor 联手是把 3DGS 推过 100× 的关键。
三种拿先验的办法
HAC— Hash-grid Assisted Context for 3DGS Compression
Scaffold-GS 把 size 砍到 156 MB 就停了,能再往下吗?
关键想法 取 Scaffold-GS anchor,联合训一个多分辨率 binary hash grid。每个 anchor 按位置查 hash 得 feature;小 MLP_c 把 feature 转成每个属性的 Gaussian 分布 (μ,σ);anchor 在这个预测分布下做 arithmetic coding。
这是学到的图像压缩(Ballé 2017/2018)框架移植到 3DGS——hash grid 是 hyperprior,MLP 把 hyperprior 翻译成 per-anchor distribution。训练时显式最小化表示的熵(loss 里加 rate 项 λR+D)。
"binary" 是指 hash grid 值量化到 {−1,+1}——hyperprior 自身基本免费。
Mip-NeRF 360: 15.3 / 21.9 MB (low/high)PSNR: 27.53 / 27.77Deep Blending: 4.4 MB / 29.98 PSNR75× over 3DGS, 11× over Scaffold-GS, 无 PSNR 下降。后续所有 entropy-coding 工作的蓝图。
HAC++— Towards 100× Compression of 3DGS 关键想法 在 HAC 之上加 (1) intra-anchor context——同一 anchor 的 k 个 sibling Gaussian 互相预测;(2) 每属性自适应量化步长;(3) 可学的 mask 训练时丢弃无用 Gaussian。
intra-anchor 部分填上了 HAC 的漏洞:一个 anchor 衍生的 k=10 个 Gaussian 显然相关(共享同一 parent feature),但 HAC 没用上。HAC++ 在 hash-grid prior 上叠加 sibling 间的自回归。
Mip-NeRF 360: 8.7 MB / 27.60 PSNRT&T: 5.4 MB / 24.22Deep Blending: 3.1 MB / 30.16 PSNR>100× over 3DGS, >20× over Scaffold-GS在 Deep Blending 上首次跌破 1 MB/scene 同时提升 PSNR——“高质量区间的压缩问题基本被解决”的最干净证明。
ContextGS— Compact 3DGS with Anchor-Level Context Model
关键想法 HAC 用 hash-grid feature 预测每个 anchor,ContextGS 用已解码的邻居预测——3D anchor 上的 PixelCNN。
把 anchor 分层 (coarse → medium → fine)。最粗一层先 hyperprior 编码;解码出来后作为 context 预测下一层的分布,arithmetic-code;如此递推。直接利用 anchor 间空间冗余——HAC 只通过 hash grid 间接利用。
Mip-NeRF 360 low: 13.3 MB / 27.62 PSNRDeep Blending: ~6 MB / 30.09“3DGS 像图像编码”最干净的写法——经典 autoregressive context 在 3D 稀疏结构上的复刻。
CodecGS— Feature Planes + HEVC
关键想法 把 3DGS 属性铺到 2D feature plane,跑一遍 HEVC——就是给你流 Netflix 的那个视频编码器。25 年工程红利免费拿,硬件解码器现成。
HEVC 有 intra prediction、变换编码、CABAC、码率控制——为什么要重造?把 feature plane 训练成 HEVC-friendly(频率域 entropy model 对齐 HEVC 实际行为)就行。
Mip-NeRF 360: 10.3 MB / 27.30 PSNRTanks & Temples: 7.8 MB / 23.63证明压缩可以彻底脱离定制学习编码器。手机里 2014 年后的 HEVC 硬解都现成。
FCGS— Fast Feedforward 3DGS Compression
关键想法 上面每篇都得给每个新场景重训 neural codec(每场景几分钟)。FCGS 不用:一个预训练网络一次前向压完任何场景——每 100K Gaussian 大约 1 秒。
Entropy 模块用 3 分量 Gaussian Mixture,条件于:(1) hyperprior h(全场景粗 latent),(2) inter-Gaussian context s(已解码 Gaussian 的 grid interpolation),(3) intra-Gaussian context c(同一 Gaussian 内通道分块)。多路径分支把不同属性路由到不同 rate 约束。
Mip-NeRF 360 low: 36.3 MB / 27.05>20× 压缩 / 秒级无需逐场景训练“压缩 = 推理”的拐点。比 HAC++ 大 ∼5×,但快 100×。和学到的图像编码器从逐图训练走向 amortized 的轨迹一模一样。
PCGS— Progressive Compression
关键想法 一条 bitstream,多档解码质量。客户端可以早停,得到一个 OK 的预览;继续读则细节越来越好。Progressive JPEG 的 3DGS 版。
Progressive masking(逐步加 anchor)+ Progressive quantization(步长逐步减小)。一次训练,多档码率。
3DGS 第一个真正的渐进式码流——流媒体和带宽自适应 AR/VR 的天然继承者。
LocoGS— Locality-aware Gaussian Compression
关键想法 沿 Morton (Z-order) 曲线排序 Gaussian——比特流里相邻的就是 3D 里相邻的。然后用 neural field + 自适应 SH 带宽利用产生的相干性。
54.6×–96.6× compression2.1–2.4× rendering speed-upMorton 排序是 1960 年代图形学技巧(用于纹理 cache),加上现代熵编码就是 100× 杠杆。
PART VIII工业格式 Formats
HAC++ 给你 3 MB 文件,然后呢?真正部署还需要:
- 跨平台二进制,不假设 CUDA;
- 解码器能在 WebGL/WebGPU/Metal/Vulkan 上毫秒级跑;
- 容器能嵌入现有 3D pipeline (glTF, USD);
- 理想情况是 标准,所有引擎都能读。
这些都不是学术论文交付的东西。2024–2026 工业格式逐渐定型。
SOG— Self-Organizing Gaussians
关键想法 把 N 个 Gaussian 排进 N×N 2D 网格,让网格邻居有相似属性。每个属性(position-x, scale-y, SH-coeff-k...)就变成一张平滑 2D 图像。然后用 PNG/JPEG-XL/WebP/AVIF 存——让图像编码器做熵编码。
排序算法叫 PLAS (Parallel Linear Assignment Sorting)——一个自定义 GPU 算法,几秒解决“把 N 个高维向量分配到 2D 网格,使邻居相似”的指派问题。
整个领域最具教学意义的想法:“把无结构问题变成结构化的,然后已有工具就能解。”
PLAS 排序:噪声属性 → 平滑属性图
19.9×–39.5× 压缩Mip-NeRF 360 ~40 MB / 27.64 PSNR无 SH 时可达 123×
PlayCanvas SOGS / SOG v2— Production WebP-based format
Production · PlayCanvas Engine 2.7.5 (2024) + .sog v2 (late 2025)
关键想法 SOG 的工业版。每个属性是 WebP texture,封装在一个 archive 里。浏览器原生解码,按 Morton 顺序直接上 GPU。
SOG v2 (2025 末) 加:Morton ordering 让 GPU 加载友好、WebGPU-only 编码 pipeline(写时不需要 CUDA)、单文件自包含 archive。
~95% 尺寸减少1 GB PLY → 42 MB .sogPlayCanvas Engine 部署中
SPZ / SPZ 4— Splat Zip (Niantic)
关键想法 每个属性 16-bit 定点量化 → gzip 整个 blob。完毕。
SOG 的故意-简单替代品:
- 16-bit fixed-point positions
- quantized quaternion / scale / opacity
- 保留完整 degree-3 SH(其他压缩格式经常不留)
- 整个 blob gzip
SPZ 4 (2026 May) 加:vendor extensions、∼3-5× 编码加速、∼1.5-2× 解码加速。
∼10× 比 .ply~90% 尺寸减少“无 ML、就工程做到位”的范例。Scaniverse 设备端捕获采用,glTF KHR_gaussian_splatting_compression_spz 的官方载荷。
.ksplat— Three.js viewer's home format
关键想法 一个“瘦身的 PLY”二进制:8-bit SH,struct layout 直接对齐 Three.js 内部 Gaussian 结构。加载即上 GPU,零转换。
多档压缩级别,最激进的会 8-bit 量化 SH。强调解码速度而非绝对体积。
“磁盘上小”和“GPU 上快”是两件事。KSPLAT 比 SOGS 大,但加载更快。
glTF KHR_gaussian_splatting— Khronos Industry Standard
关键想法 第一个跨厂商 3DGS in glTF 标准。SPZ 是官方载荷;设计与算法无关,未来 codec 可插拔。
两个 extension:
KHR_gaussian_splatting 定义无压缩结构:position、rotation、scale、opacity、SH 分成 diffuse (degree 0) + specular (degree 1-3)。
KHR_gaussian_splatting_compression_spz 把 SPZ-压缩 blob 包装成 glTF buffer。
Niantic、Cesium/Bentley、Esri、OGC、Khronos 联合背书。类似于 JPEG 被写进 web 标准的时刻。
MPEG-GSC— Gaussian Splatting Coding (ISO Future Standard)
Future ISO Standard · MPEG 153rd meeting Jan 2026
关键想法 制定 MPEG-2、HEVC 的同一标准体把 3DGS 当一类 first-class 媒体。目标:可互操作的 ISO 编码器,HEVC/VVC 作为起点。预计 2027-2028 产出参考标准。
glTF + SPZ 解决今天的 asset distribution;MPEG-GSC 将解决广播/流媒体的 codec 互操作。
PART IX前沿 Frontier
§9.1前沿 2025-2026 —— 30 个月时间线
- Aug 2023 3D Gaussian Splatting (Kerbl et al., SIGGRAPH 2023)
起点。场景 ~1.4 GB。
- Nov 2023 LightGaussian · Compact3D (Navaneet) · Compact-3DGS (Lee) · EAGLES · SOG
仅 4 个月后,基本压缩方向就已列齐。大小掉到 20-60 MB。
- Mar 2024 Scaffold-GS · HAC
anchor + entropy 组合成型。HAC 把无损情况下推到 ~15 MB。
- Oct 2024 FCGS — feed-forward compression
amortization 时刻。压缩 = 推理,不再 = 优化。
- Jan 2025 HAC++ · CodecGS · Splatpress · SG-Splatting
sub-10 MB 成为家常。Khronos、MPEG 开始开会。
- Mar 2025 PCGS (AAAI 2026 Oral) — progressive 3DGS
"progressive JPEG" for splats。一码流多质量。
- Aug–Sep 2025 EntropyGS · ExGS / Zip-GS · MEGS²
三条新支线:参数化熵编码、扩散辅助修复、面向移动端。
- Dec 2025 Smol-GS · Splatwizard · RAVE
Mip-NeRF 360 上 4.87 MB SOTA。统一基准工具包。可变码率单模型解码器。
- Feb 2026 NiFi — 1000× via diffusion · glTF KHR_gaussian_splatting released
压缩与标准化同时进入成熟期。
- May 2026 SPZ 4 · MPEG-GSC exploration ongoing
问题从“能多小”变成“怎么发出去”。
方向 1:前馈式 / amortized codec
直到 2024 末,每个 3DGS 压缩器都要每场景训练。FCGS 之后这条路解锁。未来主流编解码器会是单个预训练网络,一次前向压完任何场景。
- FCGS (ICLR 2025, arXiv 2410.08017) — 第一个前馈式 3DGS 压缩器。秒级 ∼20× 压缩。
- FCGS+ / Long-Context FCGS (arXiv 2512.00877, 2025) — Morton serialization 构建千-Gaussian 级别 context window。前馈式 SOTA。
- D-FCGS (arXiv 2507.05859, 2025) — 自由视点视频的前馈动态压缩。
为什么重要:每场景训练是 capture-to-share 工作流(手机端 capture、AR 内容创建)的瓶颈。秒级而不是 10 分钟,用户体验从根本上不同。
方向 2:扩散辅助修复
如果你能事后修复渲染坏掉的图,就可以更激进地压。decompression pipeline 变成:
scene′=compress(scene, very_aggressive)⟶render(scene′)⟶diffusion_repair(render)
ExGS / Zip-GS
arXiv 2509.24758 (Sep 2025)
关键想法 激进 training-free pruning (UGC) + mask-guided 单步扩散 (GaussPainter) 修复渲染。实时推理。100× 压缩,354 MB → 3.31 MB。
NiFi — Nix-and-Fix
arXiv 2602.04549 (Feb 2026)
关键想法 把压缩推到 1000×——大胆扔掉大部分细节,再用 artifact-aware 单步扩散解码器复活。这条线上“解码 = 生成”已经名副其实。
方向 3:4D 动态压缩
4DGS / 3DGStream 让动态场景成为可能后,自然问题:怎么压缩“splat 的视频”?标准视频编码器对像素的解法,splat 版正在 active research。
- 4DGC (arXiv 2503.18421) — rate-aware streamable 4DGS, ∼16× smaller than 3DGStream
- GIFStream (arXiv 2505.07539, CVPR 2025) — canonical-space + deformation-field, 30 Mbps real-time on RTX 4090
- 4DGCPro (arXiv 2509.17513) — hierarchical progressive 4D for volumetric video
- P-4DGS (arXiv 2510.10030) — predictive 4DGS, 90× compression
- MEGA (arXiv 2410.13613) — memory-efficient 4DGS
- CompGS++ (arXiv 2504.13022) — static + dynamic 双兼容
- D-FCGS (arXiv 2507.05859) — 前馈动态压缩
所有这些的概念套路:canonical-space + deformation。一次性存 t=0 的场景,每帧只存低带宽 deformation field(或 anchor motion)。和 MPEG 的 I-frame + P-frame 思路一模一样。
方向 4:移动端 / on-device
当前大部分 SOTA 假设 24 GB 数据中心 GPU。这条线是要让 3DGS 在手机(带电池)上跑好:
- 3DGauCIM (arXiv 2507.19133) — digital compute-in-memory 加速器
- StreamingGS (arXiv 2506.09070) — 移动端体素式 streaming
- MEGS² (arXiv 2509.07021) — SG-based memory-efficient + 统一剪枝
- FlexGaussian (ACM MM 2025) — INT8/INT4 混合精度,秒级部署
- Real-Time On-Device 3DGS with Reuse (arXiv 2511.12930)
注意:这条线的论文 headline 不是 PSNR,而是“瓦特/FPS、DRAM 字节、每帧渲染预算”——另一个优化制度。
这个领域正逐步规范化。3DGS.zip(Bagdasarian et al., 2025)是一个活的 leaderboard,钉死了跨论文的可比性。两个工具包正在汇聚成统一基准:
- Splatwizard (arXiv 2512.24742) — 统一评测框架,10+ rasterizer、熵估计、metrics 一站式。
- GSCodec Studio (arXiv 2506.01822) — 静态+动态模块化框架。
- RAVE (arXiv 2512.07052) — 单模型输出连续 RD 曲线,解码时选码率不用重训。
- 3DGS.zip 综述 — w-m.github.io/3dgs-compression-survey
附录
§A交互演示场
本文用到的所有交互 demo 集中在这里。前面的章节里都已嵌入;这里只是方便集中把玩。所有代码纯 Canvas2D,零依赖,gauss-engine.js ≈280 行——可以直接 fork。
本文用到的 demo(按出现顺序):
- 单个 Gaussian 的解剖 — §1.1,6 个 slider 拖动一个 anisotropic Gaussian。
- 不同 SH degree 的辐射花瓣 — §1.3,degree 3 → 0 视觉变化。
- 压缩配方组合 — §1.5,pruning + 比特数 + VQ + SH 同时调,看 size 与 PSNR 估计。
- 不同打分函数下的剪枝 — PART III,opacity / volume / Hessian-ish 等。
- SOG 排序前后对比 — PART VIII,从无结构到 2D 网格。
- 大小–PSNR Pareto 散点图 — §2.2,所有方法在 Mip-NeRF 360 上的位置。
§B阅读清单 & 资源
基础
综述 & 活跃 leaderboard
剪枝(PART III)
量化(PART IV)
球谐压缩(PART V)
锚点法(PART VI)
熵编码(PART VII)
工业格式(PART VIII)
前沿 2025-2026(PART IX)
动态 4D 压缩
移动端 / on-device
相邻工作
引用本综述
text
@misc{3dgs-compression-survey-2026,
title = {Compressing 3D Gaussian Splatting: A Friendly Bilingual Survey},
year = {2026},
month = {May},
note = {Educational survey covering pruning, quantization, SH compression,
anchor-based, entropy coding, industry formats, and 2025-2026
frontiers. Bilingual English/Chinese.}
}
更好的做法:引用原始论文 + 3DGS.zip live leaderboard。