프레임 하나도 애니메이션하지 않고 스파이더맨을 흔들리게 만든 방법
요약
본 글은 애니메이션 경험이 전무한 개발자가 Blender와 LLM을 결합한 시스템으로 복잡한 3D 캐릭터 애니메이션을 구현하는 과정을 설명합니다. 핵심은 'blender-mcp'라는 도구로, Claude Code 같은 LLM 클라이언트가 Model Context Protocol(MCP)을 통해 Blender의 Python API(`bpy`)를 제어할 수 있게 만든 것입니다.
핵심 포인트
- LLM과 3D 소프트웨어 연동: blende-mcp는 LLM이 Blender를 제어하게 합니다.
- 핵심 원리: MCP를 통해 JSON 명령으로 `bpy` 코드를 실행합니다.
- 작동 루프: 에이전트가 변경-캡처-검사하는 편집/실행/검사 사이클을 사용합니다.
- 주의사항: 이 시스템은 임의 코드 실행(arbitrary code execution) 위험이 있습니다.
안녕하세요, 저는 Maneshwar입니다. 비즈니스 핵심 시스템을 위해 제작된, 폭발 반경(blast-radius) 인지 AI 코드 리뷰 도구인 LiveReview를 만들고 있습니다. 개발자들이 프로젝트를 발견하고, 사용해 보고, 제품 개선에 도움을 줄 수 있도록 저희 GitHub에서 별점을 주시면 감사하겠습니다.
네, 그가 마일스 모랄레스입니다.
그는 웹에 떨어져 슈퍼히어로처럼 웅크리고 착지한 뒤, 화면 밖으로 거미줄을 발사하고 거대한 DEV 보드를 끌어오는 장면을 연출합니다.
저는 이 동작의 단 한 프레임도 손으로 애니메이션 하지 않았습니다.
또한 이번 주가 되기 전에는 Blender를 사용해 본 적이 없었습니다.
이번 글은 어떻게 그런 일이 일어났는지, 그리고 '단순한' 3D 캐릭터 안에 얼마나 놀라운 컴퓨터 과학 지식이 숨겨져 있는지에 대한 이야기입니다.
왜 하필 Blender였을까
저는 비디오를 만들려고 했습니다.
화면 녹화가 아니라, 실제로 움직이는 무언가가 들어간 영상이었습니다.
저의 첫 번째 선택지는 HTML로 영상을 작성하고 렌더링할 수 있게 해주는 [HyperFrames]였습니다.
모션 그래픽스 분야에서는 정말 뛰어납니다.
슬라이드되는 텍스트, 팝업되는 로고, 스스로 그려지는 차트 등 모든 것이 멋집니다.
하지만 캐릭터가 무언가를 움직이게 해야 하는 순간에 벽에 부딪혔습니다.
HTML은 사각형을 아름답게 움직일 수 있습니다.
하지만 사람이 거미줄에 매달려 흔들리는 것을 만들 수는 없습니다.
그래서 다음 질문은 명확했지만, 조금 두려웠습니다. 실제 애니메이터들은 무엇을 사용할까요?
무료로 오픈 소스로 이용 가능한 답은 [Blender]였습니다.
그리고 Blender에는 MCP 서버가 있어서, 제가 혼자서 배우지 않아도 된다는 의미였습니다.
모든 것을 가능하게 만든 MCP
완전 초보자인 저에게 이것이 가능하게 만든 것이 바로 [blender-mcp]입니다.
이것은 Blender를 Claude Code 같은 LLM 클라이언트와 연결하여, 400개의 메뉴를 헤매지 않고도 "이 모델을 로드하고 텍스처를 다시 연결해라"라고 말하기만 하면 실행되는 역할을 합니다.
그 아키텍처는 이해할 가치가 있습니다. 왜냐하면 들리는 것보다 훨씬 간단하기 때문입니다.
flowchart LR
ME[Me typing a prompt] --> CC[Claude Code]
CC -->|MCP over stdio| SRV[blender-mcp server]
...
이 시스템은 두 부분으로 나뉩니다.
**Blender 내부의 애드온(add-on)**은 작은 소켓 서버를 열고 명령을 기다립니다.
Blender 외부의 MCP 서버는 한쪽에서 Model Context Protocol을 통해 LLM과 통신하고, 다른 쪽에서는 해당 소켓으로 JSON 형식의 명령을 전달합니다.
이 시스템이 노출하는 가장 강력한 도구는 execute_blender_code이며, 이는 Blender의 Python API인 bpy를 통해 임의의 파이썬 코드를 실행합니다.
Blender의 모든 버튼은 본질적으로 bpy 위에 얇게 덮인 피부(thin skin)에 불과합니다.
따라서 bpy를 작성할 수 있는 에이전트는 원칙적으로 모든 버튼을 누를 수 있습니다.
이 시스템을 작동하게 만드는 루프는 스크린샷 도구가 반대 방향으로 돌아오는 것입니다.
에이전트가 무언가를 변경하고, 뷰포트를 캡처하며, 그것을 '보고', 다음에 무엇을 수정할지 결정합니다.
이는 코드를 다룰 때 사용하는 것과 동일한 편집(edit)-실행(run)-검사(inspect) 루프이지만, 대상이 3D 장면에 맞춰진 것입니다.
솔직히 경고하자면: 이 도구는 설계상 임의 코드 실행(arbitrary code execution)입니다. 마치 셸을 이용한 모든 로컬 자동화 작업처럼 취급해야 하며, 비밀 정보가 가득한 기계에 연결해서는 안 됩니다.
1단계: 캐릭터 가져오기
저는 3D 모델러가 아니었고, 금요일까지 그렇게 될 계획도 없었습니다.
그래서 Sketchfab에서 미스토리가 등장하는 마일스 모랄레스(Miles Morales) 모델, 즉 스파이더버스 스파이더맨을 가져왔습니다.

