3D Gaussian Splatting
概述
3D Gaussian Splatting(3DGS)是一种用于实时辐射场渲染的突破性技术,由Kerbl等人于2023年提出。与NeRF使用神经网络隐式表示场景不同,3DGS使用数百万个3D高斯函数作为显式场景表示,通过可微的splatting渲染实现实时高质量渲染。
3DGS的核心优势:
- 实时渲染:可达90+ FPS的渲染速度
- 显式表示:场景由可解释的3D高斯组成
- 高效训练:几小时训练时间(相比NeRF显著缩短)
- 可编辑性:高斯函数便于场景编辑和操作
核心原理
3D高斯函数
3D高斯函数定义为:
其中:
- :高斯中心(均值)
- :协方差矩阵
为保证高斯函数表示的有效性,协方差矩阵需满足:
其中 是旋转矩阵, 是缩放矩阵。这种分解使得:
- 缩放由三维向量 参数化
- 旋转由四元数 参数化
各向异性高斯
3DGS支持各向异性(anisotropic)高斯,即高斯在三个主轴方向上可以有不同的缩放。这使得:
- 薄板状高斯:表示平面表面
- 细长高斯:表示边缘和线条
- 球形高斯:表示点云中的点
协方差矩阵参数化
为保证协方差矩阵的正定性和数值稳定性,使用以下参数化:
# PyTorch实现示例
def build_covariance_from_scaling_rotation(scaling, rotation):
"""
scaling: (N, 3) - 每个高斯的缩放因子
rotation: (N, 4) - 每个高斯的四元数 (w, x, y, z)
"""
# 从四元数构建旋转矩阵
R = quaternion_to_rotation_matrix(rotation) # (N, 3, 3)
# 构建缩放矩阵
S = torch.diag_embed(scaling) # (N, 3, 3)
# 协方差矩阵: Σ = R @ S @ S^T @ R^T
M = R @ S # (N, 3, 3)
covariance = M @ M.transpose(-2, -1) # (N, 3, 3)
return covariance可微Splatting渲染
从3D到2D投影
3D高斯通过透视投影映射到2D图像平面。对于高斯中心 和协方差 ,投影后的2D高斯参数为:
其中 是从相机中心到高斯中心的变换向量, 是焦距。
2D协方差矩阵:
其中 是仿射近似的雅可比矩阵, 是视图变换矩阵。
体积splatting
对于每个像素,3DGS计算所有投影高斯在该像素处的贡献:
其中:
- :高斯 的颜色
- :高斯 的不透明度
- :高斯 在像素 处的2D高斯值
基于深度的排序
为保证正确的体积渲染顺序,需要对高斯按深度排序。3DGS使用:
- 初始排序:按深度排序
- Tile-based排序:将图像分成tiles,对每个tile独立排序
- α-blending:从前到后(或从后到前)累积颜色
训练过程
SfM初始化
3DGS通常使用Structure-from-Motion (SfM)算法(如COLMAP)获取稀疏点云作为初始高斯位置:
- 点云生成:从多视角图像提取稀疏3D点
- 高斯初始化:每个点创建一个高斯
- 属性初始化:
- 颜色:从图像颜色平均
- 缩放:基于点云密度估计
- 不透明度:初始化为0.5
自适应控制
训练过程中,3DGS通过以下机制自适应调整高斯数量和分布:
密集化(Densification)
克隆:对小高斯进行克隆,增加局部密度
- 检测梯度大的小高斯
- 创建副本并沿梯度方向移动
分裂:对大高斯进行分裂,提高分辨率
- 检测过大的高斯
- 分裂为多个小高斯
# 密集化伪代码
for gaussian in high_grad_gaussians:
if gaussian.size < size_threshold:
# 克隆
new_gaussian = clone(gaussian)
new_gaussian.center += gradient * learning_rate
else:
# 分裂
new_gaussians = split(gaussian)修剪(Pruning)
- 移除不透明度过低的高斯(< 阈值)
- 移除过大或过小的高斯
- 移除被遮挡的高斯
优化器配置
3DGS使用以下优化配置:
- 优化器:Adam(学习率调度)
- 颜色参数化:球谐函数(SH)表示视角相关颜色
- 不透明度控制:使用sigmoid激活限制在[0,1]
- 克隆/分裂间隔:每100-300次迭代
球谐函数颜色表示
理论基础
球谐函数(Spherical Harmonics, SH)用于表示视角相关的颜色。每个高斯的颜色不是单一的RGB值,而是由球谐系数定义:
其中:
- :观察方向(单位向量)
- :球谐函数基
- :球谐系数
阶数选择
| 阶数 | 系数数量 | 表达能力 |
|---|---|---|
| 0 | 1 | 常数(视角无关) |
| 1 | 4 | 线性渐变 |
| 2 | 9 | 二次渐变 |
| 3 | 16 | 高频变化 |
通常使用 或 的球谐函数,平衡表达能力和参数数量。
与NeRF对比
性能对比
| 特性 | NeRF | 3DGS |
|---|---|---|
| 渲染速度 | ~10-30 FPS | ~90+ FPS |
| 训练时间 | ~12-48小时 | ~1-2小时 |
| 内存占用 | 中等 | 较高 |
| 显式/隐式 | 隐式(MLP) | 显式(高斯) |
| 可编辑性 | 困难 | 容易 |
| 表面质量 | 光滑 | 可能存在斑点 |
优缺点分析
3DGS优势:
- 实时渲染能力
- 显式场景表示,便于编辑
- 训练速度快
- 支持动态场景
3DGS局限:
- 初始点云质量依赖SfM
- 处理无纹理区域困难
- 内存占用较大
- 对远距离场景支持有限
应用场景
实时渲染
3DGS的实时渲染能力使其适合:
- 虚拟现实/增强现实(VR/AR)
- 实时视角合成
- 游戏引擎集成
场景编辑
显式高斯表示支持:
- 场景补全
- 对象移除/替换
- 物体插入
- 风格化编辑
动态场景
扩展3DGS处理动态场景:
- 4D Gaussian Splatting
- 动态人体重建
- 面部表情捕捉
代码实现框架
核心组件
class GaussianModel:
def __init__(self):
self.positions = None # (N, 3) 位置
self.scales = None # (N, 3) 缩放
self.rotations = None # (N, 4) 四元数
self.opacities = None # (N, 1) 不透明度
self.features = None # (N, F) 特征/颜色SH系数
def densify(self, grad_threshold):
"""密集化:克隆或分裂高斯"""
pass
def prune(self, opacity_threshold):
"""修剪:移除不透明度过低的高斯"""
pass
def get_covariance(self):
"""从缩放和旋转计算协方差矩阵"""
pass
def render(self, camera):
"""渲染指定视角的图像"""
pass渲染管线
def render_image(cameras, gaussians):
"""完整的渲染流程"""
# 1. 投影3D高斯到2D
screenspace_points = project_to_screen(gaussians.positions, cameras)
# 2. 计算2D高斯参数
covs_2d = compute_2d_covariance(gaussians.covariance, cameras)
# 3. 按深度排序
sorted_indices = sort_by_depth(screenspace_points)
# 4. 光栅化
image = rasterize(
screenspace_points[sorted_indices],
gaussians.features[sorted_indices],
gaussians.opacities[sorted_indices],
covs_2d[sorted_indices]
)
return image工具与库
主要实现
| 库 | 语言 | 特点 |
|---|---|---|
| Original 3DGS | CUDA/C++ | 官方实现,高效 |
| PyTorch3D | Python | 易于扩展 |
| Nerfstudio | Python | 集成3DGS,丰富工具 |
| Kaolin | Python | 3D深度学习库 |
工具
| 工具 | 用途 |
|---|---|
| COLMAP | SfM点云生成 |
| gsplat | 高效splatting库 |
| diff-gaussian-rasterization | 可微渲染 |