NeRF 神经辐射场:用 MLP 隐式表示场景
NeRF 神经辐射场:用 MLP 隐式表示场景
NeRF(Neural Radiance Fields)是一种基于深度学习的三维场景表示方法,它使用一个多层感知机(MLP)来隐式地存储场景的几何与外观信息。与传统显式表示(如体素、网格、点云)不同,NeRF 将场景建模为一个连续的 5D 函数,输入为空间坐标和观察方向,输出为颜色和体积密度。这一简洁而强大的思想,使得从稀疏二维图像中重建出任意新视角的高质量图像成为可能。
什么场景适合使用 NeRF?
- 从多视角图像重建逼真的 3D 场景(物体、室内、室外大场景)
- 新视角合成(Novel View Synthesis),例如电影特效、AR/VR
- 三维内容生成与编辑,结合生成模型(如 DreamFusion)
- 动态场景重建(时间依赖的 NeRF 变体)
核心思想:隐式神经表示
传统 3D 表示用网格顶点坐标或体素中心值来存储信息,所需存储量随分辨率立方增长。而 NeRF 采用一种“隐式”策略:用一个神经网络(MLP)直接拟合场景本身的连续函数。这个函数可以写为:
$$F(\mathbf{x}, \mathbf{d}) \rightarrow (\mathbf{c}, \sigma)$$
- $\mathbf{x} = (x,y,z)$:三维空间中的点坐标
- $\mathbf{d} = (\theta, \phi)$:观察方向(通常用单位方向向量表示)
- $\mathbf{c} = (r,g,b)$:该点在给定方向上的发射颜色
- $\sigma$:该点处的体积密度(可理解为光线在此处终止的概率密度)
网络本身就像一个“黑盒”,对于任意位置和视角,都能查出该点的颜色和密度。通过这种方式,整个场景被压缩到 MLP 的权重中,实现了任意分辨率的连续查询。
NeRF 工作流程概览
- 数据准备:收集多视角图像及对应的相机位姿(通常由 COLMAP 等 SFM 工具估算)。
- 训练:对每一张训练图像,从相机中心向像素方向发射光线,沿光线采样多个空间点,查询 MLP 得到颜色和密度,通过体渲染公式合成像素颜色,与真实像素颜色计算损失并反向传播更新 MLP。
- 推理/新视角渲染:给定新的相机位姿,同样发射光线,用训练好的 MLP 查询并体渲染生成图像。
体渲染底层原理
NeRF 的可微分渲染基于经典的体渲染方程。对于一条从相机中心出发、方向为 $\mathbf{d}$ 的光线 $\mathbf{r}(t)=\mathbf{o}+t\mathbf{d}$,其在近远平面之间($t_n$ 到 $t_f$)的预期颜色为:
$$\hat{C}(\mathbf{r}) = \int_{t_n}^{t_f} T(t) \cdot \sigma(\mathbf{r}(t)) \cdot \mathbf{c}(\mathbf{r}(t), \mathbf{d}) , dt$$
其中,透射率 $T(t) = \exp\left(-\int_{t_n}^{t} \sigma(\mathbf{r}(s)) ds\right)$ 代表光线到达 $t$ 处未被遮挡的概率。
实际计算时,NeRF 使用分层采样和数值积分将该积分离散化:
$$\hat{C}(\mathbf{r}) = \sum_{i=1}^{N} T_i \left(1 - \exp(-\sigma_i \delta_i)\right) \mathbf{c}i, \quad T_i = \exp\left(-\sum{j=1}^{i-1} \sigma_j \delta_j\right)$$
其中 $\delta_i = t_{i+1} - t_i$ 是相邻采样点间的距离。这种计算完全可微分,所以可以直接用梯度下降优化 MLP。
网络结构与位置编码
标准 NeRF 使用了一个并不深的 MLP:8 个全连接层(每层 256 维,带 ReLU 激活)处理位置 $\mathbf{x}$,输出一个中间特征和密度 $\sigma$;随后该特征与方向 $\mathbf{d}$ 拼接,再经过一个较小的 MLP 分支(128 维)输出颜色 $\mathbf{c}$。
关键技巧是位置编码(Positional Encoding),因为神经网络倾向于学习低频函数,难以表示高频细节。NeRF 将输入的低维坐标映射到高频空间:
$$\gamma(p) = (\sin(2^0 \pi p), \cos(2^0 \pi p), ; \sin(2^1 \pi p), \cos(2^1 \pi p), ; \ldots, ; \sin(2^{L-1} \pi p), \cos(2^{L-1} \pi p))$$
典型设置:对 $\mathbf{x}$ 使用 $L=10$(共 60 维),对 $\mathbf{d}$ 使用 $L=4$(共 24 维)。这极大提升了合成图像的清晰度。
采样策略:粗 + 细网络
标准 NeRF 同时训练两个 MLP:粗网络(coarse)和细网络(fine)。二者结构相同,但采样策略不同:
- 粗采样:在光线的近远平面之间均匀采样 $N_c$ 个点;
- 细采样:根据粗网络预测的权重分布($\hat{w}_i = T_i(1-\exp(-\sigma_i\delta_i))$),在重要区域(如物体表面附近)额外采样 $N_f$ 个点,并在这两组点集上一起计算细网络的输出。
这种“分层体积采样”使训练更高效,能聚焦于场景中的重要几何区域。
训练损失
NeRF 的优化目标很简单:渲染出的像素颜色与真实像素颜色的均方误差(MSE)。对于每条光线 $\mathbf{r}$,损失函数为:
$$\mathcal{L} = \sum_{\mathbf{r}} \left| \hat{C}_c(\mathbf{r}) - C(\mathbf{r}) \right|^2 + \left| \hat{C}_f(\mathbf{r}) - C(\mathbf{r}) \right|^2$$
$\hat{C}_c$ 是粗网络渲染颜色,$\hat{C}_f$ 是细网络渲染颜色。两者同时监督,提升最终精细度。
实现注意事项
- 相机射线生成:需要根据相机内参和位姿将像素坐标转换为世界空间的光线。通常使用 OpenGL/COLMAP 坐标系约定。
- 批量策略:每轮迭代随机挑选少量图像和光线(例如 4096 条),以平衡内存与效率。
- 背景处理:标准 NeRF 假设场景无背景,远处设为黑色。后续变体(NeRF++、mip-NeRF 360)通过引入背景模型或更智能的参数化来处理无界场景。
- 训练时间:原始 NeRF 在单张 GPU 上需训练数小时至一天,现代加速版本(Instant-NGP)使用哈希编码和多分辨率网格显著提速。
主要局限与后续发展
- 速度:原始 NeRF 训练和渲染慢。Instant-NGP 引入多分辨率哈希编码,将训练压缩到分钟级;MobileNeRF 烘焙为纹理网格实现实时渲染。
- 动态场景:标准 NeRF 要求场景静态。D-NeRF、HyperNeRF 等扩展将时间作为额外输入处理动态。
- 无界场景:室内外大场景需要特殊参数化,如 Mip-NeRF 360 采用收缩空间和提案网络。
- 数据效率:少视图 NeRF(如 PixelNeRF、MVSNeRF)利用预训练特征提升仅几张图的重建质量。
- 可编辑性:纯隐式表示难以编辑。NeRF-Editing、SPIn-NeRF 等方法允许用户控制形状和材质。
NeRF 实践入门建议
如果你是初学者,可以按以下路线动手:
- 运行官方代码:尝试原版 NeRF PyTorch 实现(
nerf-pytorch),用合成 lego 数据集验证效果。 - 可视化工具:使用
viser或nerfstudio查看训练过程中的光线和密度分布。 - 进阶框架:推荐学习 Nerfstudio(模块化、易用的 NeRF 训练与可视化平台)或 Instant-NGP 的 PyTorch 移植版 tiny-cuda-nn。
- 论文精读:
- NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis (Mildenhall et al., ECCV 2020)
- Instant Neural Graphics Primitives (Müller et al., SIGGRAPH 2022)
- Mip-NeRF 360 (Barron et al., CVPR 2022)
总结
NeRF 开创性地证明了简单 MLP 结合体积渲染可以重建出照片般真实的三维场景。它的魅力在于表示简洁、可微分、端到端优化,同时为计算机视觉和图形学开辟了大量后续研究方向。尽管训练和渲染效率仍是瓶颈,但蓬勃的改进方案正逐步将 NeRF 推向实用化。理解 NeRF 的核心思想,将为你打开神经渲染这个充满活力的研究领域大门。