3D Gaussian Splatting for Real-Time Radiance Field Rendering

3DGS 논문 리뷰
김호진's avatar
Aug 05, 2024
3D Gaussian Splatting for Real-Time Radiance Field Rendering
읽은 이유
3D model 생성
 
요약
3D gaussian들을 3d 공간에 위치시켜서 그걸 최적화한다. GPU를 최대한 활용하는 rasterization 방법들을 되게 잘 써서 렌더링 속도가 빠르다. NERF와 전혀 다르고 neural net을 사용하지도 않고 3d, graphics 개념이 많다보니 읽기가 쉽지는 않았다. 새로운 개념이라 그렇지, 차근차근 읽으면 개념 자체가 어렵고 복잡한건 아니라는걸 알 수 있다. 이전 연구들을 전혀 모르다보니 어떤 사고 과정에서 3D gaussian을 사용하겠다는 결정을 할 수 있었는지 모르겠다.
 
3d 기본 개념이 없어 이해가 어려울까봐 우선 영상 설명을 하나 시청
Nerf, point cloud, 3DGS : point cloud 같이 discrete한데 최소단위가 3d gaussian 한개. 적은 개수의 최소단위를 사용한다.
  • 연산량이 적어 빠르다
  • explicit하게 설계 spherical harmony
 
  • overview
    • SfM points를 입력으로 시작 - point cloud가 Gaussian의 초기 mean값
      explicit하게 4가지를 정해서 최적화 - Gaussian position, Opacity, Covariance, Spherical Harmonics Coefficient
      Tile-based rasterization - CUDA 기반으로 병렬적으로 가능함
      렌더링한 이미지와 원본 이미지를 비교하여 loss
      가우시안 개수와 큰 구조도 변한다.
      notion image
가우시안의 알파 : 단일 실수 값
Spherical Harmonics : 구면 좌표계로 색을 표현하는 함수
l은 정수, m은 -l ~ l
notion image
출력값은 컬러이고, 정답 컬러와 비교해서 최적화되는 파라미터 k
notion image
 
Rasterizer도 매우 중요하다. 3d GS들을 어떻게 2d 이미지로 만들거지?
notion image
가우시안의 opacity 비율에 따라 gradient가 전달
전체 가우시간 개수를 관리(제거, 복사, 분리)하는 iteration 과정 : adaptive Control of gaussians
  • 제거 : opacity가 임계값(0.0002) 이하면
  • 분리 : scale이 임계값보다 크면 2개로 나눈다
  • 복사
  • 3000 iteration마다 모든 가우시안의 알파값을 0으로 초기화한다. 가우시안이 계속 늘어나는걸 방지하기 위해.(floater)
 
ablation 중요한데? 꼭 보자
 
Abstract
Radiance Field 방법이 최근에 여러 장의 사진 혹은 비디오로부터 새로운 시점의 장면을 생성하는 과제에서 큰 향상을 만들어냈다. 하지만, 높은 퀄리티로 만드려면 뉴럴넷 학습과 렌더링이 리소스가 많이 든다(오래 걸린다). 단일 물체 이외에 완벽한 scene을 1080p로, realtime에 가깝게 만드는건 현재 불가능하다. 우리는 1080p resolution novel view 학습과 렌더링이 빠르면서도 Sota 퀄리티를 달성하도록 해주는 3가지 중요한 요소를 소개한다.
1) sparse points에서 시작해서, 3d 가우시안으로 씬을 표현한다. - 빈 공간에서의 불필요한 연산도 없다.
2) 3d 가우시안의 최적화와 density control(가우시안 갯수를 조정한다는 뜻)을 동시에 수행한다.
3) anisotropic splatting(3d 데이터 포인트를 2d로 나타낼 때 포인트를 점이 아니라 타원형 또는 여러 모양으로 표현하는 방법 - 특히 방향에 따라 특성이 달라질 때 좋다(타원형이니까 각도에 따라 넓이가 달라짐))을 사용해서 학습과 렌더링을 빠르게 했다.
 
Introduction
mesh와 points가 3d를 표현하는 가장 흔한 방법이다 - explicit하고, GPU/CUDA로 빠르게 rasterization(2d로 표현)할 수 있기 때문에.
요즘에는 volumetric ray matching을 통해 MLP를 최적화해서 Neural Radiance Field로 표현하기도 한다.
보간을 통해 continuous representation으로 나타낸다. 근데 stochastic sampling은 노이즈를 포함할 수 있다(근데 그렇게 따지면..)
우리는 두가지의 가장 좋은 점만 조합한 새로운 방법을 소개한다 : 3D Gaussian representation - 1080p 퀄리티, 학습, 렌더링 속도(by tile-based splatting solution) 모두 좋다
 
  1. 3D Gaussian을 이용해서 표현한다.
    1. Structure-from-Motion(카메라 위치와 이미지를 사용해서 3d 구조를 예측하는 알고리즘. 그만큼 정확도는 낮다)을 통해 얻은 sparse point cloud로 3d gaussian set을 초기화한다.
      3D GS가 좋은 이유! 미분가능한 volumetric representation이면서, 효과적으로 2d로 프로젝션 가능하고, alpha blending(2d 상의 픽셀값을 3d 표현의 alpha 값을 사용해서 투명도 곱해서 표현가능하다는 뜻인듯?)을 적용 가능하다.
  1. 3D 가우시안의 위치, 불투명도, 공분산, spherical harmonic (SH) coefficients를 최적화합니다. 최적화 과정에서 필요에 따라 3D 가우시안을 추가하거나 제거하여 밀도를 조절합니다.
  1. tile-based rasterization과 GPU 기반의 정렬 알고리즘을 사용해서 실시간 렌더링, 빠른 학습
 
 
전체적인 개념 + 학습/렌더링 되는 방법을 자세히 설명
의역 다소
몇장의 사진에서 얻은 sparse한 포인트들(by SfM)을 가지고 고퀄리티의 3d를 만들어내고자 했다 - 학습가능해야하고 빠른 렌더링이 필요하다(3d를 표현하는 방법이 stochastic하지 않고 explicit하해서, 렌더링 과정에 샘플링이 없으면 좋다고 생각한 듯 하다.) → 그래서 3D Gaussian을 선택
 
notion image
간단한 overview.
fast raterization 중요하다. 보통 이게 최적화 과정에서 보틀넥이니까.
3d 상에 3d gaussian들이 위치한다. 이 3d gaussian들을 이용해서 특정 시점에서의 2d image를 만들고, 이 가우시안들을 최적화하는 방법. 순간순간의 결정들에서 이전 연구를 많이 취사선택했을텐데 거기까지 다 이해하진 못했다.
 
다른 글들을 보니 원래 아는 과정에서 특정 부분만 새로운 개념이 적용된게 아니라 전체적으로 모르는게 많다 보니, 부분적으로 이해하고 넘어가는 것보다 전체 프로세스를 쭉 훑으면서 이해하는게 낫다고 느껴졌다.
따라서 일단 의문이 드는 질문들에 대한 답을 찾은 뒤, 전체 3d gaussian들을 최적화하는 알고리즘을 보면서, 전체 과정을 훑기
 
  • 우선, 3D Gaussian은 Covariance(S), Mean(위치 M), Opacity(A), Color(C)로 나타내어진다.
    • 일단 S에 대해서
      • 3d gaussian의 공분산 행렬으로, 3d 이기 때문에 3*3 matrix다.
        1. 공분산 행렬은 전부 양수여야한다(분산이기 때문에 음의 값은 어짜피 의미 없다).
        1. 근데 gradient descent로 이 값을 최적화 하는 과정에 이 제약을 걸기가 까다롭다.
        1. 따라서 공분산 행렬을, 같은 특성을 가지면서도 다르게 표현한다. → scale과 rotation으로 나누어 표현!
        그리고 이 두가지를 각각 따로 독립적으로 최적화한다.
        scale matrix s는 3d vector로 나타내고, rotation은 quaternion(4*1 vector)으로 표현가능하다.
    • A는 alpha 값이고, 단일 실수값이다. opacity이기 때문에 0~1로 표현되도록 값에 sigmoid를 적용해서 얻는다.
    • Color에 대한 이해가 가장 어렵다.. Spherical Harmonics 방법을 쓴다는데 구체적으로 파라미터가 뭔지는 코드를 봐야알 것 같다.
      • notion image
        구면 좌표계로 컬러를 표현하는 방법.
        현재 그 구를 보는 시점을 두가지 각도()를 사용해서 표현한다.
        notion image
        l은 0 이상의 정수, m은 -l ~ +l 까지의 범위를 가지는 정수다.
      • 개념적으로 이해해보자면 l이 커질수록 함수가 복잡한 표현을 가진다. 0이면 구가 전부 같은 색이고, 1이면 한 방향을 기준으로 색이 달라진다.
        • m은 특정 차수 l에 대해 함수가 구면에서 어떻게 변하는지를 결정한다.
        notion image
        각기 다른 차수 l 값에서 계산한 값을 weighted sum해서 최종 값을 얻는다. 이 때 weight가(위의 식에서 k) 학습되는 값이다. l은 고정값. 논문에서 말하는 spherical coefficient가 이 k값을 의미한다.
       
  • 3D gaussian들을 이용해서 어떻게 2d image로 표현하지?
    • 입력 값 : 이미지의 w, h, 3D gaussian의 M, S, C, A, 이미지를 위한 카메라 위치 V
      notion image
      1. CullGaussian
        1. 주어진 카메라 위치에서 관측될 수 있는 가우시안만 남긴다. 뒤에있어서 어짜피 안보이는건 계산에 사용하지 않는 것.
      1. ScreenspaceGaussian
        1. 우선 3d gaussian들을 현재 카메라 시점에 기반한 평면 위로 보내, 2d gaussian으로 표현한다.
          아래가 projection 식. W는 viewing transformation, J는 쟈코비안 of affine approximation of the projective transformation
          notion image
          이전 연구에 따르면 위에서 얻어진 시그마’ 에서 3번째 row와 col을 사용하지 않고 2*2만 가져와서 동일한 특성을 가진 평면위의 가우시안으로 표현할 수 있다고 한다.
      1. 전체 width, height를 16*16의 크기의 tile들로 나눈다. 어짜피 독립적으로 계산되니까 CUDA를 통해 병렬적으로 렌더링하기 위함.
      1. DuplicateWithKeys
        1. 타일마다 각 가우시안의 키를 생성한다.
          하나의 2d 가우시안이 여러 타일에 보이는 경우엔 복사한다.(각 tile별로 CUDA 병렬처리 하기 때문에 여러개로 만들어야함)
          key는 64 bit이고, 앞의 32 bit는 depth값, 뒤 32 bit는 타일 ID
      1. SortByKeys
        1. 각 타일의 가우시안들을 key를 기준으로 sorting해서 depth 순으로 정렬한다. 이렇게해서 blending 과정에서 카메라와 가까운 Gaussian을 먼저 그린다.
      8. Blend in order
      타일마다 개별 CUDA Thread block으로 실행하여, 주어진 하나의 pixel에 대해 가까운 가우시안부터 사용해서 color와 alpha값을 계산한다. 데이터 로딩, sharing/processing 전부 병렬처리해서 빠르다고한다.
      당연히 앞에서부터 하다가 alpha값이 일정값을 넘으면 뒤는 굳이 계산 안함.
      gradient를 opacity 정도에 따라 backprop하도록 한다.
 
 
