Neural Radiance Fields (NeRF)
神经辐射场 (NeRF) 将 3D 场景存储在通过带位姿照片训练的神经网络中,并沿相机光线进行体渲染,以生成新的视角。
神经辐射场(NeRF)将3D 场景表示为一个神经网络,该网络将任意 3D 位置和观察方向映射为密度和颜色,并通过一组已知相机位置的普通照片进行学习。渲染视图时,系统会为每个像素发射一条光线,查询光线上各点的网络输出,再通过体渲染混合结果;因此,训练好的 NeRF 能从没有相机拍摄过的视角展示场景。Ben Mildenhall、Pratul Srinivasan、Matthew Tancik 及其在 UC Berkeley、Google Research 和 UC San Diego 的同事,在 ECCV 2020 上发表的论文《NeRF:用于视图合成的神经辐射场场景表示》中介绍了这项方法。NeRF 能够复现反射、细长结构和半透明材质,而这些效果难以用基于网格的摄影测量处理;NeRF 还开启了神经渲染研究热潮,并推动了高斯泼溅的发展。
神经辐射场的工作原理#
原始 NeRF 是一个不含卷积的多层感知机。它使用 8 个具有 256 个通道的全连接层处理编码后的 3D 位置,并输出体密度和一个包含 256 个值的特征向量。该特征向量与编码后的观察方向结合后,传入另一个具有 128 个通道的层,该层输出 RGB 颜色。密度只取决于位置,从而保持不同视角下的几何结构一致;颜色还取决于方向,因此可以捕捉随相机移动而变化的镜面高光和反射:
渲染一个像素时,NeRF 先用粗网络沿相机光线采样 64 个点,再在粗略渲染中密度较高的位置额外采样 128 个点,并在所有采样点上运行精细网络。每个采样点根据自身不透明度以及透射率(即穿过前方采样点后仍然存在的光线比例)贡献相应颜色;这些加权结果之和就是像素颜色。训练过程通过批次优化渲染像素颜色与照片像素颜色之间的平方差,每批处理 4,096 条光线。相机位姿通常由COLMAP等运动恢复结构软件计算;在NVIDIA V100 GPU上训练一个场景需要 100,000 到 300,000 次迭代,大约一到两天。
直接输入原始坐标的普通 MLP 学到的是平滑函数,会模糊精细细节,因此 NeRF 会先将每个坐标映射为频率逐次翻倍的正弦和余弦值;位置使用 10 个频率,方向使用 4 个频率。下面的 PyTorch代码分别使用和不使用这种位置编码,将同一网络拟合到带条纹的 1D 信号:
import torch
from torch import nn
torch.manual_seed(0)
# Color along one line through a scene, with fine detail such as a striped texture
x = torch.linspace(-1, 1, 512).unsqueeze(1)
target = torch.sin(12 * torch.pi * x) * torch.cos(3 * torch.pi * x)
# NeRF's positional encoding: sines and cosines of the coordinate at 10 doubling frequencies
freqs = 2.0 ** torch.arange(10) * torch.pi
encoded = torch.cat([torch.sin(x * freqs), torch.cos(x * freqs)], dim=1)
for name, inputs in (("raw coordinate", x), ("positional encoding", encoded)):
mlp = nn.Sequential(nn.Linear(inputs.shape[1], 256), nn.ReLU(), nn.Linear(256, 256), nn.ReLU(), nn.Linear(256, 1))
optimizer = torch.optim.Adam(mlp.parameters(), lr=1e-3)
for step in range(1000):
loss = ((mlp(inputs) - target) ** 2).mean()
optimizer.zero_grad()
loss.backward()
optimizer.step()
print(f"{name}: mean squared error {loss.item():.4f}")代码会输出 raw coordinate: mean squared error 0.0870 和 positional encoding: mean squared error 0.0000。信号的平均功率为 0.25,因此使用原始坐标的网络会漏掉约三分之一的信号,也就是那些精细条纹;使用编码后的网络则能复现这些条纹。
更快、更稳健的 NeRF#
- 抗锯齿与无界场景:Mip-NeRF 渲染的是圆锥而非无限细的光线,以消除锯齿;Mip-NeRF 360 则将这一方法扩展到无界的 360° 拍摄场景。
- 速度:NVIDIA 的 Instant NGP用多分辨率学习特征哈希表取代了网络中的大部分结构,将训练时间从几天缩短到几秒或几分钟,并能在 1920×1080 分辨率下以数十毫秒完成渲染。
- 在真实环境中拍摄的照片:NeRF in the Wild 为每张照片添加外观嵌入和独立的瞬态分量,因此即使网络照片集中的光照不断变化、游客来来往往,也能重建出干净的场景。
- 文本生成 3D:DreamFusion 会不断优化 NeRF,直到其从各个角度渲染的结果都能让 2D 文本生成图像扩散模型觉得合理;无需 3D 训练数据,就能根据提示创建 3D 物体。
NeRF 与相关概念的比较#
- 高斯泼溅:将场景明确存储为数百万个 3D 高斯,并对其进行光栅化;渲染速度可以达到实时,而且不必逐像素评估网络。2023 年,它的质量已达到 Mip-NeRF 360 的水平,并取代了许多采集工具中的 NeRF,但代价是需要更多内存。
- 摄影测量:通过匹配照片中的特征来构建显式网格。网格体积小,可在标准 3D 软件中编辑,但处理光亮、透明和极薄表面时效果不佳。
- 深度估计:NeRF 会附带生成深度图,表示每条光线停止处的期望距离,但前提是先使用同一场景中许多带位姿的照片进行优化。单目深度模型则能通过一次前向传播从单张图像预测深度。
- 隐式神经表示:NeRF 是一种专门用于表示辐射和密度的隐式神经表示;其他网络则能将图像、形状或音频存储为连续函数。
采集要求#
NeRF 假设场景静止、光照恒定,并从许多重叠视角拍摄,同时准确获知相机位姿。原论文为每个合成物体使用 100 个渲染视图进行训练,并为每个真实的前向视角场景使用 20 到 62 张照片。采集期间移动的物体(例如路人或汽车)会出现在部分照片中,却不出现在其他照片中;优化过程会用半透明的“漂浮物”来解释这种情况。Ultralytics YOLO26实例分割模型可以在每张照片中遮罩人物和车辆,这样就能在训练时排除穿过这些像素的光线。
实际应用#
- 电影与虚拟制片:将拍摄地点重建出来,再从新的相机路径进行渲染,用作逼真的背景和布景参考。
- 机器人与驾驶仿真:重建录制的环境,让自动驾驶车辆和机器人团队能够从原始行驶过程中未经过的位置渲染传感器视图。
- 产品可视化:只需拍摄几十张商品照片,就能创建交互式视图,让顾客自由旋转商品。
- 地图:为在 Google 地图中推出沉浸式视图,Google 根据用单反相机在每个地点约一小时内拍摄的照片,使用 NeRF 重建餐厅和咖啡馆的内部场景。这项技术基于 Mip-NeRF 360,并结合 NeRF in the Wild 的外观嵌入和 Block-NeRF 的曝光条件控制,最终沿精心规划的飞行路径将场景制作成交互式 360° 视频。










