테드옹의 VFX
Space Transformation 본문
[들어가기 전에]
후디니는 Row Major(행 벡터, P * m), -Z axis 카메라, Y-up, Right-handed 좌표계, NDC [0,1]를 사용한다
1. Model Space (Object) : 3D
------------Model Transform 행렬 적용
2. World Space : 3D
------------View Transform 행렬 적용
3. View Space (Camera, Eye Space) : 3D
*카메라의 위치를 (0,0,0) -z축으로 옮기고, 똑같은 행렬을 적용하여 오브젝트들을 이동해서 relative position을 유지하는 과정
**여기에서 Shader계산을 하는 것이 보통 Standard이다. 왜냐하면 Projection Transform을 진행할 때 Perspective를 적용하면 오브젝트가 변형될 수도 있기 때문. 모든 오브젝트가 같은 벡터공간에 존재하기 때문에 계산에 용이함
***2번(World Space)에서도 Shading을 할 수 있다
Matnet의 Global Variable은 기준이 Camera Space이기 때문에 Ocean Sample Layer노드에 인풋으로 들어가는 P값을 오브젝트 공간으로 변환하여 넣은 것이고, 노드에서 나온 Displacement 벡터(Interpolation : Direction Vector)는 오브젝트 공간의 벡터값이기 때문에 다시 Current(ie. Camera Space)공간으로 벡터를 변환하여 P벡터에 add한 것이다.
------------Projection Transform 행렬 적용
4. Clip Space : 3D
Frustum View Volume을 Cube로 변환
------------Perspective Divdie(Normalize) 행렬 적용
5. NDC Space : 3D
이전 단계의 Frustum View Volume을 [-1, 1] 범위를 가진 unit cube로 변환
Camera Space를 NDC Space로 변환하는 행렬
여기서 가장 중요한 건Projection Transformation은 Affine Transformation이랑 다르다, 따라서 후디니를 기준으로 행렬 4열의 컴포넌트를 바꿔주고, 동차좌표계를 이용해야한다
조금 더 세부적으로 보면
1. Perspective Matrix(Persepctive Transformation)를 이용하여 원근을 가진 오브젝트로 변형한 후
2. Orthographic Matrix(Affine Transformation)를 이용해서 [-1, 1]의 범위를 가진 큐브로 변형해주면 (Mproj * Mortho) Perspective Projection이 완성되고 이것이 NDC space가 되는 것
후디니와는 조금 다른 z-axis, column major시스템을 사용하는 vulkan이라는 프로그램을 기반으로 하고 있지만 (NDC의 범위도 다름)
Perspective Projection에 관한 내용을 너무 깔끔하게 정리해준 영상 : https://www.youtube.com/watch?v=U0_ONQQ5ZNM
아주 고맙게도 SideFX에서 fovx와 fovy를 구하는 공식을 적어주었다.
그래서 복잡하게 right, left, top, bottom까지 구할 것 없고 카메라의 파라미터만 이용해도 된다. (나이스!!)
복잡해보이지만 밑변을 aperture 파라미터, 높이를 focal length 파라미터로 계산하여 삼각함수를 사용해서 사이각을 구한 것
------------Viewport Transform (Screen Transform) 행렬 적용
6. Image Space (Screen Space) : 2D
일반적인 Affine 변환
1. [-1, 1]의 큐브를 원점에 맞도록 이동
2. 종횡비에 맞도록 Scale (1/2을 곱하는 이유는 NDC 큐브 사이즈가 2이기 때문에)
이 과정에서 1번을 진행하기 전에 X축으로 mirror를 해야할 수도 있다. 왜냐하면 전통적으로 뒤집어져있다더라
*종횡비에 맞도록 이미지가 맵핑됨
**Rasterize, Fragment operation, Coloring 등이 진행된다.
[결국 종합을 하자면...]
1. World Space
2. Camera Space
3. NDC Space (Clip + Divide)
4. Viewport Space의 순서를 거쳐서 3D오브젝트는 2D로 렌더링된다.
처음부터 끝까지 예시를 들어보면
1. Camera Transform
2. Perspective Projection (toNDC)
주목해야할 점은, 3번라인에서 포지션을 동차좌표로 직접 만들어서 26번라인에서 나눗셈(perspective divide, 즉 Normalize)을 진행한 것이고, 22번라인의 4행4열이 0인것은 Affine Transformation이 아니라 Perspective Transformation 계산이기 때문이다.
3. Viewport Transform
좌측은 3D상의 카메라에서 본 돼지고, 우측은 2D 상 Front View에서 본 돼지이다.
P *= Mworld * Mcam * (Mpers * Mortho) * Mview
+7. Tangent Space : 3D (24.06.14 추가)
셰이더를 다룰 때 가끔 등장하는 공간으로, 2D 텍스쳐에서 샘플링한 Normal (RGB vector)을 3D Normal Vector로 바꾸는 과정이다.
보통 이러한 노말 맵들은 RGB (0-1)사이의 값을 가지고 있고 Raw Colorspace로 취급되어야 한다
하지만 3D Displacement를 진행할 땐 안쪽으로 들어가는 음수값 또한 존재해야하기 때문에 2를 곱하고 -1을 하는 계산을 통해 [0, 1]의 값을 [-1, 1]의 값으로 선형보간한다.
그렇게 추출된 RGB값에 지오메트리의 Point 혹은 Vertex에서 추출한 TBN (Tangent, Bitangent, Normal) 행렬을 곱셈하고 정규화시키면 새로운 노말이 되고, 이것을 Shading 계산에 사용하여 마치 깔끔한 표면이 노말맵처럼 오돌토돌한 라이팅을 받도록 계산을 한다. 참고로 후디니에서 TBN 행렬은, 1행이 x-axis(Tangent), 2행이 y-axis(Bitangent), 3행이 z-axis(Normal)이다
따라서 과정을 정리하면
1. Raw Colorpsace에서 Normal맵의 RGB[0, 1]값을 샘플링
2. (RGB * 2) - 1의 과정을 거쳐서 [-1, 1]의 값으로 보간
3. Normalize( Mworld * RGB )의 계산을 통해서 새로운 Normal값을 계산
이렇게 2D 텍스쳐에서 3D 노말로 변형하는 걸 Tangent Space라고 부른다
아우.. 길고 길었던 사투가 끝났다

'Houdini' 카테고리의 다른 글
Python Panel 정리 (0) | 2023.11.27 |
---|---|
Houdini Orient 총정리 (1) | 2023.10.18 |
Guide Deform Wrangle (0) | 2023.09.09 |
Houdini Vellum 정리 (2) | 2023.08.17 |
Gnomon workshop - Lookdev in Arnold Houdini (0) | 2023.07.30 |