notion image
  1. 여기서 우선 가우시안들의 Mean 값은 SfM points들의 위치로 초기화되어 시작한다(갯수도?)
    1. 나머지 S, C, A 값은 임의의 값으로 초기화 한다.
  1. 데이터에서 카메라 위치 V와 그 때의 이미지 I를 가져온다.
  1. Rasterization을 통해 3d gaussian으로부터 2d image를 만든다.
  1. 두 이미지를 비교하여 Loss를 계산한다.
    1. Loss =
  1. adam optimizer로 backprop한다.
  1. Adaptive Control of Gaussian : 중요한 개념!
    1. 100 iteration마다 수행된다.
      특정 기준에 따라 3D 가우시안을 없애거나, 2개로 분리하거나, 복사해서 2개로 만든다.
      notion image
      • remove : alpha값이 임계값보다 낮으면 제거한다.
      • clone : 전체 영역을 충분히 커버하지 못하는 gaussian은 같은 크기로 복사되고, positional gradient 방향에 위치시킨다.
      • split : 전체 영역을 넘어서서 커버하는 gaussian은 2개로 나눈다(1.6의 scale). 위치는 원래 가우시안에서 2개를 샘플링해서.
  1. 3000 iteration마다 alpha 값을 0으로 초기화 해준다.
    1. 너무 많이 가우시안이 생긴 영역이 있을 수도 있는데 주기적으로 초기화해서 다시 학습하도록 하면 그 경우 gaussian들이 remove되어서 잘 학습한다.
 
Evaluation
notion image
성능도 좋으면서, 속도도 mipNERF에 비하면 훨씬 빠르다. sampling이 아니라 explicit하면서도 빡세게 병렬처리하도록 구현해서 그런듯
 
흥미로웠던 부분은 ablation인데,
notion image
초기화를 SfM으로 하지않고 랜덤하게 했을 때. iteration을 늘려도 이런가?
 
notion image
같은 수의 iteration을 기준으로 split을 안하면 주된 물체는 잘 해도 배경을 잘 못하고, clone을 안하면 배경을 어느정도 해도 주된 물체를 잘 못한다(clone이 수렴 속도를 빠르게 해준다.).
 
NERF보다 GPU memory는 많이 든다.
 
 
 
 
 
 
 
 
Share article
Subscribe to our newsletter

Kim Hojin