✅ 1. 2D vs 3D 애니메이션의 차이점

  • 2D 애니메이션에서는 프레임마다 스프라이트(이미지)를 틀어주는 방식으로 애니메이션을 구현한다.
  • 하지만 3D에서는 각 프레임마다 모델 전체를 교체하는 것은 비효율적이다. 대신 뼈대(Bone)를 기준으로 정점을 변형시키는 방식이 사용된다.
  • 즉, 정점(Vertex)은 고정되어 있고, 이를 이동시키는 기준점으로서의 뼈대가 존재한다.

✅ 2. 본(Bone)과 Transform 계층 구조

▶️ 본의 역할

  • 본(Bone)은 캐릭터의 뼈대를 의미한다. 하나의 본은 캐릭터의 한 부분(예: 팔, 다리 등)을 의미하며, 계층적으로 연결되어 있다.
  • 부모 본의 움직임은 자식 본에 영향을 준다. 예: 어깨를 움직이면 팔과 손도 함께 따라 움직인다.

▶️ Transform 계층 구조

  • 각 본은 Local(자기 기준) 좌표를 갖고 있고, 이들이 SRT(Scale, Rotation, Translation)를 거쳐 Global(전역) 좌표로 바뀌게 된다.
  • 기본 포즈인 T-Pose는 Global 좌표 상태에서 시작된다.
  • 이후 애니메이션 데이터에 따라 본들의 Local Transform이 변형되며 최종 Global Transform이 재계산된다.

✅ 3. 글로벌 <-> 로컬 좌표 변환의 핵심

이 개념이 굉장히 중요하다. 아래 과정을 머릿속에 새겨두자:

T-Pose(Global) → Relative(Local) → 애니메이션 적용(Global)로 변환

  1. Global → Local : 정점을 뼈대 기준으로 변환 (역행렬 사용)
  2. Local → New Global : 애니메이션 데이터를 기반으로 새로운 Global 좌표를 계산

이 구조를 통해 뼈대가 애니메이션으로 움직이면, 정점이 그에 따라 자연스럽게 움직이게 된다.


✅ 4. 정점(Vertex)과 스키닝(Skinning)

▶️ 정점은 고정된 위치를 가진 점이 아니다

  • 애니메이션은 뼈대만 움직이는 게 아니라, 정점들도 본의 움직임에 따라 변화해야 한다.
  • 하지만 정점 하나가 여러 본에 영향을 받을 수 있다. 이때 사용하는 기법이 바로 스키닝(Skinning)이다.

▶️ 스키닝(Skinning)

  • 하나의 정점은 최대 4개의 본에 영향을 받을 수 있다.
  • 각 본은 가중치(Weight)를 가진다. 예: 가슴 정점은 허리 60%, 가슴 40% 본에 영향을 받는다.
  • 최종 위치는 이들 본의 변환행렬에 가중치를 곱해서 더한 값이다.

예시:

finalPos = (BoneMatrix[0] * weight0) + (BoneMatrix[1] * weight1) + ...

이 방식으로 정점 하나가 여러 본의 움직임을 혼합해서 따라가게 된다.


✅ 5. 애니메이션 데이터 구조

▶️ 애니메이션 클립(Animation Clip)

  • 하나의 동작 (예: 걷기, 뛰기, 공격 등)에 해당하는 시간별 본의 위치/회전/스케일 변화 데이터를 담고 있음.
  • 매 프레임마다 본의 Local Transform을 변화시켜 애니메이션을 구현함.

✅ 6. 쉐이더와 애니메이션 적용

📌 HLSL의 핵심 코드

output.position = mul(input.position, BoneTransforms[BoneIndex]); 
output.position = mul(output.position, W); 
output.position = mul(output.position, VP);

📌 데이터 흐름

  1. 정점 정보는 모델 로딩 시 Global 좌표로 주어짐
  2. T-Pose 기준 Global Transform을 역행렬로 변환 → Local 좌표계로 변환
  3. 애니메이션 본 Transform을 계산하여 → 다시 Global로 재변환
  4. 최종 본 Transform에 따라 정점 위치 보정 (스키닝 적용)
  5. 쉐이더에서 최종 위치 계산 후 렌더링

✅ 8. 캐릭터 애니메이션 흐름

  1. 모델을 로딩하면서 본(Bone) 구조와 정점(Vertex) 정보를 가져온다
  2. 정점마다 영향을 주는 본의 인덱스와 가중치를 저장해둔다 (BlendIndices / BlendWeights)
  3. 애니메이션 클립을 로딩하여 본의 시간별 위치 데이터를 저장
  4. 매 프레임마다 본의 위치 정보를 계산 → BoneTransforms에 저장
  5. 쉐이더에서 각 정점의 본 인덱스를 기준으로 BoneTransforms를 적용해 최종 위치 계산
  6. 자연스럽게 애니메이션이 동작!

profile
李家네_공부방

0개의 댓글