Skip to content

애니메이션이 세계와 맞닿아야 할 때 ​

Oleg Sidorkin, Cinevva CTO 겸 공동 창업자

걷기 애니메이션은 다리가 어떻게 움직이는지 압니다. 하지만 한쪽 발이 계단에 닿았다는 사실은 알지 못합니다. 팔을 뻗는 애니메이션은 팔이 어떻게 움직이는지 압니다. 하지만 특정 열쇠 구멍이 어디에 있는지, 누군가 컵을 옮겼는지는 알지 못합니다.

이는 캐릭터 자동 리깅 다음에 해결해야 할 문제입니다. 바로 게임이 실행되는 동안 애니메이션이 장면에 반응하도록 만드는 것입니다. 저희는 Cinevva의 Three.js 런타임에 실험적인 보정 레이어를 구현했습니다. 이 레이어는 애니메이션이 생성한 포즈를 읽고 장면을 조회한 다음, 프레임이 렌더링되기 전에 캐릭터의 관절을 조정합니다.

아래 예제는 브라우저에서 해당 코드를 실행합니다. 프레임별 루프에서는 모션 생성 요청이 이루어지지 않습니다.

차이를 직접 체험해 보세요 ​

데모는 자동으로 시작됩니다. 예제를 선택한 후 보정을 껐다가 켜 보세요. 왼쪽 캐릭터는 기본 포즈를 보여 주고, 오른쪽 캐릭터에는 실시간 보정이 적용됩니다. 일시 정지한 다음 타임라인을 드래그하면 특정 순간을 자세히 살펴볼 수 있습니다. 어느 뷰포트든 드래그하여 캐릭터 주위를 회전하고, 스크롤하거나 손가락을 오므려 확대·축소하며, 마우스 오른쪽 버튼으로 드래그하여 화면을 이동할 수 있습니다. 두 카메라는 동기화되어 있으므로 정확히 같은 각도에서 동일한 접촉을 확인할 수 있습니다.

모든 예제는 Cinevva에서 자동 리깅한 동일한 개구리 캐릭터를 사용합니다. 걷기 예제는 Universal Animation Library의 Walk를 재생하며, Auto Rigger와 동일한 코드를 통해 리타기팅됩니다. 두 뷰포트 모두 실제 클립을 재생하고, 오른쪽에는 런타임 지형 보정이 추가됩니다. 다른 예제는 내장된 Idle 참조 애니메이션과 각 상호작용 컨트롤러를 그대로 사용합니다.

걷기 컨트롤러는 한 보폭 앞을 계획합니다. 발이 닿을 순간의 움직이는 발판 위치를 예측하고, 개구리의 발바닥 전체가 착지 영역 안에 들어오도록 중앙에 배치하며, 앞으로 내디딜 발이 미래의 계단 높이를 넘도록 스윙 경로를 계산합니다. 보폭을 조정하면서도 라이브러리 클립의 리듬과 스윙 형태를 유지합니다. 골반은 착지 전에 체중 이동과 높이 변화를 시작합니다. 그런 다음 IK가 계획된 타깃에 팔다리를 배치하고 눈에 보이는 발바닥 접촉을 세밀하게 조정합니다.

발걸음 계획을 켜면 예측된 착지 위치에 발바닥 윤곽이 나타나고, 스윙 경로가 점선으로 표시됩니다. 골반 궤적은 몸의 움직임을 비교하며, 골반 궤적 저장은 측정값을 보존합니다. 현재 이 플래너는 데모에서 미리 정의된 병진 이동 발판만 처리합니다. 불가능한 착지는 보고하지만, 임의 지형 탐색과 물리적 균형 힘은 별도의 엔진 기능입니다.

사다리 오르기는 세 접촉점으로 가로대를 붙잡은 상태에서 한 번에 한 팔다리씩 옮깁니다. 등반자가 화면 안에 머물도록 사다리가 아래로 이동합니다. 명시적인 발목 및 손 타깃이 접촉 위치를 정하고, 팔꿈치와 무릎 가이드가 관절이 사다리와 겹치지 않도록 굽힘 방향을 유지합니다. 몸의 움직임과 접촉 순서는 미리 제작된 것입니다. 자동 등반 플래너는 아닙니다.

구현된 기능 ​

