2D 스켈레탈 애니메이션: 메시 디포메이션(Mesh Deformation) 원리와 버텍스 가중치 최적화 가이드
2D 스켈레탈 애니메이션의 메시 디포메이션과 리니어 블렌드 스키닝 원리를 설명하고, 텍스처 왜곡과 버텍스 가중치를 점검하는 방법을 살펴봅니다.

핵심 요약
2D 스켈레탈 애니메이션의 메시 디포메이션(Mesh Deformation)은 텍스처 평면을 삼각형 메시로 나누고 본(Bone)의 변환에 정점 가중치를 적용해 굴곡을 연출하는 기술입니다. 아래 토폴로지와 영향 본 수는 출발점으로 삼을 수 있는 제작 지침이며, 실제 품질과 성능은 캐릭터와 엔진 구현에 따라 검증해야 합니다.
2D 메시 디포메이션(Mesh Deformation)의 동작 원리
컷아웃(Cutout) 방식은 관절 단위로 이미지를 나누고 각 파츠를 회전시켜 움직임을 만듭니다. 파츠의 연결과 회전만으로 구성하면 관절 연결 부위가 어긋나거나 종이 인형처럼 보일 수 있습니다.
메시 디포메이션은 스프라이트 텍스처를 촘촘한 정점(Vertex)과 폴리곤(Polygon)으로 구성된 2D 평면 메시로 변환한 뒤 본(Bone)의 움직임에 따라 정점 위치를 실시간으로 이동시켜 유기적인 휨과 찌그러짐을 구현합니다.
스프라이트 컷아웃 vs 메시 디포메이션 비교
| 구분 | 스프라이트 컷아웃 (Cutout) | 자유 형태 변형 (FFD / Mesh Deformation) | 스킨드 메시 디포메이션 (Skinned Mesh) |
|---|---|---|---|
| 구조 | 단순 사각형(Quad) 스프라이트 계층 | 단일 텍스처에 메시 생성 후 수동 키프레임 | 메시에 복수 본(Bone)을 바인딩하고 가중치 할당 |
| 곡선 표현 | 파츠와 관절 구성에 따라 제한될 수 있음 | 가능하지만 버텍스 키프레임 작업이 필요할 수 있음 | 메시 토폴로지와 가중치에 따라 부드러운 변형 가능 |
| 데이터 용량 | 파츠와 트랜스폼 데이터에 따라 다름 | 버텍스 오프셋을 프레임마다 저장하면 데이터가 커질 수 있음 | 본 키프레임과 바인드 가중치를 저장하는 방식 |
| 연산 비용 | 파츠 수와 렌더링 방식에 따라 다름 | 구현에 따라 다름 | 정점·영향 본 수와 CPU/GPU 경로에 따라 다름 |
리니어 블렌드 스키닝(Linear Blend Skinning, LBS) 수식
이 글에서는 각 정점의 본별 변환을 가중합하는 리니어 블렌드 스키닝(LBS) 모델로 2D 메시 변형을 설명합니다. Spine은 이 방식을 weights 또는 linear blend skinning이라고 부르지만, 도구마다 데이터와 런타임 구현은 다를 수 있으므로 특정 엔진의 동작은 해당 버전 문서를 확인해야 합니다.
정점의 초기 로컬 좌표를 , 정점에 영향을 주는 본 의 인덱스를 , 해당 본에 대한 정점 가중치를 , 본의 바인드 포즈 역행렬을 , 현재 프레임의 월드 변환 행렬을 라고 할 때, 변형된 최종 정점 위치 는 다음과 같이 계산됩니다.
가중치 합을 1로 정규화하면 본 변환의 가중합이 좌표 원점이나 크기를 의도치 않게 바꾸는 일을 방지할 수 있습니다. 이는 LBS의 일반적인 불변 조건이지만, 정규화만으로 모든 변형 왜곡이 사라지는 것은 아닙니다.
flowchart LR
A["원래 정점 위치 v0"] --> B["바인드 포즈 역변환 (B^-1)"]
B --> C["본 로컬 공간 좌표"]
C --> D["현재 본 변환 행렬 (M)"]
D --> E["본별 변환된 위치"]
E --> F["가중치(w_i) 가중합산"]
F --> G["최종 변형 정점 v'"]
메시 토폴로지 설계: 텍스처 왜곡과 핀치(Pinch)는 왜 발생하는가?
메시 디포메이션에서 점검할 문제로는 팔이나 다리가 접힐 때 텍스처가 찌그러지는 현상(Texture Pinching)이나 외곽선이 각져 보이는 현상이 있습니다.
이러한 왜곡은 삼각형 분할(Tessellation) 방향이 굴곡선과 맞지 않거나 관절 주변의 정점 밀도가 부족할 때 발생할 수 있습니다.
flowchart LR
subgraph Bad ["잘못된 토폴로지"]
direction TB
B1["단순 대각선 분할 (에지 밀도 부족)"]
B2["❌ 관절 굽힘 시 대각선 텍스처 왜곡 및 핀치(Pinch) 발생"]
B1 --> B2
end
subgraph Good ["관절 주변의 에지 루프 토폴로지"]
direction TB
G1["관절 피벗 주변에 충분한 에지 루프 배치"]
G2["✅ 굽힘 축을 따라 고르게 압축/신장 분산"]
G1 --> G2
end
Bad == "토폴로지 최적화" ==> Good
굴곡 부위 토폴로지 설계 3단계 가이드
- 외곽선 피팅(Outline Snapping)
투명 여백이 큰 스프라이트에서는 불투명 경계에 맞춰 메시를 다듬어 그려지는 영역을 줄일 수 있습니다. 다만 외곽선 품질과 정점 처리 비용을 함께 확인합니다. - 관절 굽힘선 주변에 에지 루프(Edge Loop) 배치
관절 회전 중심축(피벗) 주변의 메시 밀도를 높이면 굽힘을 더 세밀하게 표현할 수 있습니다. 필요한 루프 수와 위치는 메시 크기와 변형 범위에 맞춰 정하고 실제 포즈에서 확인합니다. ‘3-Cut’은 일부 리깅에서 쓸 수 있는 휴리스틱이지 필수 규칙은 아닙니다. - 삼각형 대각선 에지 방향(Turn Edge) 정리
자동 생성된 들로네 삼각분할(Delaunay Triangulation) 메시에서는 에지 방향이 관절 굽힘에 적합하지 않을 수 있습니다. 굽힘 방향에 맞춰 에지를 수동으로 회전(Turn)시키면 해당 포즈의 텍스처 늘어남을 줄이는 데 도움이 될 수 있습니다.

