브라우저에서 오픈 월드 만들기, 25부: 골격 하나로 모든 의상
작성: Oleg Sidorkin, Cinevva CTO 겸 공동 창업자
처음 보시나요? 시리즈 가이드를 보세요. spike가 무엇인지 설명하고 모든 부분을 링크해 둡니다.
24부에서는 세계를 영속적으로 만들고 식생에 바람을 입혔습니다. 이번 부분은 다시 그 안의 사람들 이야기인데, 이번엔 옷장 쪽에서 봅니다. 창작자가 기본 몸을 고르고, 옷을 바꾸고, 헤어스타일을 고르고, 아무 애니메이션이나 재생하는 것을, 전부 무료 에셋 팩 하나만으로, 리깅도 애니메이션 제작도 없이 할 수 있을까요? 커스텀 리그를 만드는 건 디리스크할 대상이 아닙니다. 답할 가치가 있는 질문은 CC0 팩 하나가 짐 전체를 짊어질 수 있느냐입니다.
애초에 서로 맞물리도록 만들어진 팩
Quaternius는 의심스러울 만큼 잘 들어맞는 에셋 네 개를 제공합니다. Universal Base Characters는 남성과 여성 몸에 헤어스타일 여덟 가지와 눈썹 세트 두 가지를 더한 것이고, Modular Character Outfits는 몸통, 팔, 다리, 발 부위로 나뉘며 견갑(pauldron)과 후드 같은 액세서리가 딸려 있고, Universal Animation Library 1번과 2번 팩은 도합 262개 클립으로 이동, 전투, 등반, 농사, 낚시, 대기 동작, 사교 동작을 다룹니다. 이들의 glTF를 살펴보니 왜 들어맞는지 드러났습니다. 네 팩의 모든 메시 하나하나가 똑같은 65개 관절의 UE5 스타일 골격에 리깅되어 있고, 관절 이름도 같고, 바인드 포즈도 같으며, root에서 pelvis, spine을 거쳐 head까지, 양쪽이 미러링된 팔에 각 측마다 손가락 관절 열다섯 개, 미러링된 다리까지 동일합니다. 리타기팅이 전혀 필요 없습니다. 이건 Spike 35의 세 골격 리타기팅 문제와 정확히 반대입니다. 거기서는 213개 뼈의 얼굴 리그가 65개 뼈의 Mixamo 리그와 대화해야 했죠. 여기서는 네 팩 모두 의도적으로 애니메이션 라이브러리의 골격 위에서 제작되었고, 결합이 정확합니다.
그래서 이 spike는 애니메이션 파이프라인 작업이 아니라 바인딩 작업이 되었습니다. 베이스 레이어는 몸 glTF를 불러오고, SkeletonUtils.clone으로 씬을 복제해 각 캐릭터가 로더의 캐시된 씬에 뼈 변형을 다시 흘려보내는 대신 새 골격 인스턴스를 받게 하며, 그 65개 뼈 골격을 애니메이션을 떠받치는 아마추어 객체와 함께 표준(canonical) 버전으로 캐싱합니다.
코트를 몸에 다시 바인딩하기
이 모든 걸 동작하게 하는 요령은, 의상의 메시를 그냥 씬에 다시 부모로 붙일 수 없다는 점입니다. 그 메시는 여전히 자기 glTF의 뼈를 참조하고 있고, 그 뼈들은 다른 서브트리에 자리 잡고 있기 때문입니다. 각 모듈식 부위, 농민의 몸이든 레인저의 다리든, 같은 아마추어의 자기 클론을 지닌 자기만의 SkinnedMesh로 도착합니다. 바인딩은 소스 골격의 뼈를 원래 순서대로 훑으면서 각 뼈를 표준 골격에서 이름으로 찾아내고, 그 재바인딩된 뼈들로 새 Skeleton을 만들면서 소스의 bind-inverse 행렬을 재사용한 다음, 소스의 단위 bind 행렬로 SkinnedMesh.bind를 호출합니다. 바인딩 후에는 메시가 소스 씬에서 분리되어 캐릭터 root 바로 아래에 부모로 붙습니다. bind 행렬이 바인드 시점의 월드 변환을 담고 있고 root가 단위 변환에 자리하므로, 메시 자신의 월드 변환은 결과에 전혀 영향을 주지 않으며 스키닝은 전적으로 이제 공유된 뼈를 통해 일어납니다.
머리카락과 눈썹도 슬롯이며, 이들은 잘못된 가정을 바로잡아 줬습니다. 폴더 구조에는 "head 뼈에 리깅됨"이라고 적혀 있었고, 이는 머리카락이 구운 오프셋으로 머리에 부모로 붙은 정적 메시일 거라고 암시했습니다. 그렇지 않았습니다. 모든 머리카락 파일은 65개 관절 전체에 걸쳐 가중치가 분포된 SkinnedMesh이며, 긴 머리의 가중치는 위쪽 spine과 목까지 번져 들어가 캐릭터가 고개를 숙일 때 머리가 드리워집니다. 그래서 머리카락도 다른 의상 부위와 똑같은 이름 기준 재바인딩 경로를 탑니다. 유일한 특수 사례는 의상의 몸통 슬롯입니다. 이게 부착되면 의상이 뚫고 나오지 않도록 베이스 몸 메시가 숨겨지고, 팔, 다리, 발, 액세서리는 그냥 쌓입니다. 팩이 옷이 피부를 드러내는 곳마다 베이스 몸이 비쳐 나오도록 공존하게 제작했기 때문입니다.
262개 애니메이션이 공짜로
골격이 공유되고 나면 애니메이션은 거의 김 빠질 만큼 싱겁습니다. 라이브러리 glb 두 개를 불러오면 그 클립들이 이름 붙은 하나의 목록으로 펼쳐지고, 그 클립 안의 트랙 이름들은 bone.position, bone.quaternion, bone.scale로 정확한 관절 이름을 참조합니다. 캐릭터의 아마추어에 뿌리내린 AnimationMixer가 그 뼈들을 이름으로 찾아 직접 구동하고, 전환 시 크로스페이드합니다. 뷰어의 오른쪽 패널은 262개 클립 전체를 필터링할 수 있는 목록이고 소스 표시 알약(pill)이 달려 있어서, "fish"를 검색하면 두 라이브러리에 걸친 모든 낚시 애니메이션이 떠오릅니다. 부드러운 그림자가 있는 표준 3점 조명, 발밑의 극좌표 그리드, ACES 톤 매핑이 스타일화된 베이스 텍스처를 읽기 좋게 유지하면서도 어두운 바디수트의 그림자를 으스러뜨리지 않습니다.
이것이 제품을 위해 디리스크하는 것은 큽니다. 아바타 커스터마이징 기능은 리깅 작업 제로, 애니메이션 제작 제로로 CC0 팩 위에서 출시할 수 있습니다. 네 팩을 넣고, 옷장 UI를 연결하면, 대략 의상 여섯 가지 곱하기 헤어스타일 여덟 가지 곱하기 성별 두 가지 곱하기 애니메이션 262개만큼의 변형이 박스째로 나옵니다. 65개 관절 골격은 충분히 작아서 GPU 스키닝 비용이 무시할 만하고, Spike 45의 배치 스키닝 작업이 이미 이 정도 규모의 리그에서 아바타 200개 이상을 처리합니다. CC0는 사용 제한이 전혀 없어서 유료 창작자 플랫폼에서 상업적으로 써도 괜찮습니다. 남은 미해결 질문은 사용자가 직접 업로드한 의상인데, 이는 Phase 3 문제로, 업로드 시점에 이 표준 골격으로 리타기팅하면 풀립니다. Spike 35의 런타임 리타기팅을 거꾸로 뒤집은 셈이죠. 에셋 용량은 디스크에서 약 147MB로 원본 2K PNG와 무압축 애니메이션 glb입니다. 프로덕션에서는 KTX2 텍스처 압축과 gltf-transform 한 번을 거치면 대략 30MB로 줄어듭니다.
이 장에서 다룬 기술
팩 전체에 걸친 표준 골격 하나. 네 개의 Quaternius 팩(베이스 몸, 모듈식 의상, 두 개의 애니메이션 라이브러리)은 전부 동일한 65개 관절의 UE5 스타일 골격에 리깅되어 있고 관절 이름과 바인드 포즈가 같아서, 이들을 조합하는 데 리타기팅이 필요 없습니다. SkeletonUtils.clone으로 베이스를 복제하면 로더의 캐시된 씬을 변형하는 대신 각 캐릭터가 새 골격 인스턴스를 받습니다.
이름 기준 골격 재바인딩. 각 모듈식 부위는 자기 아마추어를 참조하는 자기만의 SkinnedMesh를 가지고 옵니다. 재바인딩은 소스 뼈를 순서대로 훑으며 각각을 이름으로 표준 골격에 매핑하고, 소스의 bind-inverse를 재사용해 새 Skeleton을 만들고, 단위 bind 행렬로 SkinnedMesh.bind를 호출한 다음, 메시를 공유 캐릭터 root 아래에 부모로 붙여 스키닝이 전적으로 공유 뼈를 통해 돌아가게 합니다. 의상의 몸통 슬롯은 뚫림(clipping)을 피하려고 베이스 몸을 숨기고, 다른 슬롯은 그냥 쌓입니다.
스키닝 슬롯으로서의 머리카락. 머리카락은 head 뼈에 붙은 정적 부착물이 아니라 65개 관절 전체에 걸쳐 가중치가 분포된 SkinnedMesh이고, 긴 머리는 위쪽 spine과 목에 가중치가 들어가 고개를 숙일 때 드리워집니다. 의상 부위와 똑같은 재바인딩 경로를 탑니다.
이름 키 기반 애니메이션 리타기팅이 공짜로. Animation Library 클립은 관절을 정확한 이름으로 참조하므로, 공유 아마추어에 뿌리내린 AnimationMixer가 클립별 리타기팅 없이 크로스페이드로 262개 클립 전부를 직접 구동합니다. CC0 라이선스가 상업적 사용을 커버하고, 적은 관절 수 덕분에 GPU 스키닝이 충분히 저렴해서 Spike 45의 배치 스키닝 경로를 재사용할 수 있습니다. GPU 주도 LOD를 보세요.
29부 중 25부. 이전: 24부 - 세계를 저장하기, 그리고 눈에 보이는 바람 다음: 26부 - 모든 스케일에서 버티는 물 시리즈 가이드: /ko/blog/2026-02-25-open-world-browser-series-guide