이전 글에서는 회전 변환 행렬(Rotation Matrix)이 왜 중요한지를 살펴보았습니다.
회전은 객체의 방향 자체를 변경하는 공간 변환이며, 이러한 회전을 계산하기 위해 삼각함수와 행렬이 함께 사용된다는 점도 알아보았습니다.
이번에는 또 다른 중요한 변환인 스케일 변환 행렬(Scale Matrix)을 살펴보려고 합니다.
게임 안에는 크기가 서로 다른 수많은 객체가 존재합니다.
같은 모델이라도 어떤 것은 크게 보이고, 어떤 것은 작게 보입니다.
캐릭터가 거대화되거나 축소되는 효과가 등장하기도 하고, UI 애니메이션에서는 버튼이 커졌다가 작아지는 연출이 자주 사용됩니다.
그리고 이러한 크기 변경 역시 행렬(Matrix)을 통해 계산됩니다.
위치, 회전만큼 크기 변경도 중요
게임을 만들 때 모델링 툴에서 제작한 크기를 그대로 사용하는 경우가 많습니다.
하지만 게임 개발 과정에서 객체 크기를 실시간으로 변경해야 하는 상황이 자주 발생합니다.
예를 들어 같은 나무 모델을 사용하더라도 어떤 나무는 크게 배치하고 어떤 나무는 작게 배치할 수 있습니다.
몬스터 역시 같은 모델을 사용하면서 보스 몬스터만 더 크게 만들 수 있습니다.
UI 시스템에서도 버튼을 선택했을 때 살짝 확대되는 효과를 자주 사용합니다.
즉, 객체 크기를 자유롭게 조절할 수 있어야 같은 리소스를 다양한 방식으로 활용할 수 있습니다.
이러한 크기 변경 과정을 수학적으로 처리하는 것이 바로 스케일 변환(Scaling)입니다.
스케일은 벡터의 길이를 변경한다
회전은 방향만 바꾸고 길이는 유지했습니다.
반대로 스케일은 방향은 유지하면서 길이를 변경합니다.
예를 들어 아래와 같은 벡터를 생각해보겠습니다.
(1, 0)
이 벡터는 X축 방향으로 길이가 1인 벡터입니다.
여기에 2배 스케일을 적용하면 다음과 같은 결과가 됩니다.
(2, 0)
방향은 그대로 유지되지만 길이가 두 배가 됩니다.
반대로 0.5배 스케일을 적용하면 길이는 절반이 됩니다.
(0.5, 0)
즉, 스케일은 벡터의 크기를 확대하거나 축소하는 변환이라고 볼 수 있습니다.

2D 스케일 행렬
2D 공간에서 사용하는 스케일 행렬은 아래와 같은 형태를 가집니다.
(x, y) * | Sx 0 | = (x * Sx, y * Sy)
| 0 Sy |
여기서 Sx는 X축 스케일 값을 의미하고 Sy는 Y축 스케일 값을 의미합니다.
만약 아래와 같은 행렬을 사용한다면
(1, 1) * | 2 0 | = (1 * 2, 1 * 2) = (2, 2)
| 0 2 |
객체는 모든 방향으로 두 배 커지게 됩니다.
반대로
(1, 1) * | 2 0 | = (1 * 2, 1 * 1) = (2, 1)
| 0 1 |
과 같은 행렬을 사용하면 X축 방향만 두 배 늘어나게 됩니다.
즉, 스케일 행렬은 각 축 방향의 크기를 독립적으로 제어할 수 있습니다.
3D 공간에서는 어떻게 될까
3D 공간에서도 원리는 동일합니다.
다만 X축과 Y축뿐 아니라 Z축까지 포함됩니다.
그래서 3D 스케일 행렬은 아래와 같은 형태를 가집니다.
| Sx 0 0 | | 0 Sy 0 | | 0 0 Sz |
예를 들어
Scale = (2, 1, 1)
이라면 객체는 X축 방향으로만 두 배 커집니다.
반대로
Scale = (1, 3, 1)
이라면 Y축 방향으로만 세 배 늘어나게 됩니다.
게임 엔진에서 흔히 볼 수 있는 Transform Scale 값 역시 이러한 원리를 기반으로 동작합니다.
Unity의 Transform Scale이나 Unreal Engine의 Relative Scale 3D 역시 결국 스케일 행렬을 생성하기 위한 데이터입니다.
음수 스케일은 무엇을 의미할까
스케일 값은 반드시 양수일 필요는 없습니다.
예를 들어 X축에 -1 스케일을 적용하면 객체가 좌우 반전됩니다.
Scale = (-1, 1, 1)
2D 게임에서 캐릭터가 왼쪽을 바라볼 때 스프라이트를 뒤집는 방식으로 사용되는 경우가 많습니다.
3D 공간에서도 모델을 반전시키는 효과를 만들 수 있습니다.
다만 음수 스케일은 법선 방향이나 삼각형의 면 방향에 영향을 줄 수 있기 때문에 렌더링 과정에서 추가 처리가 필요할 수 있습니다.
그래서 실무에서는 음수 스케일 사용 시 주의가 필요합니다.
게임 엔진과 스케일 계산
게임 엔진 안에서는 스케일 계산 역시 매우 자주 사용됩니다.
레벨 디자이너는 동일한 오브젝트를 다양한 크기로 배치합니다.
애니메이션에서는 캐릭터가 커지거나 작아지는 연출이 사용됩니다.
UI 시스템에서는 마우스를 올렸을 때 버튼이 확대되는 효과가 등장합니다.
파티클 시스템에서는 시간이 지남에 따라 입자의 크기가 변화합니다.
즉, 크기가 변하는 거의 모든 상황이 스케일 계산과 관련되어 있습니다.
그래서 스케일 행렬 역시 이동 행렬과 회전 행렬만큼 중요한 기본 변환 중 하나라고 할 수 있습니다.
마무리
스케일 변환 행렬(Scale Matrix)은 객체의 크기를 변경하기 위해 사용하는 핵심 행렬입니다.
회전이 방향을 변경하고 이동이 위치를 변경한다면, 스케일은 객체의 크기를 변경합니다.
게임 엔진 안에서는 레벨 배치와 애니메이션, UI 효과, 파티클 시스템 등 다양한 기능이 스케일 계산과 연결되어 있습니다.
그리고 실제 게임 엔진에서는 이동과 회전, 스케일을 각각 따로 계산한 뒤 하나의 행렬로 결합해서 사용합니다.
다음 글에서는 이동 행렬과 회전 행렬, 스케일 행렬이 어떻게 하나로 합쳐지는지,
그리고 게임 엔진에서 자주 등장하는 월드 행렬(World Matrix)이 왜 중요한지를 이어서 살펴보겠습니다.