버텍스 가중치(Vertex Weights) 페인팅과 바인딩 최적화
메시를 구성한 후에는 사용하는 스키닝 방식에 맞춰 뼈대(Bones)와 정점 가중치를 바인딩합니다. 가중치 분배나 토폴로지가 포즈에 맞지 않으면 관절이 회전할 때 피부가 찢어지거나 고무처럼 늘어나는 결함이 나타날 수 있습니다.
1. 정점당 영향 본(Influence) 수 제한
모바일 2D 게임에서는 연산 비용과 변형 품질을 함께 확인하면서 정점 1개에 영향을 주는 본의 개수를 조정합니다.
- 단단한 부위(무기, 갑옷 장식): 본 1개 (가중치 1.0, 리지드 바인딩)
- 일반 관절(팔, 다리, 꼬리): 본 최대 2개 ()
- 복합 변형 부위(의상 자락, 머리카락 교차점): 본 최대 4개
2. 가중치 정규화(Weight Normalization) 처리
브러시 툴로 가중치를 편집할 때 정점의 가중치 합이 1.0에서 벗어날 수 있습니다. 아래 예제의 LBS에서는 합을 1로 정규화해 가중합이 예상치 않은 크기 변화를 만들지 않도록 합니다. 실제 엔진은 자체적인 가중치 처리 규칙을 가질 수 있으므로, 엔진의 입력 규칙을 확인하십시오.
using System;
public struct BoneWeight2D
{
public int boneIndex0;
public int boneIndex1;
public float weight0;
public float weight1;
// 2-Bone 가중치 정규화 유틸리티
public void NormalizeWeights()
{
float totalWeight = weight0 + weight1;
if (totalWeight > 0.0001f)
{
weight0 /= totalWeight;
weight1 /= totalWeight;
}
else
{
// 가중치가 모두 0인 예외 상황 방어: 기본 본에 100% 할당
weight0 = 1.0f;
weight1 = 0.0f;
}
}
}
3. 스무스 가중치(Smooth Weight) 감쇠 수식
관절 중심으로부터의 거리 에 따라 코사인(Cosine) 또는 부드러운 스텝(Smoothstep) 곡선을 적용하면 단일 본의 영향 가중치를 부드럽게 줄일 수 있습니다. 여러 본의 가중치를 함께 만들 때는 합이 1이 되도록 별도로 정규화해야 합니다. 이 방식만으로 LBS의 관절 볼륨 손실(Volume Loss)을 해결하지는 못합니다.
런타임 성능 최적화: 버텍스 수와 드로우콜 제어
화면에 메시 디포메이션 캐릭터가 많이 등장하면 CPU 스키닝 연산이나 GPU 정점 처리·대역폭이 병목이 될 수 있습니다. 병목 수치는 캐릭터 메시, 엔진 경로, 기기에 따라 달라지므로 프로파일링으로 확인합니다.
CPU 스키닝 vs GPU 셰이더 스키닝 비교
아래 표는 일반적인 CPU/GPU 처리 경로를 개념적으로 비교한 것입니다. 실제 버퍼 전달 방식과 배칭 결과는 엔진·패키지 버전 및 구현에 따라 다릅니다. Unity 2D Animation의 CPU/GPU 변형 선택에는 해당 패키지 문서와 프로파일링 결과를 적용합니다.
| 항목 | CPU 소프트웨어 스키닝 | GPU 버텍스 셰이더 스키닝 |
|---|---|---|
| 동작 방식 | CPU에서 정점 좌표를 계산해 VBO/동적 메시 버퍼 갱신 | 본 행렬 배열을 유니폼/텍스처로 넘겨 버텍스 셰이더에서 계산 |
| 장점 | 배칭(Sprite Batching) 및 아틀라스 통합이 용이할 수 있음 | 정점 스키닝 계산을 GPU로 옮겨 CPU 작업을 줄일 수 있음 |
| 주의점 | 정점 좌표 갱신 비용과 CPU 부하를 프로파일링 | 본 행렬 전달 방식과 셰이더 비용을 프로파일링 |
| 검토 기준 | CPU 변형 비용과 동적 배칭 효과를 프로파일링 | GPU 부하와 정점 처리량을 프로파일링 |
런타임 최적화 체크리스트
- 투명 픽셀 제거를 통한 필레이트(Fillrate) 절약
투명 여백이 큰 쿼드(Quad)는 보이지 않는 픽셀도 셰이더가 처리할 수 있어 오버드로우를 늘립니다. 다만 외곽선을 따라 메시를 세분화하면 정점·삼각형 처리량이 증가하므로, 타깃 기기에서 두 비용을 함께 측정합니다. - 정적 파츠의 본 바인딩 분리
변형이 필요 없는 눈동자, 벨트, 무기 등의 파츠는 메시 디포메이션을 적용하지 않고 단순 스프라이트 어태치먼트(Attachment)로 연결하여 불필요한 스키닝 연산을 제거합니다. - LOD(Level of Detail) 메시 구성
원거리 몬스터에는 정점 수와 본 영향을 줄인 간이 메시를 검토합니다. 감축 폭은 화면 크기와 품질 목표에 따라 프로파일링으로 정합니다.

