VRM 크기 이상, 100배 크거나 작을 때 FBX cm·m 확인법

키 170cm 캐릭터가 VRM에서 170m 거인이 되는 데는 단위 하나만 빠지면 충분합니다. 변환한 아바타가 화면을 뚫고 나갈 만큼 크거나 바닥의 점처럼 작아지는 VRM 크기 이상은 대개 이렇게 길이 단위가 어긋난 탓입니다. FBX는 센티미터를 암묵적 기본 단위로 삼고, VRM의 바탕인 glTF는 미터를 씁니다. 반대 방향으로 틀리면, 이미 미터인 1.7을 한 번 더 100으로 나눠 1.7cm 인형이 됩니다. 세 축이 같은 비율로 틀어졌고 그 비율이 100, 0.01, 39.37처럼 단위 환산 비율과 맞으면 단위 문제입니다.

이 사이트의 FBX → VRM 변환기에 넣은 시험 파일들도 키가 172.36, 169.77, 170.16 단위로 읽혔습니다. 이것을 1.6m로 맞추려면 0.0093~0.0094를 곱해야 했습니다.

거인, 인형, 그리고 딱 떨어지는 배율

단위가 어긋난 아바타는 모양은 멀쩡하고 크기만 틀립니다. 뷰어를 열었더니 화면에 발끝만 보이거나 카메라가 몸속에 들어가 있으면 100배로 커진 경우입니다. 아무것도 보이지 않아 한참 확대해야 작은 인형이 나타나면 0.01배로 줄어든 경우입니다.

키 170cm 사람을 기준으로, 미터로 읽었을 때 170이 나오면 100배, 0.017이 나오면 0.01배, 66.9가 나오면 인치 숫자를 미터로 읽은 39.37배입니다. 세 축이 같은 비율로 바뀌는 것은 단위가 모델 전체에 곱해지는 숫자 하나이기 때문입니다.

키 170cm 모델이 미터로 읽혔을 때 보이는 키와 배율, 짐작되는 원인을 정리한 표
보이는 키와 배율만으로 어느 단위가 어긋났는지 짐작할 수 있습니다. 축마다 비율이 다르면 단위가 아닌 다른 원인입니다.

반대로 축마다 비율이 다르면 단위 문제가 아닙니다. 이 사이트에서 다룬 3ds Max 모캡 FBX 중에는 파일 그대로 치수가 폭 303 × 키 172 × 두께 181cm인 것이 있었습니다. 키는 정상인데 사람 두께가 1.8m였습니다. 원인은 바인드 이후에 축·단위 변환이 끼어들어 어긋난 bind 행렬이었고, 메시를 다시 바인드하자 44×170×27cm로 돌아왔습니다(bind 행렬이 어긋나 찢어진 FBX). 스켈레톤이 납작하게 저장된 Character_0630.fbx는 30×39×22cm로 읽혀 작은 인형처럼 보였지만, 실제 원인은 본 119개의 로컬 위치가 전부 0이었던 것입니다. 스킨에 남은 바인드 행렬로 본 위치를 복원하자 164×170×29cm가 됐습니다. 크기가 이상하다고 곧바로 배율부터 곱하면 이런 문제를 덮어 버리게 됩니다.

원인: 숫자만 넘어가고 단위는 빠지는 구조

glTF 2.0 규격은 좌표 단위를 못 박아 둡니다. 좌표계 절에는 “The units for all linear distances are meters.”라고 적혀 있고, 메시 절에서도 노드의 전역 변환을 적용한 뒤의 정점 위치는 미터라고 명시합니다. VRM 1.0 규격은 좌표 단위를 glTF를 따르는 미터법으로 정했습니다. VRM 파일 안의 1.0은 언제나 1m입니다.

FBX는 사정이 다릅니다. Autodesk FBX SDK 문서에 따르면 FBX의 암묵적 좌표계는 센티미터이고, 파일을 쓰는 프로그램이 시스템 단위를 명시적으로 기록해야 합니다. 파일에서는 GlobalSettings의 UnitScaleFactor가 이 값을 담습니다. 센티미터 기준 배율이라서 센티미터 파일은 1, 미터 파일은 100, 인치 파일은 2.54가 됩니다. SDK의 단위 변환 함수(ConvertScene)도 메시의 정점 값은 두고 노드 변환과 애니메이션만 바꾼다고 문서에 적혀 있습니다. 같은 캐릭터라도 크기 정보가 정점 좌표, 노드 배율, UnitScaleFactor 세 곳에 나뉘어 들어갈 수 있다는 뜻입니다.

