딥러닝/3D

CS580 lecture 11

stop0729 2025. 4. 30. 17:45

성민혁 교수님의 컴퓨터 그래픽스 강의 11강을 듣고 내용을 정리하려고 한다.

설명을 위한 글을 쓰기보다는 듣고 이해한것을 바탕으로 남긴다.

 

 

 

Novel View Synthesis

여러 각도에서 촬영한 이미지를 최적화 시켜서 3d volume으로 만들고, 이전에 보지 못한 각도에서 봤을때도 잘 렌더링 되게 만드는 것이 목표

 

이때 우리는 기존 딥러닝 방식처럼 이해할수 없는 black box decoder를 만드는것이 목표가 아니라, 이해할 수 있는 이미지 decoder를 만드는것이 목표이다. 이를 위해 그래픽스 기법중 하나인 렌더링 방정식을 사용한다.

 

View Synthesis를 위한 neural network의 Input은 입력 사진들에 structure from motion(colmap) 을 돌려 뽑아낸 camera matrix 이고, Output은 input 사진에 해당하는 2D image 이다. Loss function은 실제 넣어준 input 사진과 Output을 뽑아낸 2D image 사이 픽셀 차이값이다(PSNR, SSIM).

 

 

 

 

Pixel2Mesh

Nerf에 관해서 얘기하기 전에 먼저 이전 방법론 몇가지를 얘기 하려고 한다. 2018년에 나온 Pixel2Mesh 이다.

 

이 논문은 3D representation으로 mesh를 선택했다. Ellipsoid한 template mesh를 처음에 초기화하고, input image로부터 conv를 통해 뽑아낸 feature를 활용하여 mesh deformation 을 시키는 것이다.

 

그러나 초기화 한 templit shape과 비슷한 형태의 input에 대해서만 결과를 잘 만들어내고, arbitary한 topology(여기서는 3D shape이라 생각) 에 대해서는 결과가 좋지 못했다. 또한 mehs update하는것이 너무 느리다는 단점도 있었다. Mesh를 3D representation으로 쓰는것의 한계점이였다. 

 

 

 

 

DeepSDF

이후에는 3D representation으로 mesh와 같은 explicit 표현이 아니라 implicit한 표현을 생각해냈다. 공간상에 위치에 대해서 그 위치가 표현하려는 3D 물체와 얼마나 가까운지, 내부에 있는지 외부에 있는지를 나타내는 표현법이다. 이는 mesh와 다르게 vertex나 topology를 고려할 필요가 없는 획기적인 방법이였다.

 

그러나 이런 implicit한 표현법을 어떻게 렌더링에 활용할 수 있을까?

 

 

 

 

Spehre Tracing

공간상의 점에서 구 모양으로 빛을 솨서 표면까지 가장 가까운 거리(f(p))를 찾고 우리가 보는 방향(p)로 진행시키는것을 반복하며 렌더링 하는 방식이 있다. 그러나 이런 방식은 diffrentiable 하지 않기에 딥러닝에 적용하기 어렵고, 너무 계산 비용이 비싸다. 또한 오른쪽 위와같이 표면에 부딪히지 못하는 경우 예외 처리가 힘들다.

 

 

 

 

Volume Rendering

좌 : ray casting, 우 : volume redering

 

그래서 나온것이 볼륨 렌더링이다. 이는 현실세계에서 빛이 물체 표면에 닿아 반사되어 우리 눈에 들어온다는 물리적 가정을 넘어서는 렌더링 기법이다. 표면속 volume 내 입자까지 고려하여 들어오는 모든 입자들의 색을 섞어 렌더링에 활용하려는 방식이다. 이런 방식은 예전부터 구름이나 유체를 렌더링 하는데 많이 활용되어 왔다. 

 

왼쪽 그림은 파란색 표면에 부딪힌 부분만 고려하는 반면, 오른쪽 그림은 부딪힌 표면 이외에도 통과해서 들어가 빨간색 까지 고려하게 된다.

 

 

 

 

