뎁스 기반 2.5D 리깅 인터페이스

Tags
Rigging
Animation
OpenSource
Description
깊이 정보를 제어 가능한 리그로 연결하는 rig-c 인터페이스의 작동 원리와 사용법을 소개합니다.
Published
2026년 11월 2일 발행
On this page
그림 속 캐릭터가 시선을 따라 고개를 돌리게 만들고 싶었습니다. 얼굴 전체를 기울이거나 레이어를 옆으로 미는 것만으로는 원하는 입체감이 나오지 않았습니다. 얼굴 안에서도 코와 볼, 귀의 깊이가 다르고, 머리카락과 몸통도 각자의 위치에서 움직여야 했습니다.
이번 업데이트의 핵심은 그 깊이를 리깅에 전달하는 인터페이스입니다. 파츠에 깊이 정보를 연결하고 어떻게 움직일지 선언하면, 좌우·상하·몸통을 제어할 수 있는 2.5D 리그를 만듭니다.
공개 look 예제를 @rig-c/parts 2.2.0과 @rig-c/core 3.1.0으로 리깅한 결과입니다. 캡처용으로 고개·눈·몸통 다이얼에 시선 경로를 추가했습니다. 그림·리그·깊이는 그대로이며, Core 렌더러가 만든 프레임을 이어 붙였습니다.

깊이가 움직임이 되는 과정

깊이 시트에는 파츠의 각 지점이 얼마나 앞에 있는지가 들어 있습니다. 리깅 과정에서는 이 값을 메시의 정점에 연결합니다. 고개를 돌리는 값이 바뀌면 기준 깊이와 각 정점의 깊이 차이에 따라 이동량이 달라집니다. 같은 얼굴 안에서도 부분마다 다르게 움직이면서 입체감이 생깁니다.
아래는 공개 head-turn 데모의 깊이 아틀라스입니다. 얼굴과 머리카락, 몸통 등 분리된 파츠의 깊이 정보가 한 장에 배치된 모습을 볼 수 있습니다. 뒤에서 다룰 파츠별 깊이 준비·적용 절차와는 구분해서 보면 됩니다.
공개 head-turn 데모에 사용된 깊이 아틀라스
공개 head-turn 데모에 사용된 깊이 아틀라스
모든 파츠를 똑같이 휘게 만들지는 않습니다. 캐릭터 설정의 turn.roles에서 파츠별 역할을 지정합니다.
  • surface: 얼굴과 머리카락처럼 깊이 시트를 읽어 표면을 변형합니다.
  • unit: 눈·입·눈썹처럼 형태를 유지하면서 하나의 깊이값으로 이동합니다.
  • rear: 뒤쪽 묶음에 별도의 반대 방향 움직임을 줍니다.
역할은 파츠 이름만으로 자동 결정하지 않습니다. 뒤쪽 머리카락이라도 표면의 굴곡을 살리려면 surface로 다룰 수 있습니다. 몸통은 turn.body.roles에 별도로 선언합니다.
notion image
뎁스 기반 리그의 움직임 중 일부 장면

준비된 예제로 사용해 보기

처음에는 공개 look 예제로 시작하면 됩니다. 원화와 분리된 파츠, 깊이 시트, 설정이 함께 들어 있어 깊이 모델을 돌릴 GPU 없이 리깅 과정을 체험할 수 있습니다.
아래는 look/ 폴더를 로컬로 받은 뒤 그 안에서 실행하는 순서입니다. Bun이 설치된 환경을 전제로 하며, 이번에 확인한 패키지 버전을 고정했습니다.
bun add @rig-c/[email protected] @rig-c/[email protected] bunx rig-parts assemble \ --source painting.png \ --full layers/full \ --head layers/head \ --config config.json \ --out assembled bunx rig-parts rig \ --config config.json \ --parts assembled/rig \ --out candidate bunx rigc build \ --rig candidate/rig.json \ --motion candidate/motion.json \ --out built \ --profile rig-play \ --pack --page-edges free --pack-shape polygon
assemble은 원화와 레이어를 읽어 파츠를 조립하고, 연결된 깊이 시트를 파츠 좌표에 맞춥니다. rig는 역할과 깊이를 읽어 메시·변형·제어 다이얼을 만듭니다. build는 리그와 움직임을 컴파일하고 검증한 뒤 Spine 데이터와 rig-c의 네이티브 모델을 생성합니다.
이 명령은 공개 예제 커밋 ddfd314a2664effaf41c770e47e43f1418d6dba8과 위 패키지 조합으로 조립부터 빌드까지 확인했습니다. 본문의 움짤과 스틸은 Core 렌더러의 출력입니다. 같은 빌드의 Play·Pixi 브라우저 재생까지 확인했다는 뜻은 아닙니다.
예제의 config.json은 자신의 캐릭터를 설정할 때 출발점으로 삼을 수 있습니다. 다만 깊이와 회전 기준값은 캐릭터에 맞춰 조정해야 합니다. 전체 입력 계약은 Depth 사용 가이드에 정리돼 있습니다.

내 그림에 깊이 정보를 연결하는 방법

