🧭 주제
SRT 변환 행렬 완전 정복 – 스케일(Scale), 회전(Rotation), 이동(Translation)을 하나의 행렬로 통합하고, 적용 순서까지 완벽히 이해하기
📚 개념
SRT는 3D 그래픽스에서 객체를 조작하는 가장 기본적이고 핵심적인 세 가지 변환 요소이다.
- S (Scale): 객체의 크기를 조절한다.
- R (Rotation): 객체를 회전시킨다.
- T (Translation): 객체의 위치를 이동시킨다.
이 세 가지 변환은 각각의 4×4 행렬로 구성되며, 이를 순차적으로 곱함으로써 하나의 복합 변환 행렬을 생성할 수 있다. 이 복합 행렬을 벡터에 곱함으로써 단 하나의 연산만으로 다중 변환을 동시에 적용할 수 있다.
이러한 변환들은 단지 시각적 위치 조정 이상의 의미를 가지며, 실제 게임에서는 플레이어, NPC, 오브젝트의 움직임과 연출을 자연스럽게 표현하는 데 필수적으로 사용된다.
특히 적용 순서(S→R→T)는 결과에 직접적인 영향을 주는 매우 중요한 요소이며, 이를 이해하고 정확히 구현해야 원하는 결과를 얻을 수 있다.
🧾 용어 정리
- 행렬(Matrix, M): 변환을 수학적으로 표현한 2차원 배열 구조, 일반적으로 4×4 크기를 사용한다.
- 벡터(Vector, v): 한 점의 위치 또는 방향을 나타내는 배열. 동차 좌표계에서는
[x y z 1] 형식으로 표현한다.
- 동차 좌표계(Homogeneous Coordinates):
[x y z 1] 형식으로 벡터를 확장하여, 이동 연산도 행렬 곱만으로 처리할 수 있도록 만든 좌표계.
- 자전(Self Rotation): 객체 자신을 기준으로 회전.
- 공전(Orbit Rotation): 외부 기준(예: 원점)을 중심으로 회전.
- 좌표계(Coordinate System): DirectX에서는 왼손 좌표계를 사용한다. 이는 Z축이 화면 안쪽(+Z 방향)을 향함을 의미한다.
- 스자이공부(S-R-T 순서 기억법): Scale → 자전(Rotation) → 이동(Translation) → 공전 → 부모 순서로 연산.
💻 코드 분석 (행렬 수식 및 구현 개념)
① Translation – 이동 변환
목적: 객체를 (a, b, c)만큼 이동
수식 설명
벡터:
v = [x y z 1]
행렬:
M = [1 0 0 0
0 1 0 0
0 0 1 0
a b c 1]
연산 결과:
v × M = [x + a, y + b, z + c, 1]
→ 각 좌표에 이동값이 더해짐
핵심: 3×3 행렬로는 불가능한 연산이며, 동차 좌표계(4×4 행렬, 벡터 끝에 1 추가)를 통해 해결함
② Scale – 크기 조절 변환
목적: 각 축 방향으로 비율 조절 (a배, b배, c배)
수식 설명
벡터:
v = [x y z 1]
행렬:
M = [a 0 0 0
0 b 0 0
0 0 c 0
0 0 0 1]
연산 결과:
v × M = [ax, by, cz, 1]
→ 각 축에 대해 독립적으로 크기가 변화됨
중심 위치에 따른 영향
- 중심이 발에 있을 경우: 스케일 확대 시 자연스럽게 위로만 커짐
- 중심이 배꼽에 있을 경우: 위아래가 동시에 늘어나며, 캐릭터의 위치가 흔들리게 되어 어색함
✅ 따라서, 모델링할 때는 발을 중심으로 잡는 것이 일반적이며 안정적이다.
③ Rotation – 회전 변환
목적: 특정 축(X, Y, Z)에 대해 θ 만큼 회전
회전 행렬 수식
Rx(θ) =
[1 0 0 0
0 cosθ -sinθ 0
0 sinθ cosθ 0
0 0 0 1]
Ry(θ) =
[cosθ 0 sinθ 0
0 1 0 0
-sinθ 0 cosθ 0
0 0 0 1]
Rz(θ) =
[cosθ -sinθ 0 0
sinθ cosθ 0 0
0 0 1 0
0 0 0 1]
2D Z축 회전 예시 결과 수식
X = xcosθ - ysinθ
Y = xsinθ + ycosθ
Z = z
원점 기준 회전 vs 비원점 회전
- 객체가 원점에 위치하지 않은 경우, 회전을 하면 자신만 회전하는 것이 아니라 위치도 회전되어 움직인다. 이는 공전과 같은 효과를 낳는다.
- 자전만 원할 경우, 먼저 원점으로 이동 후 회전하고 다시 원위치로 되돌리는 연산이 필요함.
④ SRT 통합 행렬 구성
목적: Scale, Rotation, Translation을 하나의 행렬로 통합하여 효율적인 연산
이유:
- 각각 연산하면 성능/메모리 낭비
- 하나로 합치면 GPU 연산 최적화에 유리
적용 순서 중요:
S → R → T → (공전) → 부모 순으로 곱해야 기대한 결과가 나온다
- 예) T 후 R → 공전처럼 작동 (회전 시 원점이 객체의 현재 위치가 아님)
- 예) R 후 T → 자전처럼 작동 (자기 기준으로 돌고 나서 이동)
✅ 실무에서도 반드시 스자이공부 순서로 구현해야 한다
⑤ 실제 코드 적용 및 구현 방식
개념:
TransformData 같은 구조체에서 S, R, T 정보를 저장
- 이를 기반으로 GPU에서 사용할 4×4 행렬을 구성
- Vertex Shader에서 해당 행렬을
position 벡터에 곱하여 최종 위치 계산
구현 요소:
Matrix 클래스 (4×4 float형 멤버 또는 float[16])
- 생성자(16개 원소 입력 가능)
- 연산 함수 (행렬 × 행렬, 행렬 × 벡터)
CreateScaleMatrix(a,b,c), CreateRotationZ(θ) 등의 팩토리 함수 제공
- DirectXMath 또는 GLM 같은 라이브러리 사용도 가능
🎯 핵심 요약
✅ SRT는 변환의 기본 3요소로, 이를 이해하고 구현하는 것이 3D 그래픽스의 출발점이다.
✅ Translation은 동차 좌표계를 통해만 행렬 곱으로 처리 가능하다.
✅ Scale은 중심이 어디냐에 따라 시각적 결과가 달라지므로, 캐릭터 중심은 반드시 발에 맞춰야 자연스러운 표현이 가능하다.
✅ Rotation은 sin, cos 함수를 이용해 축 별 회전 행렬로 구성된다.
→ 원점이 아닌 위치에서 회전 시 공전 효과가 발생하므로 유의해야 한다.
✅ SRT 적용 순서는 절대적으로 중요하며,
→ 순서가 바뀌면 전혀 다른 결과가 나오므로 반드시 스자이공부 순서(S → R → T → Orbit → Parent)로 곱해야 한다.
✅ 실제 게임 구현에서는 변환 행렬을 직접 만들거나 라이브러리를 활용하여 셰이더에 전달하고, GPU에서 벡터와 곱해 모든 시각적 결과를 도출한다.
좋아요! 업로드하신 “SRT 변환 행렬” 슬라이드를 공부용으로 한 페이지씩 아주 짧고 실전적으로 정리해드릴게요. (필요한 핵심식과 포인트만 넣었습니다.)
페이지별 핵심 요약
- matrix
- 목적: 좌표 변환을 “행렬 × 벡터” 한 방으로 처리.
- 포맷: 동차좌표(4×4 행렬 · [x y z 1]^T) 사용 → 이동/회전/스케일을 모두 포괄.
- Scale / Rotation / Translation (S/R/T) 소개
- S: 크기 변경, R: 방향 변경, T: 위치 변경.
- 실무에서는 보통 “S → R → T” 순서로 적용(로컬→월드 변환 관점).
- 벡터와 행렬
- 점/벡터 = 열벡터로 보고, 변환은 왼쪽에서 4×4 행렬 곱.
- 동차좌표에서 점은 w=1, 방향벡터는 w=0 취급(이동 영향 유/무가 다름).
- Translation 개념
- 좌표를 고정량 (tₓ, tᵧ, t_z)만큼 이동.
- 직관: “모든 점에 동일 벡터 더하기”.
- Translation 예시/행렬
-
변환: (x, y, z) → (X, Y, Z) = (x+tₓ, y+tᵧ, z+t_z).
-
T(tₓ,tᵧ,t_z)=
⎣⎢⎢⎢⎡100001000010tₓtᵧtz1⎦⎥⎥⎥⎤
- 동차좌표(Translation가 되는 이유)
- [x y z 1]^T의 ‘1’이 위 행렬의 마지막 열(이동)을 살림.
- 방향벡터 [vₓ vᵧ v_z 0]^T에는 이동 성분이 적용되지 않음.
- Translation 합성
- T(a)·T(b)=T(a+b) (교환 가능).
- 하지만 T와 R/S는 교환 불가 → 순서 중요!
- Translation 주의점
- 회전·스케일 뒤에 이동하면 “회전 후의 축 기준 위치”가 달라짐.
- 보통 로컬→월드: S → R → T, 스키닝/계층에서는 부모 행렬도 고려.
- Scale 개념
- (x, y, z) → (sₓx, sᵧy, s_z z).
- Uniform(한 값) vs Non-uniform(축마다 다른 값).
- Scale 행렬
-
S(sₓ,sᵧ,s_z)=
⎣⎢⎢⎢⎡sₓ0000sᵧ0000sz00001⎦⎥⎥⎥⎤
- Uniform vs Non-uniform
- Uniform: 회전 후에도 형태 왜곡 없음.
- Non-uniform: 회전과 섞이면 타원/비틀림 등 직관이 어려워짐(노멀 재정규화 필요).
- z 스케일 강조 (1)
- z가 깊이 축일 때 s_z가 원근/깊이 해석에 관여(엔진 좌표계에 따라 의미 다를 수 있음).
- z 스케일 강조 (2)
- 카메라 전/후 클리핑, 깊이 관련 셰이딩에서 s_z의 단위/스케일 주의.
- z 스케일 강조 (3)
- 모델링 단계의 z 스케일이 0에 가깝거나 음수면 뒤틀림/거울상 문제 발생.
- z 스케일 강조 (4)
- 충돌/피직스: 비균등 스케일은 바운딩 계산과 충돌해석에 영향.
- Rotation 개요
- 각도 θ와 축(또는 평면)을 기준으로 회전.
- 행렬 R는 직교행렬(역행렬=전치, det=+1).
- 기호 R, 성질
- R⁻¹=Rᵀ, ||Rv||=||v|| (길이 보존).
- 연속 회전 합성: R₂·R₁ (순서 바뀌면 결과 달라짐 → 비가환).
- 축별 기본 회전
- Rₓ(θ), Rᵧ(θ), R_z(θ) 세 축 회전이 기본 빌딩블록.
- 임의 축 회전은 로드리게스 공식 등으로 구성 가능.
- Z축 회전 행렬
-
R_z(θ)=
⎣⎢⎢⎢⎡cosθsinθ00−sinθcosθ0000100001⎦⎥⎥⎥⎤
- 좌/우수계와 회전 부호
- 우수계(Right-handed) vs 좌수계(Left-handed)에서 θ 부호/회전 방향 차이 주의.
- 사용 엔진(예: OpenGL/DirectX/Unity/Unreal)의 좌표계 규약 확인 필수.
- z 회전 복습 (1)
- 평면( x–y )에서 z축 회전은 2D 회전과 동일:
[X Y]^T = [ [c −s],[s c] ] · [x y]^T.
- z 회전 복습 (2)
- 회전 합성: R_z(α)·R_z(β)=R_z(α+β).
- 그러나 R_z와 Rₓ/Rᵧ는 교환 불가.
- SRT 합성 & Parent(계층)
원하시면 위 내용을 **한 장짜리 치트시트(PDF)**로 정리해서 만들어 드릴게요! 또, DirectX/Unreal/Unity 중 하나를 골라 좌표계/행렬 곱 규약까지 딱 맞춘 실습 예제도 바로 준비해 드릴 수 있어요.