AI/컴퓨터비전(CV)

[CV 논문] 3D Gaussian Splatting for Real-Time Radiance Field Rendering

CSE 2026. 2. 24. 13:20

 

 

아래 글에서 이 블로그에서 리뷰한 논문들의 흐름과 분야별 분류를 한 눈에 볼 수 있다.

읽은 논문들 정리

 

3D 가우시안이라는 새로운 아이디어로 기존의 여러 문제들을 해결하고 실시간성을 확보한, 요즘 제일 핫한 논문이라고 할 수 있다.


3D복원에서 기존의 MVS라는 방법은 복원이 안된 구멍이 있거나, 없는 물체를 만들어내는 문제가 있었다.

이 블로그에서도 다뤘던 NeRF에서는 광선을 따라 많은 지점을 샘플링해 속도의 문제가 있었다.

NeRF를 빠르게 발전시킨 InstantNGP같은 방식에서도 고해상도 실시간 렌더링은 한계가 있었다.

 

(참고 - NeRF논문 리뷰 : NeRF: Representing Scenes as Neural Radiance Fields for View Synthesis)

 

이 논문은 물체의 꼭짓점 같은 포인트에 구를 놓고 구를 찌그러트리고 변형해서 물체에 맞추는 방식을 사용한다.

 

컴퓨터그래픽스와 관련된 공부를 했다면 mesh라는 개념을 알 것이다.

이 논문은 러프하게 보자면 타원체를 'mesh를 이루는 polygon'처럼 학습시키는 것이라고 이해할 수 있을 것 같다.

그렇다고 두께가 0인 물체는 아니고 밀도 분포를 가진 덩어리기 때문에 더 부드러운 렌더링이 가능하다.

 

비유적으로는 동전처럼 얇고 넓은 원 모양의 솜사탕을 물체의 표면을 따라 덕지덕지 붙인다고 생각해봐도 좋을 듯 하다.

 


미분 가능한 3DGS

 

 

3DGS(3D Gaussian Splatting)는 장면을 수백만 개의 3D 가우시안으로 구성한다.

이 가우시안들은 중심점($\mu$)과 모양을 결정하는 공분산행렬($\Sigma$)로 정의되는 확률밀도함수이다.

중앙에서는 확률이 1이고, 주변으로 갈수록 확률이 낮아진다.

무한히 퍼지는 모양이므로 99%신뢰구간까지만 계산에 포함하고 나머지는 버리는 것으로 논문에서는 사용했다.

또 불투명도($\alpha$)가 너무 낮아져도 버리게 된다.

$$G(x) = \exp\left(-\frac{1}{2}(x-\mu)^T \Sigma^{-1} (x-\mu)\right)$$

$\mu$ (Mean): 가우시안의 3D 중심 좌표.

$\Sigma$ (Covariance): 가우시안의 크기와 회전(방향)을 결정하는 $3 \times 3$ 행렬.

$\alpha$ (Opacity): 각 가우시안의 투명도를 결정하며, 블렌딩 과정에서 이 값이 곱해진다.


카메라가 보는 세상은 2차원이므로 3차원에 있는 가우시안을 2차원으로 투영시킬 필요가 있다.

 

$$\Sigma' = J W \Sigma W^T J^T$$

여기서 $W$는 공간을 보는 시각을 카메라 좌표계로 바꿔주는 행렬이다.

컴퓨터그래픽스 과목에서 기초적으로 다루는 내용이므로 추가적인 설명은 스킵하자.

 

기존의 3차원 공간을 카메라의 관점에서 보는 것으로 변환했으면 이제 2차원인 카메라 화면에 어떻게 투영될지를 봐야한다.

이 3차원 → 2차원 투영변환은 비선형변환이기 때문에 이를 선형으로 근사해서 사용하는데 이를 위해 수학에서 나오는 자코비안 행렬($J$)을 사용한다.

 

논문에서는 가우시안의 중심점을 기준으로 주변의 좁은 영역에서는 투영변환이 선형변환이라고 가정했고 따라서 위의 식을 사용한 것이다.

'근사'이기 때문에 중심점에서 멀어질수록 오차가 커지지만 그 전에 이미 충분히 투명해지고 가우시안의 크기 자체가 작기 때문에 큰 문제가 없다.

 

어쨋든 결과로 나온 $\Sigma'$에서 3행/3열을 날리고 남은 2x2행렬이 화면(2차원)상에서의 타원 모양을 결정하게 된다.

굳이 3x3행렬을 만들고 행/열을 날려 2x2를 만드는 이유는 어떤 방향에서 봤을 때도 제대로 타원 모양을 결정하기 위해서이다.

처음부터 2x2라면 해당 방향에서 봤을 때만 정상작동한다.