깊이 입력은 두 경로로 받을 수 있습니다. 이미 파츠와 연결된 깊이 시트가 있으면 캐릭터 설정의 config.depth로 연결합니다. 새로 깊이를 구할 때는 조립된 파츠를 하나씩 외부 모델에 전달하는 경로를 사용합니다.
flowchart TD A["분리된 파츠와 캐릭터 설정"] --> B["assemble · 파츠 조립"] B --> C{"깊이 입력"} C --> D["준비된 깊이 시트 연결"] C --> E["depth-prepare · 추론 이미지 준비"] E --> F["외부 모델 · 깊이 데이터 생성"] F --> G["depth-apply · 좌표 검증과 시트 변환"] D --> H["rig · 역할별 메시와 다이얼 생성"] G --> H H --> I["build · 검증과 출력"] I --> J["다이얼 제어 · 검수와 손질"]

파츠별 깊이 준비와 적용

depth-prepare는 각 파츠를 회색 배경 위에 놓고 크기와 여백을 맞춘 추론용 이미지를 만듭니다. 외부 모델이 이를 읽어 깊이 데이터를 생성하면, depth-apply가 입력과 좌표의 일치 여부를 확인하고 리깅에서 사용할 시트로 변환합니다.
다음 명령은 assembled/rig와 캐릭터 설정 config.json, 별도의 깊이 레시피 depth.json이 준비돼 있다는 전제입니다.
bunx rig-parts depth-prepare \ --parts assembled/rig \ --config depth.json \ --out inference # 외부 모델로 inference의 이미지를 읽고, # depth.json에 지정한 경로에 rig-parts-map/1 데이터를 저장합니다. bunx rig-parts depth-apply \ --parts assembled/rig \ --manifest inference/manifest.json \ --config depth.json \ --rig-config config.json \ --out mapped bunx rig-parts rig \ --parts mapped \ --config mapped/config.json \ --out candidate-depth
이후에는 앞의 build 명령에서 입력 경로를 candidate-depth로 바꾸면 됩니다. 출력 폴더는 비어 있거나 아직 없어야 합니다.
rig-c에는 깊이 모델이나 가중치가 포함돼 있지 않습니다. 모델의 결과를 받아들이는 형식과 리깅으로 연결하는 절차를 제공합니다. 모델이 출력한 실제 숫자 데이터를 사용하며, 보기 좋게 변환한 회색조 미리보기 PNG를 그대로 대신 넣는 방식은 아닙니다.

깊이 레시피에서 정하는 값

깊이 모델의 상대적인 형태를 캐릭터 전체에 배치하려면 몇 가지 값을 선언해야 합니다. 레시피 예시는 공개 문서에 있으며, 그 숫자는 모든 캐릭터에 적용되는 기본값이 아닙니다.
  • median: 해당 파츠가 놓일 기준 깊이입니다.
  • relief: 파츠 내부 굴곡의 크기입니다.
  • near·zScale: 깊이값의 방향과 리그에서 사용할 크기를 정합니다.
  • frame: 모델 출력이 원래 파츠, 확대된 파츠, 여백을 포함한 입력 중 어느 좌표계를 사용하는지 지정합니다.
  • unitDepths: 작은 파츠의 깊이를 명시해야 할 때 사용합니다.
얼굴의 깊이를 바꾸면 귀나 눈의 깊이와도 맞는지 확인해야 합니다. 깊이 데이터만 교체하고 나머지 관계를 그대로 두면, 귀가 볼보다 앞에 놓이는 식의 모순이 생길 수 있습니다. 도구가 입력의 연결과 일부 관계를 검사하더라도 최종 움직임은 직접 확인해야 합니다.

다이얼로 움직임 제어

만들어진 리그에는 좌우 회전과 상하 회전을 제어하는 다이얼이 생깁니다. 몸통에도 독립적인 다이얼을 둘 수 있습니다. 포인터 위치나 게임 상태를 이 값에 연결하면 같은 리그를 여러 상황에서 사용할 수 있습니다.
기본 머리 다이얼은 yaw_dial, pitch_dial입니다. 몸통 이름은 설정할 수 있으며, 공개 look 예제는 body_dial을 사용합니다. 이름과 범위를 추측해서 넣기보다 생성된 모델의 슬라이더 선언을 읽는 편이 안전합니다.
  • Pose: 리타깃한 동작을 리그의 슬라이더에 연결합니다.
  • Review: Turn pad로 다이얼을 움직이며 결과를 확인합니다.
  • Play: 포즈를 조정하는 단계에서 다이얼 값을 설정합니다. 조정값은 매 포즈에 적용해야 합니다.
포인터를 다이얼에 연결하는 구체적인 예는 adapters의 look 예제에 있습니다. 예제의 포인터 보조 코드는 npm 어댑터의 기본 export가 아니라 예제에 포함된 코드입니다.

가능한 범위와 사람의 검수

현재 기본 회전 범위는 좌우 ±15도, 상하 ±12도입니다. 한 장의 그림에서 보이지 않던 얼굴 옆면을 새로 만들지는 않습니다. 더 큰 각도에는 다른 방향의 그림을 준비해 선언해야 합니다.
이 인터페이스는 그림과 깊이를 이용한 2.5D 투영입니다. 완전한 3D 모델의 조명이나 실루엣 변화까지 처리하지 않습니다. 또한 빌드 성공만으로 움직임의 품질까지 보장되지는 않습니다.
마지막에는 실제 움직임을 보고 검수하고 손질해야 합니다. Review는 문제가 있는 위치와 순간을 짚어 다음 수정으로 전달하는 역할을 맡습니다. 깊이를 리그로 연결하는 과정이 도구로 정리된 만큼, 이제 캐릭터별로 적용하고 다듬는 작업에 집중할 수 있습니다.