【科研思考】辐射场中的显式表达和隐式表达
光场(Light Field)和辐射场(Radiance Field)
光场被定义为 “空间中光线集合的完备表示” 。采集并且显示光场,就能在视觉上重现真实世界。
- 全光函数(Plenoptic Function)包含7个维度,是表示光场的数学模型。
与之类似的概念还有“辐射场”。光场是以人眼为中心对光线集合进行描述,而辐射场则以发光表面为中心来描述光线集合。两者是等效的描述。
人眼位于三维世界中不同的位置进行观察所看到的图像不同,用 $(x, y, z)$ 表示人眼在三维空间中的位置坐标。光线可以从不同的角度进入人眼,用 $(\theta, \phi)$ 表示进入人眼光线的水平夹角和垂直夹角。每条光线具有不同的颜色和亮度,可以用光线的波长 $λ$ 来统一表示。进入人眼的光线随着时间 $t$ 的推移会发生变化。这七个参数可以描述三维世界中的光线,被称之为“全光函数”(Plenoptic Function):
$$P(x, y, z, \theta, \phi, λ, t)$$
如果以物体的表面为中心来描述光线集合,我们就得到了辐射场。
比起光场来说,辐射场更适合用于描述“场景”。从某个角度来说,“场”的客观存在并不一定需要用人眼去观测。
在 NeRF(Neural Radiance Field)使用神经网络去拟合辐射场之后,就掀起了一阵使用辐射场来描述场景的热潮,其大体分为显式表达和隐式表达两种类型。
Overview:Explicit Representation And Implicit Representation
接下来,我们讨论的主要是“辐射场”中的显式表示和隐式表示。在这里我们做一些简化的假设:
- 去除时间轴。我们只讨论静态场景。动态场景暂时可以理解为沿时间方向的静态场景的叠加。
- 我们将光线的波长 $\lambda$ 分解为 $(R, G, B, \sigma)$ 四个参数,可以简单的表示某个点的颜色和密度。
在这些假设下,我们来分析显式表达和隐式表达的区别。
隐式表达
所谓隐式表达,就是不直接写出场景的表达式,而是通过某个函数去描述我们所需要的值。RF 系列作品中,最为纯粹的隐式表达就是 NeRF(Neural Radiance Field)。作为神经渲染的开山之作,NeRF 完全使用 MLP 对辐射场进行拟合。
值得注意的是,NeRF 的 Encoding 操作(包括 Positional Encoding,使用傅立叶编码和 SH Encoding,使用球谐编码)完全不需要参数(不是“超参数”),其本质只是把点的位置和方向信息从低频空间转化到高频空间,从而解决 MLP 不擅长学习高频细节的问题。(有研究表明,在使用梯度下降的时候,MLP 优先拟合场景中平滑的信息,随后才会“过拟合”到高频细节)。
隐式表达最大的问题是:慢。NeRF 使用了 8 层 256 宽度的 MLP,渲染一张图片需要数以秒记的时间。但其参数量也非常小,原因可能是 MLP 这种形式的拟合器是对数据的一种良好的压缩。
显式表达
显式表达直接存储空间中点的特征。从某种程度上来说,在辐射场里,显式表达约等于“基于点的表达”(Point-Based Representation)。例如:我们可以将空间划分为“网格”(Grid),或者直接存储“体素”(Voxel)。
在 RF 系列作品中,较为出名的、使用了显式表达的方法有:
- Point NeRF。存储空间中的显式点特征,但仍然使用 Ray Marching 去进行采样。采样之后,根据不同点云到采样点的距离进行获取特征并插值。
- Plenoxels:用八叉树显示表示空间信息,并且对八叉树直接进行优化。
- 3D Gaussian Splatting:最为纯粹的显式表达,用各向异性的高斯点云拟合场景,使用 光栅化管线 进行投影操作,从而达到足够快的渲染速度。
- Binary Opacity Grids 采样 Grid 编码场景,并 Baking 成 Mesh。
显式表达的速度普遍快于隐式表达,但与之相应的代价是内存消耗的快速增长。而众所周知的是,内存在如今仍然是一个相当昂贵的资源。因此,纯粹采用显式表达未必是最优选择。
显示表达和隐式表达的结合
事实上,大部分神经渲染工作并没有完全抛弃 MLP。例如 Instant NGP 虽然采用 Hash Table 编码场景,但仍然使用了小型 MLP 作为解码器。小型的 MLP 运算速度并不慢,又能良好的压缩数据,因此仍然是可以被考虑的选择。
显式表达和隐式表达的分析
以 Synthetic 场景为例:
- NeRF:5MB,<=1 FPS
- Instant NGP:28MB,30+FPS
- Gaussian:100MB,100+FPS
- Plenoxels:1G+,慢的不谈了
……
可以看出,显式表示确实需要巨大的内存开销。因此,如何平衡:
- 显式表达的高质量和快速渲染
- 隐式表达的内存开销
就成为一个重要的课题。