DeepVoxel

 

Implicit한 representation과 볼륨 렌더링을 엮기전에 먼저 이전에 기존 방법론을 잠깐 알아보자. DeepVoxels: Learning Persistent 3D Feature Embeddings, CVPR 2019이다. 3D representation 방식으로 3D Voxel을 사용하였다. 

 

 

2D 이미지로부터 CNN을 통해 한 차원 낮은 피쳐를 뽑아내고 그것을 grid voxel에 unprojection 한다. 그리고 임의의 방향에서 바라보는것을 고려해서 다시 projection 한다. 이때 ray 상에 어떤색깔로 정해질지는 Occlusion-Aware network를 사용한다. 

 

 

 

Occlusion network는 ray에 해당하는 복셀 색깔들중 어떤 복셀값이 가장 확률이 높을지를 예측해준다. 이를 통해 projection 되는 피쳐가 어떤 색을 띄는지를 결정하게 된다. 위 논문에서는 appearance 정보를 3D voxel이라는 자료구조에 encode하고 decode 하는 방식으로 표현한다. 그러나 3D voxel은 메모리 상으로 너무 무겁고, 해상도 증가에서의 한계가 있고, occlusion network 투영되는 맨 앞의 복셀을 고려하지 않게되어 물리적으로 올바르지 않다는 문제가 있다. 

 

 

 

 

Neural Radiance Fields

자 이제 불러주던 너프맨..이 되어보자.

 

 

위에서 DeepVoxel을 활용한 novel view synthesis를 제시하였는데, NeRF는 

Voxel 자료구조에 저장하던 정보들을 Implicit Funcion 형태로 바꾸고

Occlusion-aware projection을 하여 렌더링 하던것을 Volume rendering으로 바꾸고

이미지에서 cnn으로 뽑아내던 Latent feature라는 정보를 View-dependent colors로 바꿨다.

 

 

 

Volume Rendering 은 표현하려는 물체 안 입자들을 모두 고려하는 방식이다. 물체 표면에 반사되어 모든 궤적을 고려해야하는 Ray Tracing에서 물리적인 완화를 둔 방식이다. NeRF에서는 이 각각의 Volume의 density(빛의 흡수정도)와 radiance(색깔)을 고려하여 표현한다. 3DGS에서 가우시안마다 Opacity(불투명도)를 고려했던것과 다르게 NeRF에서는 각각의 density를 계산하고 렌더링시에 Opacity꼴로 표현한다.

 

 

여기서 잠깐 Radiance가 무엇인지 얘기를 해보자면, 빛 에너지를 시간으로 나누면 Flux(power)가 되고, Flux를 solid angle(3차원 상에서의 입체각)과 면적으로 나눈, 단위 면적당 단위 입체각당 빛의 양이다. 구글링 해보면 복사 휘도 뭐시기라 나와서 이해가 안갔는데 강의 전체를 들으면서 이해할 수 있었다. 이러한 Radiance는 렌더링을 할때 기본 빛의 단위량으로 쓰인다. 렌더링 방정식에서 입사하는 Radiance L(p, w)를 방향(Solid angle)을 고려하여 적분하면 reflected 되서 나가는 Radiance를 표현한다.

 

 

 

 

다시 NeRF로 돌아와서 생각해보면 입력값은 3D 공간상 좌표값 (x, y, z)와 구면 좌표계 상에서의 각 θ, φ 를 고려하여 5가지를 입력 받는다. 색(Radiance map)은 5가지 입력을 전부 사용하여 보는 각도에 따라 달라보이게 모델링 하였고, 밀도(Density map)은 각 입자의 좌표만 고려하게 하였다.

 

 

 