기능현재 런타임의 동작
고르지 않은 지면각 발의 지지점을 조회하고, 보정된 발바닥 법선을 정렬하며, 골반 높이를 조정합니다.
고정된 발디딤 상태의 접촉점을 발을 지지하는 표면을 기준으로 유지합니다.
움직이는 플랫폼병진하거나 회전하는 지지면을 따라 접촉점을 이동시킵니다.
손 타깃블렌드 가중치를 적용하여 팔이 월드 공간의 위치와 방향을 향하도록 풉니다.
손에 든 물체원하는 물체 포즈와 고정된 그립 변환으로부터 손목 타깃을 계산합니다.
닿을 수 없는 거리솔브 범위를 제한하고 캐릭터의 위치를 옮겨야 한다고 보고합니다.

이는 선택적으로 활성화하는 런타임 프로토타입입니다. 대화형 예제는 구현된 기능을 보여 주지만, 생성되는 모든 Cinevva 게임에서 자동으로 활성화된다는 뜻은 아닙니다.

고정된 발에는 기준 좌표계가 필요합니다 ​

기존 리타기터는 이미 체형 비율이 다른 캐릭터 사이에서 클립을 전송할 때 발생하는 일부 발 미끄러짐을 보정합니다. 런타임 지면 정렬에는 또 하나의 입력이 필요합니다. 바로 현재 캐릭터가 서 있는 표면입니다.

발이 디딤 상태에 들어가면 새 레이어는 지지 물체의 로컬 좌표에 접촉점을 기록합니다. 정지된 바닥에서는 몸이 움직여도 발이 제자리에 유지됩니다. 움직이는 플랫폼에서는 저장된 동일한 지점이 플랫폼과 함께 이동합니다. 이를 월드 좌표에만 고정하면 발이 뒤에 남게 됩니다.

이어서 골반은 두 다리가 모두 닿을 수 있는 제한된 높이 범위 안에서 움직이고, 각 다리는 해당 발 타깃을 향해 솔브됩니다. 초기 테스트에서는 미묘한 오류가 발견되었습니다. 도달 가능 경계를 가로질러 골반 움직임을 스무딩하자 경사면에서 발이 잠시 떠 버렸습니다. 이제 스무딩은 도달 가능한 범위 안에서만 이루어집니다.

개구리 캐릭터에서는 별도의 캘리브레이션 오류가 드러났습니다. 가장 낮은 발가락이 닿았다고 해서 발바닥 전체가 안착한 것은 아닙니다. 이제 데모는 포즈가 적용된 각 발 메시의 지지 평면을 맞춰 위치와 법선을 모두 보정합니다. 렌더링 회귀 테스트는 Idle 전체 구간에서 가장 낮은 표면점뿐 아니라 서로 떨어진 세 개의 발바닥 접촉점도 측정합니다.

공유 몸체 지지 검사는 가중치가 적용된 신체 세그먼트로 무게 중심을 추정하며, 예시용으로 들고 있는 물체의 하중도 포함합니다. 서기 및 팔 뻗기 예제는 이를 사용하여 하중이 실린 발 쪽으로 골반을 유도합니다. 걷는 동안에는 발걸음 플래너가 예상되는 체중 이동을 담당하므로, 정적인 지지 영역 중심 보정이 계획된 움직임을 방해해서는 안 됩니다. 진단 정보에는 추정 COM과 지지 접촉점이 계속 표시됩니다. 걷기 예제에는 계획된 체중 이동이 표시되며, 사다리 예제에는 그립 힘이 아직 검증되지 않았다고 표시됩니다.

걷기에는 여전히 타이밍이 필요합니다. 게임은 각 발에 가중치를 제공합니다. 이는 해당 순간에 발을 얼마나 강하게 고정된 것으로 취급해야 하는지를 뜻합니다. 스윙 중인 발은 고정에서 해제해야 합니다. 게임은 보행 주기, 캐릭터의 움직임, 다음 계단을 넘기 위한 여유 높이도 제공합니다. 이러한 결정은 IK 솔버가 추론하지 않습니다.

열쇠를 구멍에 맞춘 다음 손을 솔브합니다 ​

손목을 열쇠 구멍 쪽으로 향하게 하는 것만으로는 충분하지 않습니다. 열쇠에는 길이, 삽입 축, 그립 오프셋이 있습니다. 손목이 타깃에 완벽히 도달하더라도 열쇠 끝은 빗나갈 수 있습니다.

