原理公式
前四册(逆向:图像→结构)与第 1–4 节 CG(正向:结构→图像)结合,产生可微分渲染: 把渲染过程写成可求导的计算图,于是可以用梯度下降学出「能渲染出目标图像的场景参数」。
NeRF(Neural Radiance Fields)是代表:用神经网络 F_θ(x, y, z, 视角) → (颜色 c, 体密度 σ) 表示场景,沿光线积分得到像素颜色:
$$C(\mathbf{r}) = \int_{t_n}^{t_f} T(t)\,\sigma(\mathbf{r}(t))\,\mathbf{c}(\mathbf{r}(t))\,dt, \qquad
T(t) = \exp\!\left(-\int_{t_n}^{t}\sigma(\mathbf{r}(s))\,ds\right)$$
σ:该点的不透明度/密度(体积);T(t):光线到达 t 前的透过率。- 训练:对比渲染像素与真实照片的误差(
L2loss),反向传播更新F_θ。
推导要点:NeRF 把「3D 场景」编码进网络权重——查询任意新视角都能渲染, 是「从绘制到学习绘制」的质变。3D Gaussian Splatting 用显式高斯集合替代网络,更快。
重难点核心代码(NeRF 体渲染的数值近似——离散采样累加)
Python
def volume_render(rgb, sigma, z_vals):
"""沿光线离散采样积分的数值实现(NeRF 核心循环)。"""
delta = np.diff(z_vals, append=z_vals[-1] + 1e-3) # 采样间隔
alpha = 1 - np.exp(-sigma * delta) # 每段不透明度
T = np.exp(-np.cumsum(sigma * delta)) # 累积透过率
T = np.concatenate([[1.0], T[:-1]]) # 前段透过率
weights = T * alpha # 每段贡献权重
return (weights[:, None] * rgb).sum(0) # 加权和 = 像素颜色
完整可运行 demo 需 PyTorch + 多视图照片集,超出本文范围;上示核心循环 可直接用
numpy跑通,理解「透过率 × 不透明度 × 颜色」的体渲染本质。