10. 디렉터 희망 사항
• 애니메이션에 의한 표현의 제약을 최소화
“비탈길에서 애니메이션이 어색해 보이니 바닥을 최대한 평평하게 해주세요.”
“용 날개는 반드시 한 쌍이어야 합니다.“
“다리가 6개가 넘는 몬스터는 만들 수 없어요.”
• 몬스터가 추가될 때의 애니메이션 제작 비용을 최소화
• {걷기, 뛰기} * {평지, 경사면} * {전, 후, 좌, 우, 대각선 4방향} * …
• 왼쪽으로 회전, 오른쪽으로 회전, …
• 사실감 있게 몬스터를 표현하려면 대량의 애니메이션 어셋이 필요하다.
11. 해결 방법
• 절차적 애니메이션 기법을 사용해서 필요한 모션을 실시간 생성
• 업계에서 이미 오래전부터 사용 중
GTA4(2008)
21. 발견한 문제점
• 애니메이션 품질이 프로그래머 역량에 너무 의존한다
• 프로그래머가 센스를 발휘해서 모션의 핵심을 코드로 구현해야 한다.
• 애니메이션 아티스트가 손볼 수 있는 영역이 극히 제한적이다.
• 모션 결과가 불안정
• 코드가 변경되었을 때 모션이 크게 달라질 수 있다.
• 의도하지 않은 모션 변경을 감지하기 어렵다
22. UE4의 애니메이션 시스템
• 복잡한 노드 그래프와 스테이트 머신
• 토할 것 같은 블루프린트 노드의 향연…
• 그러나 품질이 좋기 때문에 극복 가능한 수준
• 대부분 인간형 캐릭터
• 4족보행 하거나 비행하는 캐릭터에 대한 참고 자료를 찾기 어렵다.
Paragon 애니메이션 블루프린트
(Bringing a Hero from Paragon to Life with UE4 발표 자료 일부 발췌)
24. 새 시스템의 목표
• 다양한 캐릭터를 표현할 수 있어야 한다.
• 4족 보행하는 캐릭터, 날개가 달린 캐릭터, …
• 제작비용이 낮아야 한다.
• 프로그래머 1명이 개발
• 애니메이션 아티스트가 쉽게 제어할 수 있어야 한다.
• 설정할 파라메터가 수백개면 곤란
• 프로그래밍 지식이 없어도 다룰 수 있어야 함
25. 우리의 선택
• 준 절차적인(Semi-Procedural) 애니메이션 시스템
• 샘플 모션을 분석해서 필요한 모션을 실시간 생성
• “앞으로 걷기” 모션으로부터 다음과 같은 모션을 만든다.
“옆으로 걷기”
“천천히 걷기”
“빨리 걷기”
• Rune Skovbo Johansen의 ‘Automated Semi-Procedural Animation
for Character Locomotion’ 논문을 바탕으로 함
33. SME 기본 요소
• 본(Bone, 뼈대)
• 애니메이션 시스템에서 다루는 가장 기본 요소
• 동물의 뼈대에 해당
34. SME 기본 요소
• 스파인(Spine, 척추)
• 계층 구조상 본의 조상에 해당
• 물리 시뮬레이션의 대상
• SME는 이것을 컨트롤(Control)이라고 부른다.
35. SME 기본 요소
• 조인트(Joint, 관절)
• 스파인 사이에 위치하여 스파인 사이를 연결
• 스파인의 움직임을 제한
36. SME 기본 요소
• 림(Limb, 팔다리)
• 스파인에 붙어있는 본 계층구조
• 팔, 다리, 날개 등
• 머리는 림이 아니라 스파인에 해당
37. SME 기본 요소
• 캐릭터
• 본, 스파인, 림 모두를 합친 몸 전체
• 독립적인 객체로 각 모듈의 업데이트를 책임진다.
38. 캐릭터 설정
• 모션 분석 및 런타임 처리를 위한 준비 작업
• 스켈레톤 트리에서 사용할 본을 선택
• 스파인, 조인트, 림을 설정
39. 모션 분석 개요
• 애니메이션 트랙 생성
• 컨트롤과 림의 포즈를 샘플링해서 애니메이션 트랙을 생성
• 생성한 트랙은 런타임 모션과 섞여서 재생된다.
• 림 사이클 분석
• 모션 분석의 가장 핵심 단계
• 각 림의 런타임 모션 생성을 위한 속성을 추출
샘플 데이터
애니메이션 트랙 림 사이클
런타임 모션 생성
모션 분석
40. 모션 분석 개요
• 샘플 데이터를 독립적으로 분석한다.
• 샘플 사이의 연관성을 고려하지 않는다.
• 대량의 데이터를 분석해서 결과를 최적화하지 않는다.
• 이동 모션 위주로 설명
• 이동 모션이 가장 중요하기 때문
41. 분석 가능한 샘플 데이터
• 반복되는 애니메이션
• 첫 포즈와 마지막 포즈가 일치해야 한다.
• 사이클이 오직 1개만 존재
• 같은 모션이 반복해서 등장하면 안된다.
• 루트 모션(Root Motion)이 없어야 한다.
• 즉, 제자리걸음을 하고 있어야 한다.
42. 애니메이션 트랙 생성
• 샘플링한 포즈를 키프레임 단위로 생성
• 시간은 [0, 1]로 정규화
• 각 본의 참조 포즈(Reference Pose)에 대한 상대 변환을 저장
• GlobalRefPose = LocalRefPose * ParentGlobalRefPose
• GlobalSamplePose = AnimPose * LocalRefPose * ParentGlobalSamplePose
• 런타임에 참조 포즈가 변형되면 애니메이션도 같이 변형된다.
43. 애니메이션 트랙 생성
• 스파인과 림의 애니메이션 트랙을 각각 생성
• 스파인과 림의 런타임 처리가 서로 다르기 때문
스파인 트랙
림 트랙
림 트랙
44. 트위스트 성분 제거
• 스파인의 축방향 회전(트위스트)은 허용하지 않는다.
• 트위스트가 없으면 스파인 물리 시뮬레이션 과정이 간단하다.
• 이 처리를 Swing–Twist Decomposition이라고 부른다.
• 회전을 스윙과 트위스트로 분해한 다음 트위스트를 버린다.
45. 다리 사이클 분석
• 키 타임(Key Time) 분석
• 걸음걸이의 주요 이벤트 시간을 찾는다.
• 보폭과 속력 계산
• 키 타임으로부터 각 다리의 보폭과 속력을 계산
• 발의 비행 경로 분석
• 발이 땅에서 떨어져 있는 구간에 대한 발 경로 분석
46. 다리 사이클 분석
• 각 다리 단위로 분석 후 통합
• 캐릭터의 속력을 계산
• 키 타임 정규화(Normalization)
47. 다리 사이클 키 타임
• 스탠스 타임(Stance Time)
• 발 전체를 지면에 붙이고 서 있는 가장 자연스러운 자세
48. 다리 사이클 키 타임
• 다리 사이클: 스탠스 시간에서 다음 스탠스 시간까지의 구간
Stance FootLift FootOff FootStrike FootLand Stance
49. 다리 사이클 키 타임
• 풋리프트 타임(FootLift Time)
• 뒷꿈치를 들기 시작하는 시간
• SME는 이 이벤트를 사용하지 않는다.
50. 다리 사이클 키 타임
• 풋오프 타임(FootOff Time)
• 발 전체가 지면에서 떨어지는 시간
51. 다리 사이클 키 타임
• 풋스트라이크 타임(FootStrike Time)
• 발이 지면에 닿기 시작하는 시간
52. 다리 사이클 키 타임
• 풋랜드 타임(FootLand Time)
• 발이 완전에 지면에 밀착된 시간
• 이 시간 역시 사용하지 않는다.
53. 다리 사이클 키 타임
• 발 미끄러짐 현상을 줄이기 위해서 풋오프와 풋스트라이크만 사용
• 발을 되도록 지면에 붙여 둔다.
• 합성한 모션의 보폭이 샘플 데이터보다 커지는 부작용이 있다.
54. 키 타임 탐색
• 매우 휴리스틱하게 찾는다.
• 발 높이, 발 경로의 곡률 등을 사용
• 샘플 데이터에 힌트를 붙여서 정확도를 높이는 방법을 고려 중
• 풋스트라이크는 풋오프와 동일한 방법으로 찾을 수 있다.
• 풋오프 탐색 알고리즘을 역방향으로 수행하면 풋스트라이크를 얻는다.
스탠스 풋오프 스탠스풋스트라이크
시간
발높이
55. 보폭과 속력
• 보폭(Step Length)이란?
• 멀리뛰기 모션의 보폭은?
• 다리가 하나일 때의 보폭은?
• 보폭 = 풋오프 타임과 풋스트라이크 타임의 발 위치 차이의 길이
• 이동거리와 보폭은 다르다.
• 다리 단위로 보폭을 계산하므로 다리마다 보폭이 다를 수 있다.
57. 보폭과 속력
• 각 다리의 속력을 계산한다.
• LegSpeed = StepLength / (AnimLength - (FootStrikeTime – FootOffTime))
• 이동 시간이 FootStrikeTime – FootOffTime 이 아님에 주의할 것
• 캐릭터의 속력은 각 다리 속력의 평균으로 추정
• 캐릭터가 등속으로 움직인다고 가정
풋스트라이크 스탠스 풋오프
보폭 시간
58. 보폭과 속력
• 캐릭터 속력으로 각 다리의 키 타임을 보정해서 보폭을 유지
• AdjustScale = StepLength / ((AnimLength – (FootStrikeTime – FootOffTime)) * CharSpeed)
• NewFootOffTime = FootOffTime * AdjustScale
• NewFootStrikeTime = AnimLength - (AnimLength – FootStrikeTime) * AdjustScale
• 보정된 키 타임과 애니메이션이 일치하도록 처리해야 함
• ‘애니메이션 타임워프’라 불리는 처리가 필요
• 이후 슬라이드에서 설명
59. 키 타임 정규화
• 애니메이션 길이를 1.0으로 리스케일
• 키 타임 시간을 애니메이션 길이로 나눈다.
• 가장 먼저 등장하는 스탠스 시간이 0.0이 되도록 모든 다리의 키타임을 움직인다.
이동 전
이동 후
왼발
오른발
왼발
오른발
60. 발의 비행 경로 분석
• 풋오프와 풋스트라이크 사이의 발 경로를 저장
• 애니메이션 트랙 형식으로 발 위치를 저장한다.
• 기준선에 대한 상대위치를 저장
• 기준선: 풋오프 위치와 풋스트라이크 위치를 양 끝점으로 하는 선분
• 기준선과의 위치 차이를 보폭으로 나눈 벡터를 저장한다.
• 다양한 속력에서 샘플 데이터에 최대한 근접한 모션을 생성
62. 스탠스 포즈
• 림이 부착된 스파인에 대한 스탠스 위치
• 스파인 좌표계에서 스탠스 타임의 발 위치
• 런타임에서 발자국 위치를 결정할 때 사용
• 정지 상태일 때의 발 위치는 스탠스 포즈로 알 수 있다.
• 스파인 애니메이션에 맞춰서 스탠스 포즈를 애니메이션 트랙으로 저장한다.
64. 로코모션 개요
• 캐릭터의 이동 처리
• 캐릭터의 움직임을 SME가 어떻게 처리하고 있는지 설명
• 발걸음
• 다리 림의 발 위치를 계산하는 방법
• 이동 애니메이션 처리
• 모션 분석에서 생성한 애니메이션 트랙을 적용하는 과정을 설명
65. 캐릭터의 이동
• SME는 외부의 움직임에 대한 반응을 생성하는 시스템
• 외부 객체(UE4의 액터)가 위치, 각도 변화를 SME에 전달한다.
• SME는 그 움직임에 대응하는 모션을 생성
현재 트랜스폼, 경과시간
액터 SME
캐릭터 포즈
66. 캐릭터의 이동
• 액터의 로컬 좌표계에서 처리한다.
• 캐릭터는 액터의 로컬 좌표계에서 움직인다.
• 즉, 제자리걸음하고 있다.
• 액터의 움직임이 두 번 적용되지 않도록 한다.
• 액터 자체도 움직이고 그 안의 캐릭터도 움직이면 같은 이동이 두 곳에서 처리된다.
• 캐릭터에 적용하는 액터의 움직임을 델타 트랜스폼이라고 한다면,
• 인버스 델타 트랜스폼이 필요하다.
67. 캐릭터의 이동
액터의 움직임 델타 트랜스폼 안버스 델타 트랜스폼
• 인버스 델타 트랜스폼
• 캐릭터의 포즈는 그대로 유지하고 위치만 다시 돌려놓는다.
68. 캐릭터의 이동
• 스파인은 로프 시뮬레이션과 비슷하게 처리
• 대표 스파인에 델타 트랜스폼을 적용한다.
• 조인트 제한조건을 만족하도록 나머지 스파인을 움직인다.
69. 발걸음
• 다리 사이클을 재생
• 풋오프 타임에 발을 들고 풋스트라이크 타임에 발을 땅에 붙인다.
• 발을 들고 있는 동안의 발 위치는 발 비행 경로를 따른다.
• 다리 사이클은 속력에 상관없이 항상 재생됨
• 정지 상태에서도 다리 사이클은 돌고 있다.
• 보폭은 속력에 영향을 받는다: 정지 상태에서 보폭은 0이다.
• 출발할 때 어느 다리가 먼저 나갈지 정의되어 있지 않다.
70. 발걸음
• 현재 발자국과 다음 발자국이 필요
• 현재 발자국: 현재 딛고 있거나 발을 들기 시작한 위치
• 다음 발자국: 다음에 딛을 발자국
• 발자국 교체
• 발을 딛고 나면 사용하던 다음 발자국이 현재 발자국이 된다.
71. 발걸음
• 다음 발자국 계산
• 다음 발자국 위치는 현재 스탠스 위치에서 사이클의 남은 시간 동안 이동한 거리를 더해서 얻는다.
• 현재 스탠스 위치는 다리의 스파인과 스탠스 포즈 트랙으로부터 얻을 수 있다.
t1
S(t1)
S(t2)
S(t3)
S(t4)
S(t5)
S(t6)
다음 발자국
t2
t3
t4
t5
t6
t7
S(t7)
72. 발걸음
• 다음 발자국은 발을 들고 있을 때 계산
• 발이 지면에 붙어있을 때 발자국 위치를 바꾸면 발이 미끄러진다.
• 속력이 바뀔 수 있으므로 매 프레임 다음 발자국을 계산한다.
• 발자국을 지면에 붙이기
• 발자국 위치에서 지면 방향으로 레이캐스팅해서 발자국을 지면에 붙인다.
73. 발 비행 경로
• 기준선과 비행 경로 애니메이션 트랙으로 발의 위치를 계산
• 기준선은 현재 발자국과 다음 발자국을 끝점으로 하는 선분
• t = (CurAnimTime – FootOffTime) / (FootStrikeTime – FootOffTime)이면,
• FootPos = Lerp(CurFootstep, NextFootstep, t) + StepLength * AnimTrack(t)
현재 발자국 다음 발자국
74. 발 비행 경로
• 보폭 계산
• 사이클 전체의 이동거리에서 발이 지면에 붙어있는 구간을 구하면 된다.
• StepLength = Length(CurFootstep, NextFootstep) * (1.0f – (FootStrikeTime – FootOffTime))
현재 발자국 다음 발자국
보폭 = L1 + L2
L1 L2
75. 발걸음 전환
• 다리 사이클을 바꿔야 할 경우가 있다.
• 걷기와 뛰기는 풋오프, 풋스트라이크 타이밍이 다르다.
• 말은 보행자세가 4개
평보(Walk)
속보(Trot)
구보(Canter)
습보(Gallop)
76. 발걸음 전환
• 다리 단위로 전환
• 발이 지면에 있을 때 전환해야 발 위치가 튀지 않는다.
• 사이클 시간이 풋오프 타임 ~ 풋스트라이크 타임 사이가 아닐 때 전환한다.
• 전환할 다리 사이클의 스탠스 타임에 따라 처리 방법이 다르다.
• 전환 후의 사이클 시간이 풋오프 타임 ~ 풋스트라이크 타임 사이에 있으면 발 위치가 튄다.
80. 이동 애니메이션
• 스파인과 림의 애니메이션 트랙을 재생
• 속력에 상관없이 항상 애니메이션을 재생
• 재생 속도(Play Rate)는 속력과 관계없다.
• 발 위치 맞추기
• 역운동학으로 다리 포즈를 수정해서 발을 계산해둔 위치로 옮긴다.
• 이후 슬라이드에서 설명
81. 이동 애니메이션
• 속력이 증가하면 보폭이 커진다.
• 이동거리가 늘어나므로 당연한 현상
• 모션이 어색해진다.
• 재생 속도를 증가시켜 해결하면 안된다.
• 보폭은 유지되지만 어색한 모션은 여전함
82. 이동 애니메이션
• 발이 지면에 닿는 시간을 줄여서 보폭을 일정하게 유지
• 풋오프, 풋스트라이크 타임을 조절한다.
• KeyTimeScale = RefSpeed / CurSpeed
• NewFootOffTime = FootOffTime * KeyTimeScale
• NewFootStrikeTime = 1.0 – (1.0 – FootStrikeTime) * KeyTimeScale
속력
발높이
84. 이동 애니메이션
• 애니메이션 타임워프
• 수정된 키타임과 애니메이션이 일치하도록 재생시간 보정이 필요
• 구분적 선형함수(Piecewise Linear Function)만 사용해도 충분
t
t'
FootOffFootOff’ FootStrike FootStrike’
85. 이동 애니메이션
• 중심잡기
• 발자국이 스탠스 위치에서 크게 벗어난 경우의 처리
• 애니메이션 재생속도를 높여서 발자국이 빠르게 제자리를 찾도록 한다.
86. 출발 및 정지
• 속력이 0.0 근처일 경우의 처리
• 속력이 일정 경계값 이하로 내려가면 애니메이션 비율을 줄인다.
• 서있는 모션이나 출발 모션과 섞는 방법을 연구 중
88. 다리 IK
• 애니메이션 발 위치를 절차적으로 생성한 위치로 옮긴다.
• 발자국 위치로 옮기기
• 경사면, 낮은 턱 위에 발 올리기
• 여러가지 IK 해법이 있다.
• 분석적 IK solver는 대부분 본 두개만 처리
• 게임에서는 반복적 최적화 방식의 solver를 주로 사용하고 있다.
• CCD(Cyclic Coordinate Descent)
• FABRIK(Forward And Backward Reaching Inverse Kinematics)
89. FABRIK
• 휴리스틱하게 푸는 매우 간단한 IK 알고리즘
• UE4, Unity에 통합되어 있다.
목표 목표
Backward Pass Forward Pass
90. IK 안정적으로 처리하기
• 프레임 불연속성을 줄이는 것이 관건
• 축소 단계(Shirink Pass) 추가
• 다리 관절 회전축 방향을 제한
목표
Shrink Pass 위: 회전축 방향제한 꺼짐
아래: 회전축 방향제한 켜짐
91. 목표 바라보기
• 문제 정의
• N 관절 링크의 말단이 주어진 위치를 향하도록 하는 관절 각도 계산
• 머리가 목표를 바라보게 하는 처리에 사용한다.
목표
92. 목표 바라보기
• 일반적인 IK 문제와 다른 점
• 마지막 관절 길이가 자유롭다.
• 방향을 바라보는 것이 아니라 위치를 바라봐야 한다.
목표
p
p1
p2
p3
p4
93. 목표 바라보기
• 해법
• CCD, FABRIK으로 풀기
• 관절을 곡선으로 간주하고 말단의 접선 방향을 계산
• SME의 해법
• 모든 가능한 포즈 중에서 목표를 바라보는 것을 선택
• 구현이 간단하다.
• 직관적으로 포즈를 제어할 수 있다.
94. 목표 바라보기
• 포즈 트리의 구성
• 모든 가능한 포즈를 트리로 구성
• N개의 관절이 M개의 방향을 바라볼 수 있다면 M^N 개의 조합이 가능
• 4관절, 7방향을 가지고 있으면 2,401개
• 마지막 관절은 트리에서 제외
• 트리 탐색
• 목표를 바라보는 포즈를 찾을 때까지 탐색
• 매번 처음부터 전체 트리를 탐색해도 크게 문제없는 수준
• 프레임 분산, 이전 해 근처부터 탐색 등의 최적화 가능
97. 플러그인
• SME는 UE4 플러그인으로 구현
• 엔진의 다른 기능에 영향을 주지 않기 때문에 플러그인 형식이 제일 적합
• SilvervineMotionEngine, SilvervineMotionEditor 모듈로 구성됨
• UE4의 핫리로딩 기능으로 이터레이션 과정이 수월
• 현재 버전(4.15.1)에서는 아직 플러그인 자동 핫리로딩이 안되므로 약간 불편
• 직접 리컴파일 버튼을 눌러야 한다.
98. FAnimNode_SilvervineMotion
• FAnimNode_SkeletalControl의 파생 클래스
• C++로 구현. 블루프린트 코드는 (아직) 없다.
• 애니메이션 그래프 안에서 SME가 실행된다.
• 모션 분석 및 런타임 처리 모두 SME 노드에서 처리한다.
• AnimDynamics를 적극적으로 활용
• 털 갈기, 깃발 등은 SME로 처리하지 않는다.
• 아직 제대로 된 문서가 없어서 작업이 힘들다… 매뉴얼좀…
99. 커스텀 어셋
• 런타임 성능을 위해 모션 분석 결과를 저장
• 릴리즈 버전은 저장된 결과를 로드해서 사용
• 개발 버전은 저장 없이 매 수행마다 모든 과정을 처리한다.
• 모션 분석 처리를 애니메이션 그래프 노드 밖으로 분리하는 것을 고려 중
100. SME 액터 컴포넌트
• 애니메이션 그래프는 제약이 심하다
• 엔진 디자인상 성능을 위해 일반 블루프린트와 격리되어 있다.
• SME에서 일반적인 방법으로 외부 블루프린트에 접근하는 것이 불가능
• USilvervineMotionComponent 도입
• 캐릭터, 레벨 블루프린트에서 SME에 접근하기 위한 통로
• 모션 사이클 정보 등의 SME 내부 정보를 조회 가능
• SME에서 애니메이션 노티파이 이벤트를 구현하기 어렵기 때문에 컴포넌트의 이벤트로 대체
101. 액터 속력
• AActor::GetVelocity()의 함정
• “Returns velocity (in cm/s (Unreal Units/second) of the rootcomponent if it is either using
physics or has an associated MovementComponent”
• 물리나 무브먼트 컴포넌트에 의한 속도를 반환한다.
• 블루프린트 등에서 액터의 위치를 직접 수정하면 속도에 반영되지 않는다.
• 모든 경우에 일관된 방식으로 대응하도록 SME 내부에서 직접 속도를 계산
103. 요약
• 절차적 애니메이션의 필요성
• 애니메이션에 의한 게임 디자인 제약을 낮춘다.
• 다양한 환경, 조건에 어울리는 캐릭터 움직임이 필요하다.
• 모션 엔진 개발 과정
• 모션 분석으로 런타임에 사용할 데이터를 추출하는 방법
• 로코모션 처리 과정과 유용한 IK 기법 소개
• UE4로 구현할 때의 참고사항
• 많은 피드백 바랍니다!
104. 참고자료
• GTA4, Euphoria
http://www.naturalmotion.com/middleware/euphoria
https://www.youtube.com/watch?v=87qdmuOesRs
• Generalizing Locomotion Style to New Animals With Inverse Optimal Regression
http://grail.cs.washington.edu/projects/inverse_locomotion/
• IK Rig
http://www.gdcvault.com/play/1022984/IK-Rig-Procedural-Pose
• An Indie Approach to Procedural Animation
http://www.gdcvault.com/play/1020583/Animation-Bootcamp-An-Indie-Approach
• Motion Matching
http://www.gdcvault.com/play/1022985/Motion-Matching-and-The-Road
• Bringing a Hero from Paragon to Life with UE4
https://archives.nucl.ai/recording/bringing-a-hero-from-paragon-to-life-with-ue4/