데모에서는 상호작용 시퀀스가 열쇠의 원하는 위치와 회전을 정의합니다. 그립 정보를 사용하면 열쇠를 해당 위치에 놓기 위해 손목이 어디에 있어야 하는지 알 수 있습니다. 그런 다음 팔이 해당 손목 포즈를 향하도록 솔브됩니다. 요청된 위치에 닿을 수 없는 경우에도 실제 열쇠는 솔브된 손에 계속 붙어 있습니다.

닿을 수 없는 타깃 예제는 이러한 실패를 의도적으로 보여 줍니다. 수치상 성공한 것처럼 보이게 하려고 팔다리를 늘리지 않습니다. 대신 런타임은 캐릭터의 위치를 옮겨야 한다고 보고합니다.

이 예제에는 미리 제작된 접근, 삽입, 회전 단계가 있습니다. 아직 손가락으로 잡는 동작을 계획하거나 자물쇠 내부의 여유 공간과 열쇠 형상이 맞는지 확인하지는 않습니다.

따르기 동작에서도 방향이 중요합니다 ​

따르기 예제는 용기의 주둥이를 컵 위에 유지한 채 용기를 기울입니다. 용기가 회전하면 필요한 손목 위치도 바뀝니다. 동일한 손 타깃 메커니즘이 이렇게 변화하는 포즈를 따라갑니다.

파란색 물줄기는 기울이는 동안 활성화되는 시각 효과입니다. 유체 시뮬레이션은 아닙니다. 여기서 그 목적은 정렬 상태를 눈에 보이게 하는 것입니다. 보정이 없으면 물줄기가 컵을 빗나가고, 보정이 있으면 컵의 수용 영역 안으로 떨어집니다.

보정이 실행되는 위치 ​

게임 내 실행 순서는 다음과 같습니다.

캐릭터 이동 → 애니메이션 평가 → 포즈 오프셋 적용 → 장면 접촉 솔브 → 보조 모션 업데이트 → 렌더링.

런타임은 선택적 sceneIK 설정과 함께 createAnimator를 통해 이 기능을 제공합니다. 게임은 접촉 가중치, 손 타깃, 지면 접촉 상태를 update에 전달합니다. 기존 Three.js 애니메이션 믹서를 감싸는 방식으로도 사용할 수 있습니다.

각 리그에는 의미 있는 발 및 그립 캘리브레이션이 필요합니다. 뼈 이름 매핑을 통해 올바른 팔다리를 찾을 수는 있지만, 발목 관절이 신발 바닥인 것은 아닙니다. 이 버전은 발마다 하나의 보정된 지지점을 사용하며, 아직 발뒤꿈치와 발가락을 포함한 전체 지지 영역을 모델링하지는 않습니다.

기반 기술에는 Unity의 투 본 IK와 Unreal의 IK 솔버처럼 이미 확립된 대응 기술이 있습니다. 저희 구현은 자동 리깅된 캐릭터의 요구에 맞춰 제작한 소규모 엔진 측 보정 레이어입니다.

검증한 내용과 앞으로 남은 과제 ​

첫 번째 검증 단계에는 14개의 수치 및 통합 테스트와 3,840개 프레임에 걸쳐 샘플링된 8개의 렌더링 시나리오가 포함되었습니다. 움직이는 지지면, 경사면 접촉, 상수 애니메이션 트랙, 좌표 변환, 도달 한계, 런타임 애니메이터 통합을 검사했습니다. 브라우저 자동화는 보정을 켰을 때와 껐을 때의 캔버스도 비교하고 좁은 레이아웃도 테스트했습니다.

측정값은 팔다리와 타깃 사이의 오차를 검사합니다. 스키닝된 메시의 모든 부분에 충돌이 없다는 증거나, 모든 캐릭터에서 결과가 자연스럽게 보인다는 증거는 아닙니다. 예제는 이러한 수치와 함께 직접 살펴볼 수 있도록 의도적으로 작게 구성했습니다.

다음 단계는 발걸음 계획, 더 나은 발바닥 지지, 전신 뻗기, 손가락 파지, 충돌을 고려한 상호작용 단계입니다. 물리 기반 액체 시뮬레이션은 또 다른 별도의 시스템입니다.

현재로서는 구체적이고 유용한 결과를 얻었습니다. 애니메이션의 기본 움직임을 유지하면서도 발과 손이 매 프레임 장면에 반응할 수 있습니다. 이는 자동 리깅된 캐릭터가 주변 세계와 상호작용하기 위한 출발점이 됩니다.