지난 글에서 OpenGL 에서 사용하는 전체 변환의 과정과 함께, 그 변환 하나하나에 사용되는 기본 변환인 이동, 회전, 크기조절 3가지를 정리하였다.
이번 글에서는 각각의 기본 변환이 연속적으로 일어나 하나의 행렬곱 형태로 묶인 복합 변환에 대해 정리한다.
용어
복합 행렬 (Composite Matrix) 는 연속된 변환 행렬을 모두 곱한 하나의 행렬이다.
복합 변환 (composite Transformation) : 복합 행렬로 표현되는 일련의 연속된 변환이다.
만약 어떤 물체 P 에 대해 크기조절 변환 S1 을 가하고, 회전 R1 을 가한 뒤, 다시 크기를 S2로 조절했다고 하면
이 물체를 구성하는 새로운 정점 P' = S2 * R1 * S1 * P 로 표현할 수 있다.
기존 물체 왼쪽에 변환 행렬을 곱해나간다.
이때, S2 * R1 * S1 을 미리 계산하여 하나의 행렬로 표현하면 이를 C 로 표현할 수 있고,
위 변환식을 P' = C * P 로 표현할 수도 있다.
이때 C를 복합 행렬이라고 한다.
참고로 물체를 회전한다는 의미는, 그 물체가 놓인 좌표계가 아니라, 물체의 중심 (즉, 모델좌표계의 원점, pivot point) 를 기준으로 회전하는 것을 의미한다.
특정 축 (위 그림에서는 z축) 기준으로 회전하는 것과 물체의 중심 (피벗) 기준으로 회전하는 것은 전혀 다르다.
보통 WCS 에 있는 물체를 피벗 기준으로 회전할 때는 아래의 3가지 변환을 거쳐 진행한다.
1. 피벗과 좌표계의 중심이 일치하도록 물체를 이동한다. (a)
2. 물체를 원점 중심으로 기준축 주위 회전시킨다. (b)
3. 회전된 물체를 1에서 이동했던 방향의 반대로 이동시킨다. (c)
이를 변환행렬로 표현하면 C = (-a, -b, -c) * Rz(Θ) * (a, b, c) 로 표현할 수 있다. (회전은 z축 중심 회전)
참고로 행렬은 곱셈의 교환법칙이 성립하지 않는다.
따라서 이동 후 회전과, 회전 후 이동은 전혀 다르다.
(a) 는 이동 후 회전한 결과이고, (b) 는 회전 후 이동한 결과이다.
instance : 원래 물체를 변환한 물체를 가리켜 '원래 물체의 인스턴스(instance)' 라고 한다.
물체 인스턴스는 컨벤션으로서 크기 조절 → 회전 → 이동 순으로 변환을 가하도록 되어있다.
크기 조절, 회전을 이동보다 먼저하는 이유는, 물체 중심 (피벗)과 좌표계의 원점이 일치한 상태에서 이동을 시키면 원하는대로 회전이 이루어지지 않기 때문이다.
이를 변환행렬로 표현하면 C = T * R * S 로 표현할 수 있다.
(S = 크기 조절, R = 회전, T = 이동)
복합 행렬과 OpenGL 모델링
지금까지 다룬 변환은 전역좌표계 위의 점 P 를 전역좌표계를 기준으로 특정한 변환을 가해서 전역 좌표계 위의 점 P' 으로 나타내는 변환을 다루었다. 즉, 정점을 변환하는 것이었다.
하지만 Open GL 에서의 모든 변환은 전역 좌표계를 기준으로 모델 좌표계를 변환하는 것이다.
즉, 점을 옮기는게 아니라 좌표계를 옮기는 것이다.
점이 아니라 좌표계를 옮기는 이유는 모델링을 할 때, 정점이 전역좌표계가 아닌 모델 좌표계 기준으로 표현되기 때문이다.
따라서 모델 좌표계를 전역 좌표계기준으로 변환하면, 모델 좌표계 기준으로 표현된 점들도 따라서 같이 변환되는 효과가 있다.
강의록의 표현이 이 말이다.
기준 물체의 정점좌표 P는 모델좌표계 위의 점이다.
이 점을 '모델 좌표계를 변환하는 방식의 변환 행렬' 에 곱해주면, 변환 결과 전역 좌표 P' 이 나온다.
이 방식을 사용하는 이유는 지난 글에서 말했듯, 물체를 전역 좌표에 어떻게 배치할지 모르는 상태에서 물체의 정점 좌표를 전역 좌표로 표현할 수 없기 때문에 처음엔 모델 좌표계를 기준으로 아래 이미지와 같이 표현하기 때문이다.
연필과 상자를 전역 좌표계 (World Coordinate System, WCS) 에 배치하기 전에 연필과 상자를 구성하는 정점은 각각 M1, M2 라는 자신들만의 좌표계 방식으로 표현한다.
이 물체를 실제 world 에 배치한 이후에는, 모델 좌표계 기준으로 표현된 정점들을 world 좌표계 기준으로 다시 표현해줘야 한다.
이를 GL 입장에서 보면, '물체를 이동' 하는 것이 아니라, 전역좌표계를 기준으로 '모델 좌표계를 이동' 한 것으로 본다.
모델좌표계 기준으로 표현된 정육면체 정점을 월드에 그리기 위해, WCS 좌표계를 변환행렬 T 를 이용해 MCS 위치로 옮긴다. 이후 이를 기준으로 정육면체를 그린다.
멀티미디어응용수학에서 배웠던 수식으로 작성하면 아래와 같이 표현할 수도 있다.
World 에서 Model 로의 변환 행렬에 모델 좌표 기준의 점을 곱해 World 기준의 점으로 변환한다.
최종적으로 두 방식을 비교하면 위와 같다.
왼쪽은 정점 P를 전역좌표계 기준에 맞게 옮겨서 그리는 것이다.
즉, 물체를 일단 그리고 옮기는 것이다.
오른쪽에서 CTM은 Composite Transformation Matrix 의 줄임말이다.
복합 변환 행렬을 I 라고 하는 기존 좌표계 (단위 행렬) 에 변환을 오른쪽으로 곱해 최종 CTM 을 만든다.
정점을 변환할 때는 이 행렬 오른쪽에 변환하려는 모델좌표계 위의 점을 곱하면 된다.
이 방식은 물체를 그리기 전에 좌표계를 미리 옮겨놓고 그 옮긴 좌표계 위에 점을 그리는 것이다.
아무튼 둘 다 관점의 차이지 결과는 똑같다.
왼쪽은 일단 그려놓고 옮겨야되니까 정점 왼쪽에 변환 행렬을 곱하는 방식이고
오른쪽은 일단 좌표계를 옮겨놔야되니 기존 좌표계(단위행렬) 오른쪽에 변환행렬을 곱한 뒤, 정점을 곱하는 방식이다.
다음 글에서 정리할 예정이지만, OpenGL 은 glm (gl math) 라이브러리를 이용해 변환행렬을 구할 수 있다.
이때 glm은 (OpenGL) 은 후자의 관점(모델 좌표계를 변환하는 관점)에서 접근한다.
그래서 위 이미지처럼 먼저 돌리고 이동한뒤, 그 위에 점을 그려야 한다면
위와 같이 기존 WCS 를 identity 행렬로 표현하고, 여기에 회전, 이동 순으로 변환을 적용 한뒤, 셰이더에 이 행렬을 넘겨서 최종 그릴 정점과 곱하게 시킨다.
이 내용을 이렇게 볼 수 있다.
똑같은 행렬식이 나오지만, 물체 변환(object transformation)의 관점에서 보면 왼쪽에 변환행렬을 곱해나가는 것이고,
좌표계 변환(coordinate transformation)의 관점으로 보면 오른쪽에 변환행렬을 곱해나가는 것이다.
GL은 좌표계 변환 관점으로 복합 변환을 진행하므로, 좌표계변환 방향으로 함수를 실행시켜야 한다.
계층적 모델링 (Hierarchical Modeling)
인체 또는 로봇팔과 같은 다관절 객체를 그릴 때는 계층구조를 설정하는 것이 좋다.
예를 들면, 먼저 몸을 두고, 몸에 윗팔이 붙고, 윗팔 밑에 아랫팔이 붙고, 그 아래 손이 붙는 방식이다.
이렇게 구성하면, 상위 객체에 대해 변환이 발생했을 때, 나머지 종속된 객체도 한꺼번에 모두 변환이 되므로 계산에 유리하다.
이렇게 모델링하려면, 행렬변환을 할 때,
WCS -> 몸통좌표계 -> 상박좌표계 -> 하박좌표계 -> 손좌표계 순으로 변환하는 행렬을 작성하면 된다.
이렇게 몸통부터 손끝까지 차례대로 변환하는 것을 Forward Kinematics (순방향 키네마틱스) 라고 한다.
대충 코드로는 이렇게 구현된다.
'CS > HCI 윈도우즈프로그래밍' 카테고리의 다른 글
[OpenGL] 16. Transformation (4) - 셰이더에 행렬 변환 적용하기 (1) | 2024.04.19 |
---|---|
[OpenGL] 15. Transformation (3) - GLM 사용하기 (0) | 2024.04.19 |
[OpenGL] 13. Transformation (1) - 변환의 기본 개념 (0) | 2024.04.17 |
[OpenGL] 12. Shader (8) - 여러 Texture 생성하기 (0) | 2024.04.14 |
[OpenGL] 11. Shader (7) - Texture Wrapping, Filtering, MipMaps (1) | 2024.04.12 |