왜 이미지 모델만으로는 안 되는가
게임용 스프라이트 시트는 단순히 예쁜 그림이 아닙니다. 프레임이 수학적으로 정확한 격자에 맞아야 하고, 캐릭터가 매 프레임 중앙에 있어야 하며, 배경은 완벽히 투명해야 합니다.
이미지 생성 모델은 이런 규칙을 자주 어깁니다. 특히 걷기나 달리기처럼 다리 움직임이 핵심인 애니메이션에서 오류가 많습니다. 프레임마다 위치가 흔들리고, 배경이 섞이고, 캐릭터 비율이 변합니다.
그래서 이미지 모델 + 비디오 모델 + 로컬 파이썬 스크립트 세 가지를 조합해야 합니다. 각 도구가 잘하는 것만 하게 만드는 것이 이 파이프라인의 핵심입니다.
이미지 모델로 깨끗한 첫 포즈를 만들고, 비디오 모델로 자연스러운 움직임을 만든 뒤, 파이썬으로 프레임 추출부터 스프라이트 시트 생성까지 자동화한다.
전체 파이프라인 한눈에 보기
Step 1. 이미지 모델로 첫 포즈 만들기
GPT Image, Nano Banana 같은 이미지 모델로 캐릭터의 첫 포즈를 만듭니다. 이 단계에서 배경과 여백을 어떻게 설정하느냐가 전체 파이프라인의 성패를 가릅니다.
#00FF00Step 2. 비디오 모델로 움직임 만들기
첫 포즈를 Kling 같은 비디오 모델에 넣고 애니메이션 영상을 만듭니다. 여기서 핵심은 프롬프트를 기계적으로 쓰는 것입니다. 감성적 표현은 모델을 혼란스럽게 만듭니다.
캐릭터가 검을 머리 위로 들어 올리고, 잠깐 준비 자세를 취한 뒤, 한 걸음 앞으로 움직이며 아래로 검을 내려친다.
이후 후속 동작을 거쳐 준비 자세로 돌아온다.
카메라는 고정되어야 하며, 줌/팬/회전/흔들림이 없어야 한다.
캐릭터는 화면 중앙에 유지되고, 전체 몸과 검은 프레임 안에 있어야 한다.
배경은 항상 평평한
#00FF00 초록색이어야 한다.
비디오 모델 필수 조건
| 조건 | 이유 |
|---|---|
| 업로드 이미지를 첫 프레임으로 사용 | 캐릭터 일관성 유지 |
| 디자인, 의상, 비율, 무기, 얼굴 유지 | 캐릭터 변형 방지 |
| 카메라 고정 | 프레임 정렬 기준 보존 |
| 줌, 팬, 회전, 흔들림, 컷 전환 금지 | 동일 |
| 캐릭터 화면 중앙 유지 | 스프라이트 시트 정렬 |
| 크기 변화 금지 | 셀 크기 일관성 |
| 방향 전환 금지 | 좌우 반전 방지 |
배경 계속 #00FF00 | 크로마키 제거 가능 |
| 그림자, 바닥, 효과, 모션 블러 금지 | 깨끗한 알파 채널 |
단순한 픽셀 RPG 캐릭터라면 오히려 짧고 명확한 프롬프트가 좋습니다. 너무 긴 프롬프트는 모델이 불필요하게 캐릭터를 회전시키거나 재해석하게 만들 수 있습니다.
Step 3. 비디오에서 프레임 추출하기
로컬에서 FFmpeg를 사용해 비디오의 모든 프레임을 PNG로 추출합니다. 이때 캐릭터만 잘라내지 않는 것이 중요합니다.
전체 비디오 캔버스가 정렬 기준이기 때문에, 캐릭터 주변을 프레임마다 다르게 자르면 애니메이션이 흔들립니다. 영상에서의 고정 카메라 위치를 그대로 보존해야 합니다.
1# tools/extract_frames_ffmpeg.py 2 3# 비디오 → 전체 프레임 PNG 추출 4# frame_0001.png, frame_0002.png, ... 5# 추출 정보 JSON 리포트 생성 6# FPS 샘플링, FFmpeg crop 옵션 지원
Step 4. 사용할 프레임 선택하기
추출된 프레임 중 실제 스프라이트에 넣을 프레임을 고릅니다. 균등 간격으로 고르면 안 되고, 동작의 흐름을 기준으로 선택해야 합니다.
프레임 선택 우선순위
- 시작 프레임 — 애니메이션의 첫 장면
- 마지막 프레임 — 루프 연결점
- 핵심 동작 프레임 — 타격 순간, 점프 정점 등
- 보간 프레임 — 핵심 동작 사이의 자연스러운 연결
공격 애니메이션을 예로 들면 준비 자세 → 예비 동작 → 검을 드는 동작 → 타격 순간 → 충격 → 후속 동작 → 회복 자세 순으로 읽기 쉬운 동작 흐름을 골라야 합니다.
보통 게임에는 12프레임 시트를 사용합니다. 24프레임 시트는 더 부드러운 참고용이나 느린 동작에 사용합니다.
Step 5. 배경 보정 (필요할 때만)
정상적이라면 #00FF00 크로마키 배경을 그대로 제거하면 됩니다. 하지만 배경이 흰색, 회색, 연한 색으로 생성되었거나 초록색이 정확하지 않을 때만 보정 스크립트를 사용합니다.
1# tools/matte_light_background.py 2 3# 프레임 모서리 색으로 배경색 추정 4# 비슷한 배경색 제거 5# 부드러운 알파 가장자리 생성 6# 리포트 생성
이 스크립트는 응급용입니다. 가장 좋은 방법은 처음부터 정확한 #00FF00 배경으로 만드는 것입니다. 보정은 품질 손실을 피할 수 없습니다.
Step 6. 초록 배경 제거 후 스프라이트 시트 만들기
파이프라인의 핵심 단계입니다. animation_pipeline.py가 선택된 프레임을 불러와 배경을 제거하고 스프라이트 시트를 생성합니다.
1# tools/animation_pipeline.py 처리 순서 2 31. 선택된 프레임 불러오기 42. #00FF00 배경 제거 53. 초록색 테두리 번짐 제거 64. 작은 노이즈 제거 75. 각 프레임을 256x256 투명 PNG로 변환 86. 가로형 스프라이트 시트 생성 97. 미리보기 이미지 생성 108. 검증 JSON 리포트 생성
출력 크기
| 프레임 수 | 시트 크기 |
|---|---|
| 12프레임 | 3072 x 256 |
| 24프레임 | 6144 x 256 |
preserve-canvas 모드
이 모드는 전체 비디오 캐릭터를 그대로 256x256 셀 안에 축소합니다. 캐릭터만 잘라내거나 매 프레임 중앙 정렬하지 않습니다. 이게 중요한 이유는, 캐릭터를 프레임마다 다시 정렬하면 가짜 카메라 움직임이 생기고 애니메이션이 흔들리기 때문입니다.
영상에서의 고정 카메라 위치를 그대로 보존해야 한다. 캐릭터를 프레임마다 재정렬하면 흔들린다.
Step 7. 결과 검수하기
완성된 시트를 바로 게임에 넣으면 안 됩니다. 반드시 다음 항목을 검수합니다.
- 리포트 상태가
pass인지 확인 - 시트 크기가 정확한지 확인
- 모든 프레임의 캔버스 크기가 같은지 확인
- 모든 프레임의 스케일과 위치가 같은지 확인
- 무기, 팔다리, 망토, 머리카락, 이펙트가 잘리지 않았는지 확인
- 중복 프레임이 의도된 것인지 확인
- 움직임이 튀지 않는지 확인
- 워터마크가 제거되었는지 확인
- 다른 캐릭터 애니메이션과 크기가 맞는지 확인
최종 파일 구조
Step 8. 로컬 미리보기 갤러리
스프라이트 시트를 쉽게 비교하려면 정적 HTML 뷰어를 만듭니다. build_sprite_gallery_manifest.py가 final_sprites/ 폴더를 스캔해서 매니페스트를 생성합니다.
Step 9. 임시 파일 정리하기
추출된 고해상도 프레임은 용량이 큽니다. 하지만 코딩 에이전트에게 파일을 바로 삭제하게 하지 말고, 사람이 확인 후 지울 수 있도록 정리 폴더로 옮기게 하는 것이 안전합니다.
보관 vs 정리
| 보관 | 정리 가능 |
|---|---|
| 최종 스프라이트 시트 | 추출된 전체 프레임 |
| 최종 프레임 셀 | 중간 선택 프레임 |
| JSON 리포트 | 실패한 영상 |
| Contact sheet | 재실행 폴더 |
| 최종 채택 원본 비디오 |
핵심 팁 모음
- 첫 포즈는 초상화가 아니라 애니메이션용으로 만들어야 합니다. 넉넉한 여백이 필수입니다.
- 비디오 모델은 첫 포즈보다 더 크게 움직이는 경향이 있습니다. 여유를 두세요.
- 공격, 점프, 달리기 등은 극단 포즈보다 전환 포즈에서 시작하는 것이 좋습니다.
- 프롬프트는 감성적 표현보다 기계적 동작 설명이 좋습니다.
- "빠른 공격"보다 "검을 들어 올림 → 멈춤 → 내려침 → 회복"처럼 단계별로 써야 합니다.
- 카메라 고정 조건을 반드시 넣어야 합니다.
- 점프, 착지, 낙하 같은 수직 애니메이션은 캐릭터 움직임과 먼지/바람 효과를 따로 만드는 것이 좋습니다.
- 마지막 프레임이 첫 프레임과 너무 비슷하면 애니메이션이 멈춘 것처럼 보일 수 있습니다.
- 끝 포즈가 idle과 잘 연결되지 않으면 이미지 모델로 브릿지 프레임을 만드세요. 비디오 재생성보다 저렴합니다.
- 비용을 줄이고 싶다면 이미지 모델만으로도 가능하지만, 품질과 안정성은 비디오 모델 함께 쓸 때 훨씬 좋습니다.