위의 $\Sigma'$를 구하는 식은 이해했는데 정작 그 안의 $\Sigma$를 어떻게 구하는지는 얘기하지 않았다.

원래 이 $\Sigma$를 학습시켜야 하지만, 이것의 의미는 통계적으로 분산이므로 음수가 될 수 없는데, gradient계산을 하다보면 음수가 나올수 있기 때문에 직접 학습을 시키지 않는다.

수학적 표현으로는 0 이상의 고윳값을 가져야한다.

이를 PSD조건이라고 한다.

 

따라서 논문에서는 수학적 안전장치를 사용했다.

수학적으로 어떤 행렬 $A$에 대해서 $AA^T$형태는 PSD를 만족함을 알고 있기 때문에,

$\Sigma = RSS^TR^T$

위 식처럼 쪼개서 $R$과 $S$를 대신 학습한다.

이 두 행렬은 각각 가우시안의 크기정보와 회전정보를 나타낸다.

 

$S$는 $(s_x, s_y, s_z)$로 저장된 3차원 벡터를 대각행렬로 변환한 행렬이다.
이는 가우시안의 각 축 방향으로의 크기를 나타낸다.

 

$R$는 회전행렬이다.
4차원 쿼터니언 $(q_r, q_i, q_j, q_k)$형태로 저장된 회전 정보를 3x3행렬로 만든다.
4차원 벡터를 3x3행렬로 바꾸는 과정에 대해서는 이 블로그의 다른 글인 아래 링크를 참고하면 좋을 듯 하다.
3차원 공간에서의 회전 : Quaternion(사원수) & 회전행렬

 

이 과정에서 속도를 위해 미분을 할 때 pytorch, tensorflow같은 툴을 사용하지 않고 직접 모든 파라미터의 미분 식을 유도해 사용했다.


최적화 및 가우시안의 밀도 조절

최적화

SGD와 표준 GPU프레임워크, 커스텀 CUDA커널을 사용해 효율성을 높였다.

또 투명도에는 sigmoid를 사용해 0~1 사이의 범위로 조정하고, 공분산의 scale에 지수 활성화 함수를 적용한다.

공분산의 scale은 위에서 얘기한 $S$행렬을 얘기하는데 이 행렬의 대각 원소들, $s = (s_x, s_y, s_z)$는 음수를 원소로 가지면 안되므로 지수를 취해주는 것이다.

 

최적화를 위해 아래와 같은 손실 함수를 사용한다.

$$\mathcal{L} = (1 - \lambda)\mathcal{L}_1 + \lambda\mathcal{L}_{D-SSIM}$$

 

$ \mathcal{L}_1$은 렌더링된 이미지와 실제 정답 이미지의 픽셀 값 사이의 수치 차이를 계산한다.

$\lambda \mathcal{L}_{D-SSIM}$은 이미지의 구조적 유사성을 평가한다.

 


가우시안 밀도 조절

SfM에서 얻어진 sparse points들이 있는 상태에서 시작한다.

이후 밀도를 조절하는 과정을 거친다.

 

100 iterations마다 아래 동작들을 한다.
1. 투명도가 일정 값 아래인 가우시안은 삭제한다.

2. 가우시안을 밀집화(densification) 한다.

 

두번째 경우인 밀집화는 가우시안들이 아직 잘 구성되지 않은 영역(under-reconstruction)이있거나 한 가우시안이 너무 넓은 영역을 차지하는 경우(over-reconstruction)일 때 발생한다.

 

이 밀집화는 결국 기하학적 특징이 가우시안들에 의해 아직 잘 구성되지 않았다고 볼 수 있다.

따라서 이 때는 gradient가 클 것이다.

그래서 이 reconstruction을 판별하는 기준은 gradient가 $\tau_{pos}=0.0002$보다 클 때이다.

가우시안의 크기가 특정 값 이하라면 2-1의 과정으로, 더 크다면 2-2의 과정으로 넘어간다.

 

2-1. under-reconstruction

가우시안을 복제해서 더 상세한 표현을 가능하게 하므로써 해결한다.

이 때 가우시안의 크기(scale)가 작은 놈을 골라 복제한다.

복제를 하고 gradient방향으로 조금 이동시켜 배치한다.

 

2-2. over-reconstruction

이 경우 하나의 큰 가우시안을 두 개로 분할 한다.

이 때 실험적으로 결정된 계수인  $\phi = 1.6$로 크기를 나눠 두 개의 가우시안을 만든다.

 

위 과정들과 별개로, 3000 iterations마다 $\alpha$를 0에 가깝게 설정하는 과정이 있다.