문제는 이 세 곳을 모두 읽는 도구만 있지 않다는 점입니다. 웹에서 FBX를 열 때 많이 쓰는 three.js의 FBXLoader는 r160 소스 기준으로 UnitScaleFactor를 읽어 userData.unitScaleFactor에 적어 두기만 하고 크기에는 곱하지 않습니다(2026년 9월 dev 브랜치도 같습니다). 정점과 노드 배율은 그대로 반영하므로 센티미터 FBX는 키 170짜리 물체로 읽힙니다. 이걸 glTF로 그대로 내보내면 170이 미터로 저장되고, VRM 뷰어는 170m 거인을 그립니다. 이 사이트의 변환기도 이 로더를 쓰므로 시험 파일의 키가 172.36 같은 센티미터 숫자로 들어왔습니다.

반면 Unity는 Convert Units 옵션으로, Blender는 FBX의 UnitScaleFactor를 읽어 가져올 때 단위를 맞춥니다. 그래서 같은 FBX가 Unity나 Blender에서는 정상 크기인데 웹 도구에서만 거인이 되는 일이 생길 수 있습니다. 파일이 틀린 게 아니라 읽는 쪽이 단위를 환산하지 않은 것입니다.

프로그램별 기본 단위

아래 표는 각 프로그램의 공식 문서와 소스 코드에서 확인한 내용입니다(2026년 9월 확인 기준).

프로그램·형식기본 길이 단위FBX와 주고받을 때
glTF 2.0 / VRM 1.0미터규격으로 고정
FBX센티미터(암묵적)UnitScaleFactor에 센티미터 기준 배율 기록
Blender내부 1 = 1m(Unit Scale 1.0일 때)내보내기 Apply Scalings 기본값 All Local
3ds Max시스템 단위 기본값 인치FBX 내보내기는 시스템 단위 그대로, Scale Factor 1.0
Unity1 unit = 1m가져오기의 Convert Units로 파일 단위를 변환
three.js FBXLoader파일 숫자 그대로UnitScaleFactor를 크기에 적용하지 않음

Blender의 FBX 입출력 코드에는 Blender 기본 단위가 미터에 해당한다는 주석이 있고, FBX 배율을 100 × Unit Scale로 계산합니다. 매뉴얼(5.2 LTS)은 Unit Scale이 화면에 표시되는 값만 바꾸고 내부 동작은 바꾸지 않는다고 설명합니다. 눈여겨볼 것은 FBX 내보내기의 Apply Scalings입니다. 기본값 All Local은 단위 배율을 각 오브젝트의 변환에 넣고 FBX 배율은 1.0으로 둡니다. 코드대로라면 한 변 2m 큐브는 three.js FBXLoader에서 한 변 200으로 읽힙니다. FBX Units Scale을 고르면 오브젝트 배율은 1로 남고 UnitScaleFactor가 100이 되어, 같은 큐브가 three.js에서 2로 읽힙니다. 옵션 설명에도 Blender는 FBX 배율로 단위를 판단하지만 다른 프로그램은 그렇지 않을 수 있다는 주의가 붙어 있습니다.

3ds Max는 시스템 단위 기본값이 인치입니다. Autodesk 도움말에 따르면 표시 단위(Display Unit)는 뷰포트에 보이는 숫자만 바꾸고, 실제 크기는 시스템 단위가 정합니다. 표시 단위를 센티미터로 바꿔 놓아도 시스템 단위가 인치면 인치 장면입니다. FBX 플러그인은 기본적으로 이 시스템 단위를 그대로 파일 단위로 쓰고 Scale Factor 1.0, 즉 변환 없이 내보냅니다. 문서대로라면 인치 장면을 그대로 내보낸 파일은 키 170cm 인물이 66.9로 읽히는 인치 파일이 됩니다. 이 사이트의 시험 파일인 3ds Max 리그 Character_0726.fbx는 163×170×29로 읽혔으니 센티미터 크기의 숫자로 저장된 경우입니다.

Unity 매뉴얼(Unity 6.6)은 물리 시스템이 게임 세계의 1m를 1 unit으로 기대한다고 적고, 모델 가져오기 설정에 Scale Factor와 Convert Units를 둡니다. Convert Units는 모델 파일에 정의된 배율을 Unity 크기로 바꿉니다.

경계 상자 키와 UnitScaleFactor로 배율 가려내기

  1. 세 축 치수 재기. three.js라면 불러온 모델의 경계 상자를 구하고, 로더가 적어 둔 단위 값도 같이 찍어 봅니다.
  2. 세 축 비율 비교. 사람 캐릭터 기준으로 키만 정상이고 폭이나 두께가 몇 배씩 틀리면 단위가 아니라 바인드나 본 문제입니다.
  3. 키 숫자를 사람 키와 대조. 1.5~1.9면 미터, 150~190이면 센티미터, 59~75면 인치, 1,500~1,900이면 밀리미터 숫자입니다.
  4. UnitScaleFactor 확인. three.js에서는 userData.unitScaleFactor, ASCII FBX는 텍스트 편집기에서 UnitScaleFactor를 검색하면 됩니다. Blender로 가져왔을 때 키가 1.7m인데 웹 도구에서 170이면 파일 정보는 맞고 도구가 센티미터를 미터로 바꾸지 않은 것입니다.
  5. 원본 프로그램 설정 확인. 3ds Max의 System Unit Setup, Blender의 Units 패널과 FBX 내보내기 옵션입니다.