'단순히 불러오기(just load it)'하는 것조차 배울 점이 있었습니다.
파일에는 마스크를 쓴 상태와 벗은 상태, 포즈를 취한 상태와 T-포즈의 마일스 네 개 복사본이 나란히 들어있었습니다.
텍스처는 C:\[사용자 이름]\[바탕 화면]...과 같은 원작자의 Windows 폴더를 가리키고 있었기 때문에, 에이전트는 이를 zip 파일 내의 파일들로 다시 연결해야 했습니다.
게다가 zip 파일에는 노멀 맵(normal map)과 스페큘러 맵(specular map)이 빠져 있었습니다.
Blender에서 누락된 파일을 가리키는 텍스처 노드는 핫핑크색으로 렌더링됩니다.
이는 3D 세계의 404 에러와 같으며, 매우 눈에 잘 띕니다.
해결책은 해당 슬롯들을 연결 해제하는 것이었지만, 그 대가로 슈트의 일부 표면 디테일을 포기해야 했습니다.
그리고 마스크가 벗겨진 Miles를 열자 그의 얼굴은 흰색 선과 점들로 뒤덮여 마치 공포 영화 속 같았다.
사실 그 얼굴은 괜찮았다.
해당 모델에는 눈꺼풀, 눈썹, 입술, 턱, 볼, 심지어 혀까지 포함된 **143개 본(bone)의 페이스 리그(face rig)**가 장착되어 있었고, 아머처는 '앞에서 그리기(draw in front)'로 설정되어 있어 이 모든 본들이 그의 피부 위에 그려져 있었다.
체크박스 하나를 거치자 그는 다시 잘생겨졌다.
모든 것을 여는 개념: 리그잉 (rigging)
여기서 내가 이 포스트의 나머지 부분이 의존하는 단어를 배웠다.
3D 캐릭터는 본질적으로 **메시(mesh)**이다. 즉, 삼각형으로 붙여진 정점(vertex)들의 거대한 목록이다 (Miles는 약 27k 개의 면을 가지고 있다).
메시는 조각상과 같다.
조각상으로는 흔들리는 동작을 만들 수 없다.
이것을 움직이게 하려면 세 가지가 더 필요하다.
아머처(armature), 즉 뼈대이다.
이는 **본(bone)**의 나무 구조이며, 각 본은 다음 본의 부모 역할을 한다: 골반 → 척추 → 가슴 → 어깨 → 위팔 → 아래팔 → 손목 → 손가락.
어깨를 회전시키면 그 아래에 있는 모든 것이 함께 움직인다. 이는 어떤 게임 엔진의 트랜스폼 계층 구조(transform hierarchy)나 CSS transform을 가진 중첩된 <div>와 정확히 같다.
**스킨 웨이트(skin weights)**는 메시를 뼈대에 연결하는 역할을 한다.
모든 정점은 각 본이 자신에게 얼마나 영향을 미치는지 알려주는 작은 표를 저장하고 있다.
아래팔의 한 정점은 100% forearm일 수 있다.
팔꿈치 바로 위의 정점은 50% upper_arm과 50% forearm일 수 있는데, 이것이 종이가 빨대처럼 접히지 않고 팔꿈치가 부드럽게 구부러지도록 하는 원리이다.
이 수학적 계산을 선형 블렌딩 스킨닝(linear blend skinning)이라고 하며, 이는 행렬들의 가중 평균에 불과하다:
final_position(v) = Σ weight(v, bone) × bone_matrix × rest_position(v)
bones
**휴식 자세(rest pose)**는 모든 것이 측정되는 기준점이다.
이것이 다운로드하는 모든 캐릭터가 팔을 쭉 뻗은 T-pose로 서 있는 이유다.
그것은 안무 동작이 아니다.
그것은 원점, 즉 몸의 git init이며, 모든 애니메이션은 이 기준점에 상대적인 회전으로 저장된다.
이것들을 조합하면 **리그(rig)**가 완성되는 것이다.
그리고 그 순진한 계획은 무너졌는데, 모델의 리그에는 뼈대(bones)만 있을 뿐 _컨트롤러(controls)_가 없었기 때문이다.