BRDF f를 고려하고 어떤 path로 traicing 할지 고려하기 위해 몬테카를로 적분을 하던...  기존 렌더링 방정식과 다르게 볼륨 렌더링은 ray를 쐈을때 샘플링 되는 r(t) 점마다의 Transparency, σ(r(t)), c(r(t), d) 세가지만 고려하면 된다. 이때 σ(밀도)와 c(색)은 network를 통해 산출된다. 그리고 Transparency는 각 입자의 밀도를 고려하여 자연상수의 역수로 취해주기에 t가 커질수록 작아진다. 즉 ray에서 깊이가 깊어질수록 점점 투명도가 낮아지는것을 모델링 한거다. 즉 네트워크를 통해 구한 밀도와 색을 볼륨 렌더링 방정식에 넣으면 그 ray에 해당하는 픽셀값에서의 색이 나온다.

 

 

 

볼륨 렌러링에 관해서 좀 더 파보자.

ρ : particle density = unit volume당 particle 개수 

t : 단위 거리

E : ray를 일정한 면적을 가진 원통으로 본다면 그것이 투영될때 면적

A : particle이 투영됐을때의 면적

 

이때 단위 볼륨당 particle 개수는 E*Δt*ρ(t)이고 paticle에 의해 빛이 흡수되는 정도는 E*Δt*ρ(t)*A이다.이때 우리가 network를 통해서 구하는 밀도 σ는 A*ρ(t)라 한다. 즉 우리가 위에서 말한 volume 밀도 σ는 ray가 particle에 충돌해서 감소되는 정도를 말하고, particle의 개수와 면적에 비례한다고 모델링한다.

 

 

 

그렇다면 Transparency는 충돌할 확률을 적분해서 역수 취하였기에 t지점까지 부딪히지 않고 남아있을 확률을 의미한다. 또한 Transparency와 σ의 곱은 t지점까지 부딪히지 않았는데 t지점에서 부딪힐 확률을 의미한다. 

 

 

 

Transparency는 ray가 일정한 방향으로 향하므로 solid angle이 정해져있기에 light intensity라 생각한다. 빛이 향하는 방향이 정해져있을때 t지점에서 intensity의 변화율은 t지점의 T * (1 - σ(t) * Δt) 라 한다. (1 - σ(t) * Δt)은 t지점에서 particle에 의해 가려지고 남아있는 빛이 투과되는 정도를 의미한다. 이때 ΔT를 미분방정식으로 풀면 위와 같은 결과가 나온다. T는 ray가 진행함에 따라 감소되는 정도를 모델링 하려고 했기에 자연상수의 역수로 감소하는 모습을 보게 된다.

 

사실볼륨렌더링 공식을 세세하기 설명하려면 너무 이야기가 길어진다. 볼륨 렌더링 유도에 관해서는 아래에서 자세히 볼 수 있다.

https://yconquesty.github.io/blog/ml/nerf/nerf_rendering.html#the-rendering-formula

 

 

 

 

 

그러면 렌러링 공식 내의 밀도와 Transparency는 구했는데, 이를 사용하여 어떻게 실제 적분을 할 수 있을까? 여기서 고려할 점은 볼륨 렌더링 공식안에는 적분이 있는데 우리가 사용하는 컴퓨터는 discrete하기에 continuous한 적분에 대해서 계산할 수가 없다. 따라서 볼륨 렌더링 공식을 discrete하게 바꿔서 구해야한다. Ray의 모든 점을 고려해야할게 아니라 일정 간격마다 한 점씩 고려(stratified sampling) 하기로 정한다. 

 

 

 

 

빛을 따라 적분한 C(r) 값은 각 간격마다 구한 색들의 합으로 구한다. 신기한것은 이렇게 discrete 하게 만든 볼륨렌더링 방정식이 기존 컴퓨터 그래픽스의 alpha compositing 형태와 같다는것이다.

 

 

 

결국 NeRF는 network에 밀도와 rgb의 정보를 담고 있는 형태이다. 그리고 그러한 네트워크로 부터 나온 밀도와 RGB값을 볼륨렌더링 방정식에 넣어 나온 픽셀 C(r)값과 ground truth 값 사이에 Loss를 구하여 backpropagate하면서 넣어준 scene에 맞게 network를 학습시킨다. 네트워크에서 특이한점은 앞단에서는 밀도만 구하고, 뒷단에서 보는 방향까지 포함해서 RGB 값을 구한다.

 

 

 

 

 

