共计 2173 个字符,预计需要花费 6 分钟才能阅读完成。
3D 高斯散射(3DGS)作为神经渲染的新兴技术,能够高效建模复杂光场并实现实时渲染质量。与传统体素和点云方法相比,3DGS 通过可微分的高斯基元实现更自然的视角合成。其参数化表示与物理光照模型的兼容性,使其成为动态场景重建的热门选择。

数学原理拆解
- 3D 高斯参数化表示
每个高斯基元定义为:
$$G(\mathbf{x}) = \exp\left(-\frac{1}{2}(\mathbf{x}-\mu)^T\Sigma^{-1}(\mathbf{x}-\mu)\right)$$ - $\mu\in\mathbb{R}^3$ 为中心位置
-
$\Sigma$ 为 3×3 协方差矩阵(需正定),实践中分解为旋转矩阵 $R$ 和缩放矩阵 $S$:$\Sigma=RS(RS)^T$
-
可微分渲染的雅可比计算
像素颜色 $C$ 对高斯参数 $\theta$ 的偏导:
$$\frac{\partial C}{\partial\theta} = \sum_{i=1}^N\frac{\partial w_i}{\partial\theta}c_i + w_i\frac{\partial c_i}{\partial\theta}$$ - $w_i$ 为第 $i$ 个高斯在像素点的贡献权重
-
需链式求导计算 $\partial w_i/\partial\mu, \partial w_i/\partial\Sigma$ 等
-
概率密度梯度传播
通过重参数化技巧避免采样不可微:
$$\nabla_\theta\mathbb{E}{\mathbf{x}\sim G}[f(\mathbf{x})] = \mathbb{E}[\nabla_\theta f(\mu + R\cdot S\cdot\epsilon)]$$}(0,I)
PyTorch 实战实现
import torch
import torch.nn as nn
class DifferentiableGaussianRender(nn.Module):
def __init__(self, num_gaussians):
super().__init__()
# 初始化可学习参数
self.means = nn.Parameter(torch.randn(num_gaussians, 3)) # [N,3]
self.scales = nn.Parameter(torch.ones(num_gaussians, 3)) # 对角 S 矩阵
self.rotations = nn.Parameter(torch.randn(num_gaussians, 3, 3)) # R 矩阵
self.colors = nn.Parameter(torch.sigmoid(torch.randn(num_gaussians, 3)))
def _build_covariance(self):
# 保证正定性:通过 QR 分解得到正交矩阵
R = torch.linalg.qr(self.rotations)[0] # [N,3,3]
S = torch.diag_embed(torch.exp(self.scales)) # 指数保证正数
return R @ S @ S.transpose(-1,-2) @ R.transpose(-1,-2)
def forward(self, pixels):
cov = self._build_covariance() # [N,3,3]
diff = pixels[:,None] - self.means # [P,N,3]
# 计算马氏距离(批处理优化)inv_cov = torch.linalg.inv(cov) # [N,3,3]
exponent = -0.5 * (diff @ inv_cov * diff).sum(-1) # [P,N]
# 计算权重并归一化
weights = torch.exp(exponent) # [P,N]
weights = weights / (weights.sum(-1, keepdim=True) + 1e-8)
# 加权混合颜色
return (weights[...,None] * self.colors).sum(-2) # [P,3]
关键实现说明:
– 第 8 行:使用指数变换保证缩放因子为正
– 第 12 行:QR 分解强制得到正交旋转矩阵
– 第 20 行:马氏距离计算时利用广播机制避免循环
避坑指南
- 协方差矩阵稳定性
- 每次前向计算前执行 QR 分解(代码第 12 行)
-
对缩放参数施加 L2 正则:
loss += 0.01 * self.scales.pow(2).sum() -
梯度爆炸预防
- 限制高斯中心初始范围:
means.uniform_(-1,1) -
使用梯度裁剪:
torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0) -
内存优化
- 分块处理像素:每次前向只计算 256×256 像素区域
- 混合精度训练:
with torch.autocast(device_type='cuda', dtype=torch.float16):
延伸思考
- 如何设计自适应高斯基元数量策略?当前固定数量是否限制表达能力?
- 在动态场景中,能否用 RNN 或 GNN 建模高斯参数的时间演化?
- 现有实现是否可以利用球谐函数(Spherical Harmonics)提升光照真实性?
通过本文的代码框架,读者可快速搭建基础 3DGS 渲染器。实际部署时建议结合 CUDA 定制核函数加速,并尝试将高斯参数预测与 NeRF 等架构结合。期待看到更多关于动态分辨率与物理约束结合的创新方案。