const box = new THREE.Box3().setFromObject(model);
const size = box.getSize(new THREE.Vector3());
console.log(size.x, size.y, size.z, model.userData.unitScaleFactor);

r160은 최상위에 그룹 하나만 있는 파일이면 그 그룹을 대신 반환하면서 이 값을 빠뜨려 undefined가 찍힐 수 있습니다(dev 브랜치에서는 옮겨 담도록 고쳐졌습니다). 변환 전에 모델이 제대로 읽히는지부터 보려면 3D 모델 뷰어에 넣어 볼 수 있습니다. GLB 파일로 확인했을 때 파일 선택 뒤 서버로 가는 요청은 0건이었습니다.

크기를 맞추는 두 가지 방법

첫째, 단위 정보를 믿고 환산합니다. 로더가 UnitScaleFactor를 적용하지 않는 경우라면 “미터 키 = 읽힌 키 × UnitScaleFactor ÷ 100″입니다. 앞의 Blender 큐브로 확인하면 All Local 파일은 200 × 1 ÷ 100 = 2m, FBX Units Scale 파일은 2 × 100 ÷ 100 = 2m로 둘 다 맞습니다. 원래 키가 보존되어, UnitScaleFactor가 1인 파일이라면 172.36은 1.7236m가 됩니다. 약점은 단위 정보가 틀렸거나, 앞의 모캡 파일처럼 바인드 이후에 변환이 섞인 파일에서는 틀린 크기를 그대로 믿는다는 점입니다.

둘째, 목표 키에 맞춥니다. 이 사이트의 변환기가 쓰는 방식으로, 모델의 키를 재서 1.6m가 되도록 배율을 정합니다. 시험 파일 세 개의 원본 키 172.36, 169.77, 170.16에 대해 배율은 각각 0.0093, 0.0094, 0.0094였습니다. 단위 정보가 비었거나 틀려도 결과가 항상 사람 크기로 나온다는 게 장점이고, 원래 키가 사라진다는 게 단점입니다. 172cm로 설계된 캐릭터도 160cm가 됩니다. VR처럼 눈높이가 실제 키와 맞아야 하는 곳에 쓸 아바타라면 첫째 방법으로 환산하거나, 변환 뒤에 원하는 키로 다시 맞추는 편이 낫습니다.

시험 파일 세 개의 원본 키와 0.01 단위 환산 결과, 1.6m 정규화 배율을 비교한 표
단위 환산은 원래 키를 지키고, 목표 키 정규화는 단위 정보가 틀려도 항상 같은 크기를 보장합니다.

크기를 바꿀 때 같이 바뀌어야 하는 것

배율을 정했으면 모델의 길이 값 전부에 똑같이 적용해야 합니다.

  • 정점 좌표와 모프 타깃: 표정용 모프 타깃의 이동량도 길이라서, 메시만 줄이면 표정을 켜는 순간 얼굴이 튀어나옵니다.
  • 본의 로컬 위치: 회전은 단위와 무관하지만 부모에서 떨어진 거리는 길이입니다.
  • 스킨의 역바인드 행렬: 행렬의 이동 성분이 옛 단위로 남으면 본과 메시가 어긋납니다.
  • 애니메이션의 위치 트랙: VRM 1.0 휴머노이드 규정은 hips를 보통 유일하게 이동하는 본으로 봅니다. hips 이동 값을 그대로 두면 줄어든 몸이 옛 숫자만큼 움직여 100배 멀리 미끄러집니다.

루트 노드에 배율 하나만 걸어 두는 방법도 있지만, 본과 애니메이션을 따로 다루는 프로그램에서는 그 배율이 빠질 수 있어 값 자체를 바꿔 두는 편이 안전합니다.

단위와 함께 자주 틀어지는 것이 방향과 바닥 높이입니다. glTF 에셋의 정면은 +Z이고, VRM 1.0의 T포즈 규정도 몸과 발끝이 +Z를 향하고 발바닥이 Y 0.0에 닿도록 정합니다. 변환기는 정면 방향을 자동으로 감지해 모델을 돌리고 VRM 정면(+Z)을 화면에 파란 화살표로 표시하니, 크기를 확인한 뒤 얼굴이 화살표 쪽을 보는지도 한 번 더 보면 됩니다. 크기와 방향이 맞았는데도 팔이 엉뚱하게 꺾인다면 그다음은 본 이름 문제입니다. Mixamo FBX를 VRM 본에 매핑하는 방법에서 이어서 다룹니다.

참고한 자료

위로 스크롤