Input을 그냥 scene으로 넣어주면 novel view scene의 high frequency 영역을 잘 보여주지 못하는 모습을 보였다. 이를 보안하기 위해 positional encoding으로 input을 쪼개서 넣어준다. 신호를 푸리에 변환해서 넣어주듯이 우리 scene을 positional eocoding을 통해 쪼개서 넣어주면 사진의 high frequency부분을 더 잘 렌더링 해주는 모습을 볼 수 있었다. 이것은 neural network를 커널 관점에서 볼때 나타나는 성질이다. 네트워크가 깊고 input이 많을때는 high frequency(픽셀의 색 입장에서 보면 급격히 변하는 선이나 테두리 같은 부분)까지 잘 표현하고, low frequency에 대해서는 얕은 네트워크로 충분하다고 말한다.

 

 

 

 

그래서 저자는 위치에 따른 밀도의 변화에서 high frequency 특성이 중요하다고 생각했기에 앞단의 깊은 네트워크로 표현하고, 보는 방향까지 포함하여 나오는 RGB는 low frequency로 충분하여 뒷단의 얕은 네트워크로 표현하였다.

 

 

 

 

 

 

BRDF를 포함한 렌더링 방정식에서는 입사되는 빛이 어떤 방향으로 향하는지를 모두 계산할 수 없기에 importance sampling을 하였다. BRDF 함수를 더 고려하여 방향을 sampling 할지, 입사광을 더 고려할지에 따라 multi importance sampling을 하면서 그에 따른 결과를 볼 수 있었다.

NeRF에서는 방향을 sampling 하는것이 아니라 ray에 있는 특정 간격마다의 점을 sampling 한다. 또한 이때 sampling 할 지점이 어떤 점이 좋을지 알 수 없기에 coarse하게 sampling 한번하고, 이후에 coarse하게 sampling 한것을 토대로 조금 더 정확한 sampling을 한다.

 

 

 

훈련 과정은 위와 같다. 그러나 Nerf는 볼륨 렌더링 기반이기에 rasterization 방식보다 훨신 느리다. 또한 large scene을 잘 잡지 못한다. 정확한 Colmap 결과가 필요하다. 움직이는 scene에 대해서 표현하기 어렵다. 변하는 조명에 대해서 표현하기 어렵다. 정확한 shape을 표현하기 어렵다. 마지막으로 보지못한 장면에 대해서 일반화 하기가 어렵다. 위와 같은 문제점들은 앞으로의 연구주제들이고 이미 어느정도 해결되기도 하였다.

 

 

 

 

결국 풀려는 문제가 렌더링이기에 그래픽스와 비전 도메인에 관한 지식이 필요하다고 생각하였다. 뉴럴 네트워크는 도메인 지식을 활용하여 어떤 정보를 담고 어떻게 학습시킬지에 관해서 생각해볼수 있겠다. 사실 요즘은 implicit 하게 학습시키는 NeRF보다 3dgs가 활발한 것 같다. 

 

 

 

 

 

 

reference :

 

https://mhsung.github.io/kaist-cs580-spring-2024/

 

CS580 Computer Graphics (KAIST, Spring 2024)

CS580: Computer Graphics Time & Location Time: Mon/Wed 10:30am - 11:45am (KST) Location: Online via Zoom Zoom Link Description This course covers advanced topics in computer graphics, focusing on rendering. It is divided into three parts: a review of basic

mhsung.github.io

 

 

https://yconquesty.github.io/blog/ml/nerf/nerf_rendering.html#numerical-quadrature

 

NeRF: A Volume Rendering Perspective

NeRF: A Volume Rendering Perspective Overview NeRF implicitly represents a 3D scene with a multi-layer perceptron (MLP) F:(x,d)→(c,σ) for some position x∈R3, view direction d∈[0...

yconquesty.github.io