code和原文:https://github.com/ashawkey/nerf2mesh
1. Nerf2Mesh结构总览
Nerf2Mesh可以理解为是一种在Nerf结构基础上的下游任务。它的输出是两样东西:
- mesh网格
- 纹理图
在上图中,最左侧的立方体就是Nerf所构建的三维数据,它包含离散点的三维坐标、不透明度(density)以及rgb色彩。
Nerf2Mesh的整体结构也像图中分为上下两个分支:
- Density field
- Appearance Field
2. Apearance Field分支
2.1 分支结构
左下角的Appearance Field Volumn是Nerf输出的XYZ,rgb数据,它是和纹理渲染相关的一些信息。
最开始的Nerf是在三维重建的角度来设计整个网络结构,网络的输入是RGB+方向向量,它并没有考虑到光照和物体的材质。所以原始的Nerf在光反射的场景表现不好。或者说,Nerf在网络设计的时候,并没有显式地去学习光照、材质、漫反射、镜面反射这些内容(或许内部会像一个black box一样学习到一些光照信息),所以会导致渲染的时候光照的表现不好。
Nerf输出的内容经过MLP1提取特征,然后分成两个分支分别提取漫反射和镜面反射的分量:
- 镜面反射分支需要引入方向向量,再经过一层MLP2最终得到镜面反射的分量
- MLP1的输出就是漫反射分量
这也不难理解:漫反射产生的纹理和相机位置无关,但是镜面反射产生的纹理与相机位置强相关。
2.2 Loss
第一个Loss和Nerf中的loss是相同的,表示渲染出来的rgb图像与GT之间的L2 损失
第二个Loss 是针对镜面反射纹理(specular)的,我的理解是避免镜面反射纹理太大。因为镜面反射大部分都是很暗的,接近于0。
第三个Loss中的alpha表示不透明度density,它的作用是让纹理的边缘更加sharper。
3. Density Field分支(Mesh重建)
左上角的Density field Volumn是Nerf输出的XYZ,Density数据,它代表三维空间的结构信息。
在这个分支中,Nerf输出的三维数据会经过Marching Cubes方法(一种使用点云进行三维重建的方法,类似SDF)生成一个粗糙的Mesh;
然后经过coarse to fine的优化方法(下面详细解释),得到一个refine的mesh。
3.1 Coarse Mesh
Nerf的输出是RGB,XYZ,Density信息。其中和mesh结构相关的是XYZ,Density。Marching Cubes或者SDF这些三维重建方法可以利用三维点云数据重建出mesh结构,但是mesh会比较粗糙。
3.2 Coarse To Fine
优化的整体思路是在输出端接入一个可微的渲染层。这样就可以使用梯度下降进行网络中参数的优化。图中圈起来的部分就是可微的渲染过程。它使用finetune的mesh与diffuse+specular的纹理图进行渲染。
3.2.1 Mesh顶点的优化
直接使用Marching Cubes或者SDF这些三维重建的方法生成的mesh很挫,这里用的方法是在每个vertex顶点上学习一个offset:
这里的大概意思就是:训练的时候在Marching Cubes重建的mesh的每个顶点上加上一个可学习的偏移量(这个可学习的方式具体是nn.embedding还是通过FC层学习的要看下代码)。在经过differentiable rendering之后与GT 之间计算Loss。然后通过梯度下降的方法来调整这些偏移量。
3.2.2 Mesh Face的优化
Mesh Face不可微:
这里使用了重投影的方法,计算mesh中每个三角面片上的累计误差:公式(6)表示的是在2D图像上某个坐标位置上,网络输出的渲染结果与GT之间的误差。把这个2D坐标反向投影到mesh上,落在哪个面片上,就在这个面片上进行误差的累计。遍历2D图像上所有点之后,就完成了mesh面片上的误差累积。误差越高的,说明当前的这个位置mesh重建的越挫。优化的策略如下:
- 误差太大说明mesh网格不够精细,需要增加面片密度
- 误差很小说明mesh网格已经很精细了,可以适当减少面片(合并)
3.3 Loss
- 第一个loss是统计某个顶点与附近周围顶点坐标之间的距离,起到平滑的作用,目的是让三角面片的形状看上去不要那么奇怪,
- 第二个loss目的是限制网络学习到的offset偏移量不要过大,可以理解为这只是个微调作用。
4. 总结
Nerf2Mesh在Nerf的基础上做了如下工作:
- 引入漫反射+镜面反射,强调了光照和材质这些在渲染中必要的属性(网络结构做了调整)。
- 接入了可微的渲染层(这个其实Nerf也有)
- 可以输出比较好的mesh:它在Nerf结构的基础上接入了三维重建,并在此基础上用网络对三维重建mesh的vertex顶点坐标进行优化(由于渲染层可微,使得整个过程可以通过梯度下降的方式进行优化)。对于不可微的三角面片,使用重投影的方式将2d平面上的渲染误差映射到mesh的面片上,统计每个面片上的累计误差,最后对面片做分解、合并的调整。