바로 보는 구조
| 공간 | 의미 |
|---|---|
| Object space | 모델 자체의 로컬 좌표 |
| World space | 장면 안의 공통 좌표 |
| View space | 카메라 기준 좌표 |
| Clip space | projection 후 clipping 기준 좌표 |
| NDC | -1..1 정규화 좌표 |
| Screen space | 실제 픽셀 좌표 |
object -> world -> view -> clip -> NDC -> screen공간
그래픽스에서 좌표는 숫자 세 개가 아니라 어떤 기준에서 본 위치인가까지 포함합니다. 같은 (1, 0, 0)이라도 object space에서는 모델의 오른쪽일 수 있고, world space에서는 장면의 x축 방향일 수 있습니다.
좌표 공간을 섞으면 조명, 카메라, normal, texture projection이 모두 틀어집니다. 예를 들어 light direction은 world space인데 normal은 object space라면 dot product 결과는 의미가 없습니다.
dot(normal_object, light_world) // 서로 다른 공간이라 잘못된 계산
dot(normal_world, light_world) // 같은 공간이라 의미 있음변환
변환은 좌표를 한 공간에서 다른 공간으로 옮기는 연산입니다. translation, rotation, scale은 보통 4x4 행렬로 합쳐서 다룹니다. 4x4를 쓰는 이유는 위치 이동까지 행렬 곱으로 표현하기 위해 homogeneous coordinate를 사용하기 때문입니다.
계산 기준
| 계산 | 보통 맞춰야 하는 공간 |
|---|---|
| 물체 배치 | world space |
| 카메라 상대 위치 | view space |
| clipping | clip space |
| 조명 dot 계산 | world 또는 view space |
| normal map | tangent space |
| 후처리 | screen space |
변환 순서도 중요합니다. scale, rotation, translation을 어떤 순서로 곱하느냐에 따라 결과가 달라집니다.
translate * rotate * scale
rotate * translate * scale두 식은 같은 숫자 행렬을 쓰더라도 “먼저 회전한 뒤 옮기는가”, “옮긴 뒤 원점 기준으로 회전하는가”가 달라집니다.
주의할 점
행렬 표기와 곱셈 순서는 API와 수학 관례에 따라 달라질 수 있습니다. row-major/column-major, row vector/column vector, 왼손/오른손 좌표계를 함께 확인해야 합니다.
중요한 것은 특정 표기를 외우는 것이 아니라, 지금 값이 어느 좌표 공간에 있고 다음 단계가 어떤 공간을 요구하는지 추적하는 것입니다.
참고 링크
1 sources