🧭 주제

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)에 대해 θ 만큼 회전

회전 행렬 수식

  • X축 기준:
Rx(θ) =
[1     0        0     0
 0  cosθ  -sinθ  0
 0  sinθ   cosθ  0
 0     0      0     1]
  • Y축 기준:
Ry(θ) =
[cosθ   0   sinθ   0
   0     1     0    0
 -sinθ   0   cosθ   0
   0     0     0    1]
  • Z축 기준:
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 변환 행렬” 슬라이드를 공부용으로 한 페이지씩 아주 짧고 실전적으로 정리해드릴게요. (필요한 핵심식과 포인트만 넣었습니다.)

페이지별 핵심 요약

  1. matrix
  • 목적: 좌표 변환을 “행렬 × 벡터” 한 방으로 처리.
  • 포맷: 동차좌표(4×4 행렬 · [x y z 1]^T) 사용 → 이동/회전/스케일을 모두 포괄.
  1. Scale / Rotation / Translation (S/R/T) 소개
  • S: 크기 변경, R: 방향 변경, T: 위치 변경.
  • 실무에서는 보통 “S → R → T” 순서로 적용(로컬→월드 변환 관점).
  1. 벡터와 행렬
  • 점/벡터 = 열벡터로 보고, 변환은 왼쪽에서 4×4 행렬 곱.
  • 동차좌표에서 점은 w=1, 방향벡터는 w=0 취급(이동 영향 유/무가 다름).
  1. Translation 개념
  • 좌표를 고정량 (tₓ, tᵧ, t_z)만큼 이동.
  • 직관: “모든 점에 동일 벡터 더하기”.
  1. Translation 예시/행렬
  • 변환: (x, y, z) → (X, Y, Z) = (x+tₓ, y+tᵧ, z+t_z).

  • T(tₓ,tᵧ,t_z)=

    [100t010t001tz0001]\begin{bmatrix} 1&0&0&tₓ\\ 0&1&0&tᵧ\\ 0&0&1&t_z\\ 0&0&0&1 \end{bmatrix}
  1. 동차좌표(Translation가 되는 이유)
  • [x y z 1]^T의 ‘1’이 위 행렬의 마지막 열(이동)을 살림.
  • 방향벡터 [vₓ vᵧ v_z 0]^T에는 이동 성분이 적용되지 않음.
  1. Translation 합성
  • T(a)·T(b)=T(a+b) (교환 가능).
  • 하지만 T와 R/S는 교환 불가 → 순서 중요!
  1. Translation 주의점
  • 회전·스케일 뒤에 이동하면 “회전 후의 축 기준 위치”가 달라짐.
  • 보통 로컬→월드: S → R → T, 스키닝/계층에서는 부모 행렬도 고려.
  1. Scale 개념
  • (x, y, z) → (sₓx, sᵧy, s_z z).
  • Uniform(한 값) vs Non-uniform(축마다 다른 값).
  1. Scale 행렬
  • S(sₓ,sᵧ,s_z)=

    [s0000s0000sz00001]\begin{bmatrix} sₓ&0&0&0\\ 0&sᵧ&0&0\\ 0&0&s_z&0\\ 0&0&0&1 \end{bmatrix}
  1. Uniform vs Non-uniform
  • Uniform: 회전 후에도 형태 왜곡 없음.
  • Non-uniform: 회전과 섞이면 타원/비틀림 등 직관이 어려워짐(노멀 재정규화 필요).
  1. z 스케일 강조 (1)
  • z가 깊이 축일 때 s_z가 원근/깊이 해석에 관여(엔진 좌표계에 따라 의미 다를 수 있음).
  1. z 스케일 강조 (2)
  • 카메라 전/후 클리핑, 깊이 관련 셰이딩에서 s_z의 단위/스케일 주의.
  1. z 스케일 강조 (3)
  • 모델링 단계의 z 스케일이 0에 가깝거나 음수면 뒤틀림/거울상 문제 발생.
  1. z 스케일 강조 (4)
  • 충돌/피직스: 비균등 스케일은 바운딩 계산과 충돌해석에 영향.
  1. Rotation 개요
  • 각도 θ와 축(또는 평면)을 기준으로 회전.
  • 행렬 R는 직교행렬(역행렬=전치, det=+1).
  1. 기호 R, 성질
  • R⁻¹=Rᵀ, ||Rv||=||v|| (길이 보존).
  • 연속 회전 합성: R₂·R₁ (순서 바뀌면 결과 달라짐 → 비가환).
  1. 축별 기본 회전
  • Rₓ(θ), Rᵧ(θ), R_z(θ) 세 축 회전이 기본 빌딩블록.
  • 임의 축 회전은 로드리게스 공식 등으로 구성 가능.
  1. Z축 회전 행렬
  • R_z(θ)=

    [cosθsinθ00sinθcosθ0000100001]\begin{bmatrix} \cos\theta&-\sin\theta&0&0\\ \sin\theta&\cos\theta&0&0\\ 0&0&1&0\\ 0&0&0&1 \end{bmatrix}
  1. 좌/우수계와 회전 부호
  • 우수계(Right-handed) vs 좌수계(Left-handed)에서 θ 부호/회전 방향 차이 주의.
  • 사용 엔진(예: OpenGL/DirectX/Unity/Unreal)의 좌표계 규약 확인 필수.
  1. z 회전 복습 (1)
  • 평면( x–y )에서 z축 회전은 2D 회전과 동일:
    [X Y]^T = [ [c −s],[s c] ] · [x y]^T.
  1. z 회전 복습 (2)
  • 회전 합성: R_z(α)·R_z(β)=R_z(α+β).
  • 그러나 R_z와 Rₓ/Rᵧ는 교환 불가.
  1. SRT 합성 & Parent(계층)
  • 보통 로컬→월드: M = T · R · S (열벡터/우곱 관례).

    • 반대로 행벡터/좌곱 관례라면 표기가 바뀜. 핵심은 “적용 순서”가 S→R→T라는 점.
  • 계층: M_world = M_parent · M_local. 부모 변환이 자식에 누적.


원하시면 위 내용을 **한 장짜리 치트시트(PDF)**로 정리해서 만들어 드릴게요! 또, DirectX/Unreal/Unity 중 하나를 골라 좌표계/행렬 곱 규약까지 딱 맞춘 실습 예제도 바로 준비해 드릴 수 있어요.

profile
李家네_공부방

0개의 댓글