NeRF 구현을 위해 ray casting을 공부한 내용을 이곳에 기록한다.


NeRF 구현을 위해 dataset을 다운 받으면 다음과 같이 나와있다.

{
    "camera_angle_x": 0.6911112070083618,
    "frames": [
        {
            "file_path": "./train/r_0",
            "rotation": 0.012566370614359171,
            "transform_matrix": [
                [
                    -0.9999021887779236,
                    0.004192245192825794,
                    -0.013345719315111637,
                    -0.05379832163453102
                ],
                [
                    -0.013988681137561798,
                    -0.2996590733528137,
                    0.95394366979599,
                    3.845470428466797
                ],
                [
                    -4.656612873077393e-10,
                    0.9540371894836426,
                    0.29968830943107605,
                    1.2080823183059692
                ],
                [
                    0.0,
                    0.0,
                    0.0,
                    1.0
                ]
            ]
        },
        {
            "file_path": "./train/r_1",
            "rotation": 0.012566370614359171,
            "transform_matrix": [
                [
                    -0.9305422306060791,
                    0.11707554012537003,
                    -0.34696459770202637,
                    -1.398659110069275
                ],
                [
                    -0.3661845624446869,
                    -0.29751041531562805,
                    0.8817007541656494,
                    3.5542497634887695
                ],
                [
                    7.450580596923828e-09,
                    0.9475130438804626,
                    0.3197172284126282,
                    1.2888214588165283
                ],
                [
                    0.0,
                    0.0,
                    0.0,
                    1.0
                ]
            ]
        },

이게 뭘까

일단 자료를 조금 찾아보다 보면 결국 이런 형식으로 나옴을 알 수 있다.

{
    "camera_angle_x": 0.6911112070083618,
    "frames": [
        {
            "file_path": "./train/r_0",
            "rotation": 0.012566370614359171,
            "transform_matrix": [
                [
                    //r11,
                    //r12,
                    //r13,
                    //tx
                ],
                [
                    //r21,
                    //r22,
                    //r23,
                    //ty
                ],
                [
                    //r31,
                    //r32,
                    //r33,
                    //tz
                ],
                [
                    0.0,
                    0.0,
                    0.0,
                    1.0
                ]
            ]
        },

즉, $\begin{bmatrix} r_{11} &r_{12} &r_{13} &t_x \\ r_{21} &r_{22} &r_{23}&t_y \\r_{31} &r_{32} &r_{33} &t_z \\ 0&0&0&1 \end{bmatrix}$를 의미한다. 위에 태그에서 볼 수 있듯이, 이는 transfom의 기능을 해주는데, 정확히 무엇을 무엇으로 transform하는 것인지 확인해보자.

우선 좌표계를 헷갈리면 안 된다.

image.png

위와 같이, 바라보는 시점을 기준으로 x-y를 나누며, 사실 생각해보면 당연하다. 결국엔 2D로 변환할 건데 x-y 평면이 내가 바라보는 시점과 수직해야할테니까.

그래서 뒤쪽에 Z의 값에 -1을 곱하라는 의미도 이런 의미에서 비롯된다. 우리는 앞을 보고 있는데 Z축의 양의 방향은 우리를 향해 있으니.

카네기 멜론의 slide에서 볼 수 있듯이, 결국 coordinate transform이란 아래와 같다.