오늘 리뷰할 논문은 MobileNeRF입니다. 기존의 NeRF는 ray별로 volumetric rendering을 하기 때문에 연산 부하가 있고 GPU를 필요로 합니다. MobileNeRF에서는 기존의 NeRF 구조를 최대한 효율적으로 바꾸어서 GPU가 없는 기기에서도 interactive하게 3D novel view synthesis를 할 수 있도록 합니다. 이 과정에서 z-buffer, GLSL fragment shader 같이 컴퓨터 비전 관련 소프트웨어를 사용하여 범용성이 높아진다고 합니다.
https://mobile-nerf.github.io/
https://arxiv.org/abs/2208.00277
Abstract
3D novel view synthesis를 수행하는 NeRF는 ray를 쏘아서 pixel 별로 volumetric rendering algorithm을 사용하여 값을 구합니다. 이런 구조는 핸드폰이나 GPU를 사용하지 않는 컴퓨터 하드웨어에는 사용하기 힘든 구조입니다. MobileNeRF는 다른 그래픽하드웨어에서 GPU를 사용하지 않고도 호환이 될 정도로 가볍고 효율적인 파이프라인을 제안합니다. MobileNeRF는 binary opacity와 feature vector를 가지고 있는 texture vector를 가지고 있는 texture polygon을 사용하여 novel view synthesis를 진행합니다. Z-buffer를 사용하여 polygon을 rendering한 뒤, 굉장히 작은 view-dependent MLP로 pixel 별 feature 값을 color 값으로 매핑합니다. MLP의 크기가 굉작히 작아서 fragment shader를 사용하여 구현이 가능하고 다양한 기기에서 즉각적으로 렌더링이 가능할 정도로 배치의 크기를 키울 수 있다고 합니다.
Introduction
앞에서 말했던 것처럼 NeRF는 기본적으로 방향과 카메라 위치를 기준으로 픽셀 별로 ray를 쏘아서 ray 상에 있는 여러 지점에 대해 radiance와 density를 계산하고 적분하는 volumetric rendering을 수행합니다. 이 과정에서 연산의 부하가 커지고 rendering을 즉각적으로 하기엔 너무 느리기도 하고 다양한 하드웨어에서 범용적으로 사용하기도 어렵습니다.
최근데는 Plenoxel이나 SNeRG 같은 3D voxel grid를 사용해서 density가 높은 sparse한 voxel 안에 feature를 저장하는 접근 방식들이 제안되고 있습니다. 이런 방식은 NeRF의 연산 속도와 부하는 상당히 줄이고 있습니다. SNeRG 같은 경우에는 일단 ray 상에 있는 voxel 안에 diffuse color와 feature vector를 계산하여 저장해둡니다. 그 후 해당 feature들을 가벼운 MLP에 태워서 색을 예측하는 방식입니다. 이 방법은 test time 속도를 굉장히 올려주지만 volumetric texture를 GPU에 저장해야하기 때문에 모바일 기기에서 사용이 어렵다고 합니다.
MobileNeRF는 volumetric texture(feature)가 아니라 textured polygon을 사용하여 scene의 표면에만 polygon의 형태로 필요한 feature들을 저장하는 방식을 제안합니다. 이렇게 되면 density가 높은 모든 voxel을 모두 계산하는 기존의 3D grid 방식보다 저장할 정보가 더 적어지기도 하고, z-buffer를 사용하는 전통적인 polygon rasterization pipeline을 사용할 수 있게 된다고 합니다. 또한 가벼운 MLP는 GSLS fragment shader(OpenGL)로 구현하였다고 합니다.
MobileNeRF의 Contribution은 아래와 같습니다.
- SNeRG와 같은 성능으로 10배 더 빠른 속도
- Volumetric texture가 아닌 surface texture만을 저장하여 Computing power가 부족한 상황에도 사용가능
- Web browser과도 호환이 되며 대부분의 하드웨어에 사용 가능
- 간단한 triangle mesh 구조이기 때문에 실시간으로 scene 조작이 가능
Related Work
NeRF의 다양한 연구에 대해서 소개를하고 있습니다.
Method
MobileNeRF는 효율적인 novel view rendering을 하기 위해서 위 그림(a), (b) 처럼 polygon mesh와 이에 대한 texture map(feature, opacity)을 저장해둡니다. 해당 정보를 가지고 렌더링을 할 때는 camera pose를 받아서 2단계로 이루어진 deferred rendering process를 거친다고 합니다.
Rendering Stage-1
구해둔 mesh와 texture image를 사용하여 feature image(위 그림의 c)를 구합니다.
Rendering Stage-2
위에서 구한 feature image의 feature 정보를 fragment shader로 돌아가는 light MLP에 태워서 color 값을 계산아여 위 그림의 (d) 같은 결과를 만들어냅니다.
Mesh representation은 크게 세 단계의 Training stage를 통해 저장됩니다.
3.1. Continuous training (Training Stage 1)
기존의 NeRF와 비슷하게 continuous opacity 값을 가지고 NeRF를 학습합니다. 정확하게는 위 그림처럼 하나의 mesh와 세 개의 MLP를 학습합니다. 위에서 보이는 initial grid mesh에서 vertex는 학습이 되면서 점점 위치가 바뀌게 되고 위 그림의 오른쪽 처럼 grid도 뒤 틀린 모양이 되게 됩니다.
학습은 픽셀 값에 대한 MSE loss를 사용합니다.
그리고 픽셀 값인 C(r)은 위와 같이 alpha compositing을 하여 구합니다. 여기서 volumetrix density가 아니라 opacity 값으로 alpha compositing을 한다고 합니다.
세 개의 MLP는 다음과 같이 계산이 됩니다. 각각 opacity, feature, color를 계산합니다. 그리고 여기서 network H가 deferred neural shader라고 부르는 작은 MLP에 해당합니다.
Polygon Mesh
Polygon mesh는 여러 상황의 scene에서 위와 같이 초기화한다고 합니다. (a) 같은 상황에서 크기가 PxPxP인 grid g를 초기화 합니다. 그리고 grid 안의 voxel를 초기화 하고 인접한 네 개의 voxel를 연결하는 quadrangle 형태로 연결하는 topology를 사용했다고 합니다. 각 voxel의 정중앙에 움직일 수 있는 vertex이 존재하며 이는 학습 과정에서 voxel 안의 영영에서 이동이 가능합니다.
Vertex가 voxel 밖으로 나가면 I(v)가 1이 리턴되도록 하여 밖으로 나가 못하도록 하였다고 합니다.
Quadrature
특정한 ray 상에서 적분할 때 사용한 voxel을 찾이 위해서 위와 같은 방법을 사용합니다. Ray와 만나는 모든 vertex가 잠정적으로 대상이 되고(a) 그 중에서 물체가 없을 것 같은 voxel들은 모두 지워줍니다(b). 사용하지 않을 voxel을 지울 때 Instant NGP와 같이 acceleration grid G를 사용하였다고 합니다. 마지막으로 quadrangle 형태로 연결 되어있던 vertex들을 가지고 계산을 하게 됩니다. 식은 아래 처럼 나타납니다.
Back-propagation을 하기 위해서 barycentric interpolation을 하였다고 합니다. 그리고 acceleration grid를 학습하기 위해서 다른 부분에 대해서는 gradient를 끊은 상태로 grid에 loss를 흘려주었다고 합니다.
또한 아래 loss 텀도 사용되었다고 합니다.
3.2. Binarized training (Training Stage 2)
대부분의 하드웨어들은 반투명한 mesh에 대한 계산을 지원하지 않습니다. 또한 반투명한 meshsms alpha-compositing을 할 때 정렬을 해야하는 등의 추가적인 과정을 필요로 합니다. 이 부분을 개선하기 위해 continuous한 opacity를 0/1로 변환하였습니다.
1차적으로 위처럼 discretization을 진행하고 모델을 안정화하기 위해서 아래 14번 식으로 두 모델을 동시에 학습하는 과정을 거칩니다.
그리고 수렴이 끝난 뒤에 13번 식만 가지고 fine-tuning을 하게 됩니다.
3.3. Discretization (Training Stage 3)
그 후에 representation 들을 OBJ 파일로 저장을하며 training camera pose상에서 보이는 quadrangle에 대해서만 남기고 나머지는 지운 상태로 저장했습니다. 각 quad는 KxK texture 패치를 가지고 있으며 여기서는 K=17로 한 뒤 16x1의 texture를 사용하고 나머지 1픽셀은 padding으로 사용하였습니다. Texture map은 PNG 이미지 형태의 파일들로 저장합니다.
3.4. Anti-aliasing
Super-sampling을 통한 anti-aliasing을 하였습니다. Resolution을 두배로 들려서 feature를 계산한 뒤에 sub-pixel feature를 평균내서 deferred shader에 넣어줍니다. 처음에는 deferred shader에 feature를 네 번 계산한 뒤에 평균을 내는 방법을 사용했지만 computational bottleneck이 생기기 때문에 feature를 평균 낸 뒤에 deferred shader를 사용한 연산을 한 번만 했다고 합니다.
3.5. Rendering
앞에 나온 내용의 요약 정도라 생략하겠습니다.
4. Experiments
여러 하드웨어 상에서 성능을 비교한 표입니다.
아래 표를 보면 굉장히 효율적으로 동작하는 동시에 성능도 다른 모델들과 비슷한 것을 확인할 수 있습니다.
데이터셋 당 vertex와 triangle의 갯수는 다음과 같습니다.
Ablation 입니다.
배경에 해당한 mesh를 인위적으로 제거하고 객체의 mesh가 어떤 식으로 보여지는지 보여주는 figure입니다.
하지만 반사되는 부분, 반투명한 부분 등의 상황에서 아직은 보완이 필요합니다.
Mesh를 사용해서 다양한 활용이 가능합니다.