reconstruction과정을 거치며 카메라 근처에서 가우시안의 개수가 불필요하게 늘어날 수 있는데, 이를 거르기 위함이다.

$\alpha$를 0에 가깝게 설정하면 계속 진행될 학습에서는 정말 필요한 가우시안의 투명도 값만 증가하게 되고 $\alpha$값이 거의 그대로 유지되는 가우시안들은 삭제된다.

 

또 월드 공간에서 너무 크거나 뷰 공간에서 너무 큰 가우시안은 주기적으로 제거된다.


빠르고 미분가능한 Rasterizer

 

Rasterizer는 간단히 얘기하면 2D화면에 그려주는 SW라고 할 수 있다.

 

이 논문에서는 카메라 화면을 16x16 픽셀 크기의 타일로 나눠 계산하는 방법을 적용했다.

고전적으로는 각 카메라 픽셀 마다 어떤 물체들이 겹치는지를 계산했어야 했다.

하지만 이 방법은 해당 타일 구역 안에 있는 가우시안들을 미리 찾고, 정렬까지 한 후 해당 타일 안의 픽셀들이 그 정렬된 가우시안 리스트를 같이 사용할 수 있게 한 것이다.

출처 : 직접 그림

 

과정을 조금 더 자세히 얘기하면,

1. frustum 바깥의 가우시안은 계산에서 제외시켜버린다.

2. 또 view frustum의 near 평면(그림에서 빨간 네모)에 가깝거나 frustum의 경계에 가까운 값들을 계산할 때는 계산이 불안정해질 수 있기 때문에 이 위치들에 있는 가우시안들은 제거한다.

3. 각 타일별로 자신에게 포함되는 가우시안들의 인스턴스를 생성한다.

4. 각 인스턴스에 대해 타일 번호와 view depth의 정보를 담고 있는 64비트 키를 할당한다.

5. 이 키들을 바탕으로 Radix Sort를 진행한다.

결과적으로 동일한 타일의 가우시안끼리, 그 안에서도 카메라와 가까운 순서대로 정렬되게 된다.

6. 각 타일은 이 정렬 리스트를 보고 자신이 처리할 가우시안 리스트의 시작과 끝을 파악한다.

7. 타일마다 하나의 GPU 쓰레드를 실행해 독립적으로 렌더링 한다.

 

이 때 계산은 NeRF논문과 같은 front to back, 알파 블렌딩을 사용한다.

즉 카메라에 가까운 것들부터 하나씩 쌓아가는 방식이다.

이때 어떤 픽셀의 불투명도가 충분히 커졌다면 뒤에는 계산하지 않고 종료한다.

 

 

역전파를 할 때는 순전파 때 각 픽셀에 영향을 준 가우시안들의 순서를 아는 것이 중요하다.

그래서 이전에 사용했던 타일의 범위와 정렬된 가우시안 리스트를 다시 사용한다.

그리고 계산에 쓰였던 가우시안들의 순서를 역으로 뒤에서부터 앞으로 훑으며 계산을 수행한다.

 


흐름이 정리된 그림은 아래와 같다.


결과

이 표는 3개의 데이터셋(Mip-NeRF360, Tanks&Temples, Deep Blending)에서 여러 모델들을 비교한 것이다.

이 논문의 모델이 모든 데이터셋의 대부분의 성능지표에서 더 좋았던 것을 볼 수 있다.

또한 프레임 수에서 압도적인 차이를 보여주었다.

 

Limited-BW : 그래디언트를 받는 가우시안 수를 제한

Random Init : SfM포인트 대신 랜덤한 점으로 시작

No-Split : 큰 가우시안을 쪼개는 것 금지

No-SH : SH(Spherical Harmonics)함수를 사용하지 않고 기본 색상만 사용

No-Clone : 작은 가우시안 복제 금지

Isotropic : 타원체가 아닌 구로만 사용

Full : 제한 없는 원본 모델

 


요약

기존 신경망 기반 렌더링(NeRF)의 느린 속도를 극복하기 위해 미분가능한 3D 가우시안과 타일기반 레스터라이저를 사용해 고화질과 실시간성을 동시에 잡은 논문

 

핵심포인트

1. 가우시안의 사용

단순한 점이 아닌 위치, 공분산, 불투명도, 색상을 가진 가우시안으로 장면을 정의해 빈 공간을 계산하느라 시간을 낭비하지 않는다.

 

2. 미분 가능한 타일 기반 레스터라이저

수백만 개의 가우시안을 타일별로 묶어 빠르게 정렬해서 픽셀당 계산량을 줄였다.

 

3. 적응형 밀도 제어

그래디언트 값을 기준으로 가우시안을 복제 또는 쪼개기를 하여 효율적으로 스스로 장면에 가우시안을 맞춘다.