자주 묻는 질문 (FAQ)
Q1. 2D 캐릭터 1개당 적절한 버텍스 개수는 몇 개인가요?
정답으로 통용되는 정점 수는 없습니다. 이 글의 예시 범위(주인공 300~600개, 일반 몬스터 80~150개)는 초기 프로토타입에서 시험할 휴리스틱일 뿐이며, 목표 기기와 화면 동시 출현 수를 기준으로 프로파일링해 조정합니다. 전체 정점 합계도 프로젝트별 성능 예산으로 정합니다.
Q2. 팔이나 다리를 180도 접었을 때 관절이 찌그러지는 캔디 래퍼(Candy-wrapper) 왜곡은 어떻게 해결하나요?
캔디 래퍼 왜곡은 주로 팔·다리처럼 길쭉한 부위를 장축 주위로 크게 비틀 때 나타나는 LBS의 부피 손실 현상입니다. 단순히 팔꿈치나 무릎을 180도 굽히는 경우와 같은 설명은 정확하지 않습니다. 보조 본, 변형 보정, 다른 스키닝 기법 등을 검토하되 구체적인 해결책은 해당 리그와 엔진에 맞춰 검증합니다.
Q3. Spine이나 Unity 2D Animation에서 가중치 자동 바인딩 후 수동 수정은 필수인가요?
항상 필수인 것은 아닙니다. 자동 가중치 결과가 겹친 부위나 의도한 변형을 제대로 처리하는지 포즈에서 확인하고, 오류가 보일 때 수동으로 수정합니다. 2D에서도 깊이 순서와 리그 구성은 도구와 메시 데이터에 따라 처리 방식이 다를 수 있습니다.
정리 및 결론
2D 스켈레탈 애니메이션의 메시 디포메이션은 표현력과 성능 사이의 정밀한 균형 감각이 필요한 테크니컬 아트 영역입니다.
- 관절의 굽힘 방향에 맞춰 필요한 에지 루프 토폴로지를 구성하십시오.
- 일반 관절은 영향 본을 2개부터 검토하고, 복합 변형은 필요한 본 수를 프로파일링해 정규화된 가중치로 구성하십시오.
- 캐릭터 규모와 밀도에 맞춰 CPU 배칭 스키닝과 GPU 셰이더 스키닝 중 최적의 파이프라인을 선택하십시오.



