深入理解神经辐射场 (NeRF):从体渲染到可微 3D 重建
1. 引言:神经渲染的范式革命
1.1 什么是 NeRF?
神经辐射场(Neural Radiance Fields,NeRF) 是 Mildenhall 等人在 2020 年 ECCV 上提出的革命性方法,论文标题为 “Representing Scenes as Neural Radiance Fields for View Synthesis”。
它的核心思想令人惊艳:
用一个简单的多层感知机(MLP)作为”场景记忆器”,输入空间坐标和观察方向,输出颜色与密度;通过对相机光线进行体渲染积分,即可从任意新视角合成出照片级真实感的图像。
这种”神经网络即场景”的表示方法,绕过了传统几何重建(点云、网格)的中间步骤,直接从图像端到端学习场景的连续表征。
1.2 为什么 NeRF 重要?
| 维度 | 传统方法 | NeRF |
|---|---|---|
| 表示 | 离散(点云 / 体素 / Mesh) | 连续(MLP 隐式表示) |
| 渲染质量 | 受网格分辨率限制 | 照片级真实感 |
| 几何表达 | 需要显式重建 | 隐式学习 |
| 新视角合成 | 依赖纹理映射 | 任意视角生成 |
| 存储效率 | 高分辨率 Mesh 庞大 | 单个 MLP 仅 ~5MB |
NeRF 开启了神经隐式表示这一研究范式,并催生了 Instant-NGP、Plenoxels、Mip-NeRF 360、3D Gaussian Splatting 等一系列后续工作。
1.3 NeRF 的应用场景
- 电影 / 特效:自由视角视频(Free-Viewpoint Video)
- VR / AR:沉浸式三维内容生成
- 文化遗产:文物、遗址的高保真数字化
- 自动驾驶:场景重建与仿真
- 机器人:环境建模、避障
- 医学影像:CT / MRI 三维重建
- 数字人:人脸 / 人体 NeRF 重建
2. 核心思想:5D 神经辐射场
2.1 场景的数学建模
NeRF 把一个静态场景建模为一个 5D 向量值函数:
其中:
- :空间位置(3D 坐标)
- :观察方向(单位向量)
- :该位置沿方向 观察到的颜色
- :体积密度(Volume Density),表示该位置的”不透明度”
关键洞察:颜色是视角相关的(镜面反射),但密度是视角无关的(几何属性)。NeRF 显式地分离这两者。
2.2 为什么需要视角依赖?
考虑一个金属球:
- 正面看:能看到球面的高光(接近白色)
- 侧面看:看到的是漫反射(接近灰色)
- 但球的位置和密度始终不变
如果颜色只依赖于位置,就只能表达漫反射;引入方向后,可以表达视角相关效果(镜面反射、各向异性等),这是高质量渲染的关键。
2.3 MLP 结构
用一个简单的 MLP 实现,约 8 层全连接,宽度 256:
输入: x = (x, y, z) → γ(x) (位置编码, 详见第 4 节) ↓ 8 层 MLP ↓ 临时特征: z(x) (输出 256 维) ↓ ┌───────┴────────┐ ↓ ↓σ ← Linear(z) c ← concat(z, γ(d)) → 额外 MLP → Linear → RGB (1 维) (128 维中间层)注意:密度 只从位置特征 预测;颜色 则结合位置特征 和方向编码 共同预测。
设计巧思:这种结构强制 MLP 先用位置信息判断”这是不是一个表面”,再用方向信息判断”沿这个方向看是什么颜色”——这符合物理直觉。
3. 体渲染:从辐射场到 2D 图像
3.1 物理模型:光线的辐射积分
在真实世界中,从相机出发的每条光线都会与场景中的物质发生吸收、发射、散射。最终到达相机的颜色,是沿光线对所有辐射贡献的加权积分。
NeRF 假设场景中没有散射(即只吸收和发射),那么颜色可由下式给出:
其中:
- :光线的参数化方程
- :累积透射率(光线从 走到 而未被吸收的比例)
- :体密度函数
- :辐射颜色
- :近端 / 远端距离
累积透射率定义为:
直观理解: 表示”光线到达 之前有多大概率没被任何东西挡住”。
3.2 离散化:数值积分
连续积分无法直接用神经网络计算,需要离散化为分层采样:
其中:
- :采样点数量
- :相邻采样点的距离
- :该采样点的不透明度
- :累积透射率
3.3 体积渲染流程图
相机射线 r = o + td ↓ ┌────┴────┐ ↓ ↓ 采样 采样 ↓ ↓ σ₁,c₁ σ₂,c₂ ... σₙ,cₙ ↓ ↓ ↓ ──→ α₁ α₂ αₙ (αᵢ = 1 - exp(-σᵢδᵢ)) ↓ ↓ ↓ T₁·α₁·c₁ + T₂·α₂·c₂ + ... + Tₙ·αₙ·cₙ ↓ 像素颜色 C(r)3.4 代码实现
import torch
def volume_render(sigmas, colors, deltas): """ sigmas: (N_samples,) 体密度 colors: (N_samples, 3) 颜色 deltas: (N_samples,) 相邻采样点距离 """ # 计算每段的不透明度 alpha alphas = 1.0 - torch.exp(-sigmas * deltas)
# 累积透射率 T Ts = torch.cumprod(1.0 - alphas + 1e-10, dim=0) # 注意:T[0] = 1(从近端开始),T[i] 对应 i 之前未被吸收的比例 Ts = torch.cat([torch.ones_like(Ts[:1]), Ts[:-1]], dim=0)
# 加权求和 weights = Ts * alphas # (N,) pixel_color = (weights.unsqueeze(-1) * colors).sum(dim=0)
return pixel_color, weights4. 位置编码(Positional Encoding)
4.1 为什么需要位置编码?
深度学习的一个普遍现象:MLP 倾向于学习低频函数。对于类似 这种 3D 坐标,MLP 难以表达锐利的边缘和精细细节。
位置编码(Positional Encoding, PE)的灵感来自 Transformer:将低维输入通过高频函数映射到高维空间,让 MLP 能拟合高频变化。
4.2 编码公式
对于标量坐标 (如 ),其位置编码为:
其中 是编码阶数(NeRF 原始论文中 用于位置, 用于方向)。
为什么是 2 的幂次?这是为了让编码覆盖从粗到细的频率范围。
4.3 代码实现
def positional_encoding(x, L): """ x: (..., D) D 维输入 L: 编码阶数 return: (..., D * 2 * L) """ freqs = (2.0 ** torch.arange(L, device=x.device)) * torch.pi # x: (..., D) → (..., D, 1) # freqs: (L,) → (..., 1, L) xb = x.unsqueeze(-1) * freqs return torch.cat([torch.sin(xb), torch.cos(xb)], dim=-1).flatten(-2)4.4 频率选择的影响
| 阶数 | 编码维度 | 表达范围 |
|---|---|---|
| 6 | 仅最粗粒度 | |
| 30 | 中等细节 | |
| 60 | NeRF 默认,丰富细节 | |
| 90 | 极高细节(但易过拟合) |
如果 太小:图像会非常平滑、模糊 如果 太大:会出现高频噪声、过拟合
5. 训练流程
5.1 训练数据准备
NeRF 的训练数据要求比较严格:
- 多视角图像:同一场景的多张图像(通常 50~200 张),且视角需有足够变化
- 相机标定:每张图像对应的相机内外参(内参 、外参 )
- 相机位姿估计:通常用 COLMAP 通过 SfM(Structure from Motion)自动恢复
没有精确的相机位姿,NeRF 无法训练。这是它最大的”门槛”之一。
5.2 训练过程
输入:图像集 与相机位姿
目标:优化 MLP 参数
for iteration in range(num_iters): 1. 随机采样一批相机视角 2. 对每个像素,生成相机射线 r = o + td 3. 在光线上分层采样 N 个点 4. 用 MLP 预测 (σ, c) 在每个点 5. 体渲染得到预测像素颜色 Ĉ 6. 计算损失 L = Σ ||Ĉ - C_gt||² 7. 反向传播更新 θ5.3 损失函数
原始 NeRF 使用简单的 MSE 损失:
其中 是一个 batch 中随机采样的光线集合。
后续工作(如 Mip-NeRF 360)加入了 LPIPS、SSIM 等感知损失,进一步提升质量。
5.4 分层采样(Hierarchical Sampling)
NeRF 的一个关键技巧:粗采样 + 细采样 两阶段:
第一阶段(粗采样): 在光线上均匀采样 N_c 个点(如 64) 用这些点的权重分布得到粗略的密度分布
第二阶段(细采样): 根据粗采样的权重分布,用逆变换采样 N_f 个点(如 128) 这些点集中在"重要"区域(接近表面的位置)
最终渲染:合并所有点(粗 + 细)一起做体渲染这种策略让采样点集中在真实表面附近,大幅减少冗余计算,并提升渲染质量。
5.5 训练时间与资源
| 配置 | 训练时间 | 显存 |
|---|---|---|
| 单 RTX 3090 | ~24 小时 | ~10 GB |
| 单 RTX 4090 | ~12 小时 | ~10 GB |
| Google TPU v2 | ~10 小时 | TPU 内存 |
| Instant-NGP (哈希加速) | ~5 分钟 | ~4 GB |
原始 NeRF 极其缓慢——这是它最大的实用瓶颈,催生了大量加速研究。
6. 完整代码示例:PyTorch 简化版
6.1 模型定义
import torchimport torch.nn as nn
class NeRF(nn.Module): def __init__(self, pos_L=10, dir_L=4, hidden=256): super().__init__() self.pos_L, self.dir_L = pos_L, dir_L
# 位置编码维度: 3 * 2 * pos_L # 方向编码维度: 3 * 2 * dir_L self.in_dim_pos = 3 + 3 * 2 * pos_L self.in_dim_dir = 3 + 3 * 2 * dir_L
# 主干 MLP (8 层) self.backbone = nn.Sequential( nn.Linear(self.in_dim_pos, hidden), nn.ReLU(), *[nn.Sequential(nn.Linear(hidden, hidden), nn.ReLU()) for _ in range(7)] ) # 密度分支 self.sigma_head = nn.Linear(hidden, 1) # 中间特征(用于颜色) self.feat_head = nn.Linear(hidden, hidden) # 颜色分支(带方向) self.color_head = nn.Sequential( nn.Linear(hidden + self.in_dim_dir, hidden // 2), nn.ReLU(), nn.Linear(hidden // 2, 3), nn.Sigmoid(), )
def forward(self, x, d): gamma_x = positional_encoding(x, self.pos_L) gamma_d = positional_encoding(d, self.dir_L)
h = self.backbone(gamma_x) sigma = self.sigma_head(h).squeeze(-1) # (...,) feat = self.feat_head(h)
color = self.color_head(torch.cat([feat, gamma_d], dim=-1)) return color, sigma6.2 训练循环
import torch.optim as optim
model = NeRF().cuda()optimizer = optim.Adam(model.parameters(), lr=5e-4)scheduler = optim.lr_scheduler.ExponentialLR(optimizer, gamma=0.1 ** (1 / 250000))
for it in range(num_iters): # 1. 采样一批光线 rays_o, rays_d, gt_colors = sample_rays(dataset)
# 2. 分层采样 t_vals = stratified_sampling(rays_o, rays_d, near, far, N_c=64) t_vals, _ = importance_sampling(t_vals, weights, N_f=128)
# 3. 查询 MLP pts = rays_o[..., None, :] + rays_d[..., None, :] * t_vals[..., :, None] dirs = rays_d[..., None, :].expand_as(pts) colors, sigmas = model(pts.reshape(-1, 3), dirs.reshape(-1, 3)) colors = colors.reshape(*pts.shape[:-1], 3) sigmas = sigmas.reshape(*pts.shape[:-1])
# 4. 体渲染 pred_colors, weights = volume_render(sigmas, colors, deltas)
# 5. 损失与优化 loss = F.mse_loss(pred_colors, gt_colors) optimizer.zero_grad() loss.backward() optimizer.step() scheduler.step()7. NeRF 的关键改进与变体
7.1 改进时间线
| 年份 | 方法 | 核心贡献 |
|---|---|---|
| 2020 | NeRF | 奠基性工作,提出 5D 神经辐射场 |
| 2021 | Mip-NeRF | 抗锯齿,处理多尺度 |
| 2022 | Instant-NGP | 哈希编码,5 分钟训练 |
| 2022 | Plenoxels | 不用 MLP,纯体素网格 |
| 2022 | Mip-NeRF 360 | 处理无界场景 |
| 2022 | NeuS | 表面重建,高质量几何 |
| 2023 | 3D Gaussian Splatting | 实时渲染,显式表示 |
| 2023 | Zip-NeRF | 工业级质量 |
| 2024 | 4D-GS / Dynamic 3DGS | 动态场景 |
7.2 Instant-NGP:哈希加速
关键问题:原始 NeRF 的 MLP 查询极其耗时(每条光线数百次前向传播)。
Instant-NGP 的方案:用多分辨率哈希编码替代位置编码。
- 维护多个分辨率的 3D 网格(哈希表)
- 每个网格点存一个可学习特征向量
- 查询时:根据坐标做三线性插值,拼接多分辨率特征
- 再输入一个小型 MLP(仅 2 层)
效果:
- 训练时间:从 ~12 小时 → 5 分钟
- 渲染:实时(30 FPS)
- 显存:仅 ~4 GB
Instant-NGP 是 NeRF 实用化的关键里程碑,使其在工业界真正可用。
7.3 Mip-NeRF:抗锯齿
问题:训练分辨率与渲染分辨率不同时,NeRF 会出现严重锯齿和模糊。
方案:用**综合多尺度位置编码(IPE, Integrated Positional Encoding)**替代固定阶数的 PE。
- 考虑每条光线在每个采样段上覆盖的体积(不是点)
- 用高斯近似的圆锥台体积做积分
- 天然抗锯齿,支持连续缩放
7.4 Mip-NeRF 360:无界场景
问题:原始 NeRF 假设相机在场景中心,无法处理 360° 环绕或室外大场景。
方案:
- 使用参数化的无界收缩空间(contracted space)
- 将远处背景用 MLP 单独处理
- 提出 interlevel loss 和 distortion loss,正则化几何
7.5 NeuS:从 NeRF 到表面重建
动机:NeRF 渲染质量好,但几何是隐式的,难以提取 mesh。
NeuS 的核心:将**符号距离函数(SDF)**与体渲染结合。
- 用 MLP 预测 SDF 而不是体密度
- 通过 SDF 的 Sigmoid 推导 ,保证几何一致性
- 可以直接用 Marching Cubes 提取高质量 mesh
8. NeRF vs 3DGS:核心差异
8.1 本质对比
| 维度 | NeRF | 3DGS |
|---|---|---|
| 表示 | 隐式(MLP) | 显式(3D 高斯集合) |
| 渲染 | 沿光线采样 | 光栅化 + alpha 合成 |
| 训练速度 | 慢(10~24h) | 快(30~60min) |
| 渲染速度 | 慢(<5 FPS) | 极快(100+ FPS) |
| 存储 | MLP 仅 ~5MB | 场景文件通常 100~500MB |
| 编辑 | 困难 | 天然支持 |
| 几何提取 | 困难(需 NeuS) | 直接(密度场) |
| 动态场景 | 需特殊设计 | 4D-GS 自然扩展 |
8.2 适用场景
| 场景 | 推荐 |
|---|---|
| 研究 / 论文基线 | NeRF(更经典) |
| 工业实时渲染 | 3DGS |
| 几何提取(Mesh) | NeuS / 3DGS |
| 神经语义编辑 | NeRF + Instruct-NeRF2NeRF |
| 物理仿真 | 3DGS(显式几何) |
| 极少训练视角 | NeRF + 正则化 |
| 大规模场景 | 两者都需要分块 |
9. 进阶话题
9.1 动态 NeRF / 4D 建模
- D-NeRF:把时间作为第 6 维输入
- Nerfies:形变场 + 规范化空间
- HyperNeRF:高维拓扑变化(如人脸表情)
9.2 NeRF 编辑
- EditNeRF:局部编辑
- Instruct-NeRF2NeRF:用 2D 扩散模型引导 3D 编辑
- NeRF-Art:风格化
9.3 NeRF + Diffusion
- DreamFusion / Magic3D:用 2D 扩散模型作为先验,从文本生成 3D
- Zero-1-to-3:单张图像生成新视角
9.4 工业部署
- GPU 渲染:原始 NeRF、Instant-NGP、3DGS
- 移动端:移动 GPU 推理(量化、蒸馏)
- Web:WebGL / WebGPU 实时查看
10. 关键数学公式汇总
为方便查阅,下面列出本文涉及的核心公式:
- 5D 神经辐射场:
- 体渲染积分(连续形式):
- 累积透射率:
- 离散化体渲染:
- 位置编码:
- MSE 损失:
11. 总结与展望
NeRF 的核心贡献
- 连续表征:用 MLP 表示 5D 连续辐射场,摆脱离散几何的分辨率限制
- 体渲染框架:可微的体积积分让端到端训练成为可能
- 照片级真实感:在静态场景上达到前所未有的渲染质量
- 研究范式:开启了神经隐式 3D 表示的整个研究领域
当前挑战
- 训练缓慢:原始 NeRF 需要数小时到一天
- 渲染效率:每像素需数百次 MLP 查询
- 相机位姿依赖:需要 COLMAP 等工具预标定
- 几何提取困难:隐式表示不便于下游几何任务
- 泛化性:每个场景需独立训练,跨场景泛化能力弱
未来方向
| 方向 | 关键工作 |
|---|---|
| 加速训练 | Instant-NGP、Plenoxels、Hash Grid |
| 抗锯齿 | Mip-NeRF、Mip-NeRF 360 |
| 实时渲染 | 3DGS(重要替代方案) |
| 表面重建 | NeuS、VolSDF |
| 动态 4D | D-NeRF、Nerfies、HyperNeRF |
| 文本生成 | DreamFusion、Magic3D |
| 编辑 | Instruct-NeRF2NeRF |
| 工业部署 | 模型压缩、移动端、Web 渲染 |
| 多模态 | CLIP-NeRF、LangSplat |
| 大规模 | Block-NeRF、城市级重建 |
NeRF 是过去十年计算机视觉最具影响力的工作之一。它的核心思想——“用神经网络隐式表示场景”——已经渗透到 3D 视觉的方方面面。即便 3D Gaussian Splatting 在很多场景取代了它,NeRF 仍然在需要连续隐式表示的科学计算、神经语义编辑、可微仿真等领域持续发光发热。
参考资料
- Mildenhall, B., et al. (2020). “Representing Scenes as Neural Radiance Fields for View Synthesis.” ECCV.
- Barron, J. T., et al. (2021). “Mip-NeRF: A Multiscale Representation for Anti-Aliasing Neural Radiance Fields.” ICCV.
- Barron, J. T., et al. (2022). “Mip-NeRF 360: Unbounded Anti-Aliased Neural Radiance Fields.” CVPR.
- Müller, T., et al. (2022). “Instant Neural Graphics Primitives with a Multiresolution Hash Encoding.” ACM TOG (SIGGRAPH).
- Yu, A., et al. (2021). “Plenoxels: Radiance Fields without Neural Networks.” CVPR.
- Wang, P., et al. (2021). “NeuS: Learning Neural Implicit Surfaces by Volume Rendering.” NeurIPS.
- Park, J. J., et al. (2021). “Nerfies: Deformable Neural Radiance Fields.” ICCV.
- Pumarola, A., et al. (2021). “D-NeRF: Neural Radiance Fields for Dynamic Scenes.” CVPR.
- Poole, B., et al. (2022). “DreamFusion: Text-to-3D using 2D Diffusion.” arXiv / ICLR 2023.
- Haque, A., et al. (2023). “Instruct-NeRF2NeRF: Editing 3D Scenes with Instructions.” ICCV.
- Kerbl, B., et al. (2023). “3D Gaussian Splatting for Real-Time Radiance Field Rendering.” ACM TOG (SIGGRAPH).
- Martin-Brualla, R., Radwan, N., et al. (2021). “NeRF in the Wild: Neural Radiance Fields for Unconstrained Photo Collections.” CVPR.
- Tancik, M., et al. (2022). “Block-NeRF: Scalable Large Scene Neural View Synthesis.” CVPR.
- “Nerfstudio: A Modular Framework for Neural Radiance Field Development.” GitHub: nerfstudio-project/nerfstudio.
- Kajiya, J. T., & Von Herzen, B. P. (1984). “Ray Tracing Volume Densities.” ACM SIGGRAPH — NeRF 体渲染积分的原始论文。
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!