순운동학(Forward kinematics) 대 역운동학(Inverse kinematics)
나는 애니메이터가 캐릭터의 엉덩이를 잡고 아래로 끌어내리면, 발은 바닥에 붙어 있는 상태에서 무릎만 구부러지는 유튜브 영상을 본 적이 있다.
내가 마일스(Miles)의 엉덩이를 끌어내리자, 그의 온몸이 유령처럼 바닥을 통과하며 떠내려갔다.
그 차이는 이 분야 전체에서 가장 멋진 아이디어 중 하나이다.
**순운동학 (Forward kinematics, FK)**은 날것의 뼈대(raw skeleton)가 하는 방식이다.
모든 관절의 각도를 설정하면, 손은 회전 사슬이 놓는 곳 어디에나 있게 된다.
계산하기는 쉽지만, 애니메이션 하기는 지옥 같다. 문고리 위에 손을 놓고 싶다고? 그곳에 손을 위치시키는 어깨, 팔꿈치, 손목 각도를 추측하는 것은 행운을 빌어야 한다.
**역운동학 (Inverse kinematics, IK)**은 질문을 뒤집는다.
손(또는 발)이 어디에 있어야 하는지 말하면, 솔버(solver)가 거꾸로 작동하여 그곳에 손을 위치시키는 관절 각도를 찾아낸다.
이는 문자 그대로 매 프레임마다 해결되는 최적화 문제(optimisation problem)이며, Blender는 이를 처리하는 IK 제약 조건(IK constraint)을 제공한다.
발에 IK 타겟(targets)을 고정하고 엉덩이를 끌어내리면, 발이 움직일 수 없기 때문에 솔버는 무릎을 구부릴 수밖에 없다.
그것이 유튜브 영상 속의 마법이다.
마법이 아니라, 제약 조건 해결사(constraint solver)인 것이다.
하지만 전체 IK 컨트롤 리그를 손으로 만드는 것은 정말 기술적인 작업이다.
그리고 나는 이번 주에 마일스가 백플립을 하는 모습을 원했고, 다음 분기가 아니었다.
Mixamo: 서비스를 이용한 리깅(rigging)
Adobe의 무료 자동 리거 및 애니메이션 라이브러리인 Mixamo를 소개한다.
작업 흐름은 이렇다: 캐릭터를 T-포즈 상태의 FBX로 내보내기(export), 업로드하고, Mixamo가 뼈대와 스킨 가중치(skin weights)를 구축해준다.
사용자가 해야 할 일은 몇 개의 마커를 배치하는 것뿐입니다.

턱(Chin), 손목(wrists), 팔꿈치(elbows), 무릎(knees), 사타구니(groin).
대칭 기능이 켜진 상태에서 다섯 개의 랜드마크만 지정하면 되므로, 사실상 측면당 단 세 번의 클릭이면 충분합니다.
이를 통해 시스템은 전체 골격을 추론해내는데, 이는 인간 신체가 얼마나 많은 구조를 가지고 있는지 상기시켜주는 좋은 예시입니다. 관절 위치만 안다면 나머지 부분은 대부분 비율 문제입니다.
배치(Placement)가 생각보다 훨씬 중요합니다.
제가 처음 시도했을 때는 손목을 팔뚝 위에 놓았는데, 그러면 거미줄을 쏠 때마다 손이 잘못된 방향으로 구부러지게 만들었습니다.
저는 손가락뼈까지 포함하는 **Standard Skeleton (65)**를 선택했는데, 이는 손가락 없이 두 손으로 당기는 동작은 마치 오븐 장갑을 낀 사람처럼 보이게 하기 위해서였습니다.
그러자 정말... 작동했습니다.

리깅된 캐릭터는 Mixamo의 모션 캡처 애니메이션 라이브러리로 바로 들어갑니다.
이 동작들은 실제 퍼포머들이 모캡(mocap) 수트를 입고 녹화하고 정리한 것이기 때문에, 핸드 키잉 애니메이션으로는 재현하기 어려운 무게 이동이나 미세한 떨림까지 가지고 있습니다.
점프, 등반, 매달리기, 던지기, 춤추기, 넘어지기 등 모든 동작이 가능합니다.


한 가지 트레이드오프(trade off)가 있었는데, 그 부분이 조금 아쉬웠습니다.
Mixamo는 자체적인 바디 스켈레톤을 만듭니다.
모델이 기본으로 제공하는 아름다운 143개 본리깅(bone face rig)에 대해서는 알지도 못하고 신경 쓰지도 않습니다.
“스킨 포함”과 “스킨 미포함”
애니메이션을 다운로드할 때 Mixamo는 사용자에게 **스킨 포함(with skin)**으로 받을지, 아니면 **스킨 미포함(without skin)**으로 받을지 묻습니다.
이것은 데이터를 표현 방식과 분리하는 좋은 교훈입니다.
스킨 포함 옵션은 메쉬(mesh), 스켈레톤(skeleton), 그리고 모션(motion)을 제공합니다.
스킨 미포함 옵션은 오직 스켈레톤과 모션만을 제공하며, 이는 시간에 따른 본 회전 값 몇백 킬로바이트에 불과합니다.
모든 클립이 동일한 65개 본 스켈레톤과 동일한 본 이름을 대상으로 하기 때문에, 스킨은 단 한 번만 필요합니다.
나머지 모든 것은 본 이름으로 키가 지정된 키프레임 데이터일 뿐이며, Blender는 본이 일치하는 어떤 아마추어(armature)에도 기꺼이 이를 적용합니다.
그래서 저는 첫 번째 클립은 스킨 포함으로 다운로드하고 나머지는 스킨 미포함으로 다운로드했습니다.
그리고 저는 그것들을 아주 많이 다운로드했습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기