티스토리 뷰
이번에는 3D 캐릭터 스켈레톤 애니메이션에 대해서 얘기해볼까 합니다.
앞으로 이어지는 포스팅에서 컴퓨터를 이용해 3D 캐릭터 애니메이션을 구현하는 방식을 개괄적으로 설명하고 기반이 되는 수학적 지식과 간단한 샘플 코드를 보여드리겠습니다.
*참고로 본 포스팅은 그래픽스 프로그래밍을 하는 프로그래머를 위한 포스팅입니다.
따라서 마야나 블렌더 등 3D 툴을 이용해 캐릭터 애니메이션을 만드는 작업에 대해서는 설명하지 않습니다.
샘플 코드에서는 이미 만들어진 캐릭터 애니메이션 파일(.dae)을 Assimp로 읽어서 OpenGL을 이용해 랜더링할 것입니다.
목표
먼저 아래와 같이 3D 캐릭터가 뛰어가는 영상을 만들고 싶다고 해봅시다.
출처: https://giphy.com/gifs/character-animation-mjLzRdQl5oV6U
해결법1
컴퓨터 그래픽스를 해 본 여러분이라면 위 캐릭터가 정점과 삼각형 평면들로 이루어진 3D 객체라는 것을 알고 계실 것입니다.
그렇다면 과연 어떻게 이 캐릭터가 뛰어가는 영상을 만들까요? 가장 직관적으로 느껴지는 해결법은 바로 매 프레임 마다 캐릭터의 정점들을 옮긴 값들을 저장하고 저장한 정점 값대로 캐릭터를 랜더링하여 영상을 만들어내는 것입니다.
문제점1
물론 가능한 이야기지만 뛰어가는 모션을 만들기 위해 얼마나 많은 노력이 들어가야할지 안 봐도 훤합니다.
모든 프레임의 정점 값을 저장하는 것 대신 특정 프레임들의 정점 값만 저장하고 사이 프레임들은 보간하는 방식을 쓴다해도 매우 많은 작업이 필요할 것입니다.
예를 들어 1000개의 정점을 가진 캐릭터로 150프레임의 애니메이션을 위해 각 10번째 프레임에서의 정점 값을 저장한다고 생각해봅시다.
단순 계산만으로도 최대 1000x(150/10)=15000번의 마우스질이 필요합니다.
문제점2
사실 해결법1의 더 큰 문제점은 바로 이렇게 많은 마우스질을 통해 저장한 정점 값이 굉장히 부자연스러운 움직임일 수 있다는 것입니다.
3D 사람 캐릭터의 피부를 삼각형을 이루는 정점들의 집합이라고 생각했을 때 캐릭터가 움직일 경우 이 정점들의 위치가 어떻게 결정되는지 생각해봅시다.
왼팔을 드는 행동을 취한다고 해봅시다. 왼팔을 듦에 따라 왼손을 이루던 정점들, 왼쪽 전완과 상완을 이루는 정점들은 따라 움직일 것입니다. 이 정점들을 제외한 제외한 나머지 정점들은 움직이지 않습니다.
이번에는 왼팔의 팔꿈치를 굽히는 행동을 취한다고 해봅시다.
역시 왼손을 이루던 정점들, 왼쪽 전완을 이루는 정점들은 따라 움직일 것입니다.
나머지는 움직이지 않죠.
마지막으로 왼쪽 손목을 굽힐 경우 왼손을 이루던 정점들만 움직이게 됩니다.
이처럼 정점들은 관절의 구조에 따라 나름의 규칙을 가지고 움직입니다. 해결법1 같은 경우는 관절에 대한 정보 없이 사람이 임의로 정점의 위치를 결정하기 때문에 부자연스러운 움직임이 만들어 질 수 있습니다.
해결법2
해결법1의 문제들을 해결하는 방법은 캐릭터 애니메이션의 규칙을 파악하고 제대로 활용할 수 있는 추가적인 데이터를 만드는 것입니다.
그것은 바로 뼈대 데이터입니다.
각 정점들을 하나의 뼈대에 속하게 하고 뼈대가 움직여야만 움직이도록 하면 되기 때문입니다.
또 뼈대를 계층구조로 만들면 원하는 정점들만 움직이도록 할 수 있습니다.
상완 뼈를 움직이면 상완 뼈에 속한 정점들은 모두 움직이고
상완 뼈의 자식인 전완 뼈에 속한 정점들 역시 모두 움직이게 하면 되기 때문입니다.
전완 뼈가 움직일 때는 상완 뼈가 전완 뼈의 자식이 아니므로 상완 뼈에 속한 정점들은 움직이지 않습니다.
하지만 아직 주의해야할 것이 하나 있습니다.
그것은 바로 관절 부분에 속한 정점들은 조금 다른 규칙을 가진다는 것입니다.
예를 들어 팔꿈치 부분에 있는 정점에 대해 생각해봅시다. 어깨를 돌려 상완을 움직일 경우 이 정점은 움직입니다. 그 외에도 팔꿈치를 굽혀 전완을 움직일 경우 피부가 전완에 따라 움직이게 됩니다.
하지만 자세히 살펴보면 손 쪽에 가까운 피부일수록 전완 움직임의 영향을 많이 받고 어깨 쪽의 가까운 피부일수록 전완 움짐임의 영향을 적게 받습니다. 하나의 정점이 두 개의 뼈대의 움직임에 영향을 받는 것이지요.
게다가 영향을 받는 비율도 조금씩 다른겁니다.
이 부분도 신경써서 구현해야 자연스러운 애니메이션을 구현할 수 있습니다.
마지막으로 지금까지 나온 내용에 따라 용어정리를 한 번 하자면
캐릭터의 피부를 이루는 정점 및 삼각형들을 메쉬(Mesh),
캐릭터가 취하는 움직임의 기반이 되고 정점들의 움직임에 영향을 끼치는 것을 뼈대(Bone),
Mesh와 Bone을 이용해 캐릭터의 움직임을 구현하는 것을 스켈레톤 애니메이션(Skeletal Animation)이라고 합니다.
다음 두 개의 포스팅에는 Skeletal Animation을 구현하기 위한 수학적 지식인 Transformation에 대해서 설명드리겠습니다.
'프로그래밍' 카테고리의 다른 글
Unreal을 이용한 CelShading (0) | 2020.10.02 |
---|---|
Unreal Blueprint를 이용해 직접 만든 DLL 사용하기 (0) | 2019.12.25 |
언리얼 HLSL을 이용한 Custom Shader 제작 (1/2) (1) | 2019.11.29 |
Unreal4를 이용한 Camera 제어 무작정 시작하기 (0) | 2019.10.11 |
OpenGL 및 Assimp를 활용한 스켈레톤 애니메이션 프로그래밍 (3/3) (0) | 2019.08.31 |
- Total
- Today
- Yesterday
- Mesh Processing
- 유니티
- value type
- RubiksCube
- Unity
- batching
- RL
- NDC
- dynamic batching
- static batching
- collision detection
- Mesh
- SRP
- VTK
- Unreal
- 값 형식
- perspective projection
- Scriptable Render Pipeline
- opengl
- AABB
- 루빅스큐브
- normalized device coordinate
- C#
- reference type
- 강화학습
- transform
- CollisionDetection
- MeshProcessing
- Transformation
- 참조 형식
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |