밤새 AI에게 맡긴 3D 폐차장 게임 (2) 그림에서 3D 모델, 뼈대, 애니메이션까지
참고 그림 31장을 3D 모델로 바꾸고, 블렌더를 화면 없이 돌려 뼈대와 동작을 입힌 과정이에요. 참고 그림과 게임 속 모델을 나란히 놓고 잘 된 것과 안 된 것을 비교했어요.
목차 9개
1편에서는 SCRAPYARD SURVIVOR의 게임 화면을 목표 그림과 비교했어요. 이번 편은 그 게임에 들어간 캐릭터, 적, 폐차, 무기 부품을 어떻게 만들었는지예요. 모델링 프로그램을 손으로 연 적은 한 번도 없어요. 하룻밤, 자정부터 새벽 6시 17분까지 Claude Code가 스크립트를 짜서 전부 자동으로 돌렸어요.

흐름은 이래요.
- 에셋 31개의 이름과 그림 설명을 목록 파일 하나에 적는다
- 이미지 생성 API로 참고 그림을 한 장씩 뽑는다
- 3D 변환 API에 그림을 넣어 GLB 모델을 받는다 (하나에 3~22분, 한 번에 하나씩)
- 웹에서 쓸 수 있게 텍스처를 줄이고 압축한다
- 사람 모양 캐릭터는 블렌더를 화면 없이 돌려 뼈대를 심고 무료 동작을 옮겨 입힌다
- 네 발 로봇 개는 뼈대와 동작을 코드로 직접 만든다
참고 그림 뽑기

모든 그림 설명 뒤에는 공통 문구를 붙였어요. 밝은 회색 배경, 물체 전체가 잘리지 않게, 고른 조명이에요. 3D 변환이 잘 되려면 배경이 단순하고 물체가 온전히 보여야 해서예요. 사람 캐릭터는 팔을 옆으로 쭉 뻗은 T자세로 정면을 보게 했어요. 나중에 뼈대를 심을 때 팔과 몸통이 떨어져 있어야 구분하기 쉽기 때문이에요.
그림 한 장에 30초 남짓 걸렸어요. 그런데 그림 생성과 3D 변환이 같은 GPU를 나눠 써서, 새벽 2시 35분쯤부터 3D 작업이 GPU를 오래 잡고 있자 그림 요청이 5분 넘게 대답이 없었어요. 그 뒤로는 3D 대기열이 빌 때 그림을 몰아서 만들었어요.
그림에서 3D 모델로

잘 나온 것들부터 보면 이래요. 세단은 찌그러진 보닛과 녹 무늬까지 그림과 거의 같고, 작업대는 위에 놓인 공구와 빨간 공구함까지 따라 나왔어요. 조명탑과 크레인처럼 가는 철골 구조도 모양은 살아 있어요. 다만 뒷면은 그림에 없으니 변환기가 짐작해서 채워요.
모델은 서버가 한 번에 하나만 처리해서 순서대로 돌렸고, 실패하면 면 수를 절반으로 줄여 한 번 더 시도하게 했어요. 가장 애먹은 건 메모리였어요. 효과음과 음악 생성도 같은 GPU를 써서, 소리를 만드는 중에 3D 작업이 돌면 20%쯤에서 한참 기다리다 메모리 부족으로 실패했어요.
비스듬히 나온 폐차 바로 세우기

폐차와 소품은 입체감이 잘 보이게 비스듬한 각도로 그림을 뽑았는데, 3D 모델도 그 각도 그대로 대각선으로 놓여서 나왔어요. 폐차를 벽처럼 나란히 세우려고 하면 45도씩 틀어져 있고 충돌 상자도 엉뚱하게 잡혔어요.
그래서 모델의 점들이 가장 길게 퍼진 방향을 계산해서, 그 방향이 차의 앞뒤가 되도록 돌려 놓게 했어요. 세단은 바로 세우기 전 겉 상자가 4.33×4.6m였는데, 세운 뒤 길이 4.6m, 폭 2.33m가 됐어요. 조명탑과 크레인처럼 높이가 중요한 건 키로 크기를 맞췄어요.

노란 화살표를 따라가 보면 바로 세운 폐차들이 같은 방향으로 나란히 놓여 있어요.
모델이 도착하기 전과 후

게임 코드는 모델을 기다리지 않고 먼저 진행됐어요. 모델이 없는 자리에는 갈색 상자를 세워 두고, 파일이 생기면 그 자리에 들어가게 했어요. 왼쪽이 새벽 1시 41분의 모습이고, 오른쪽은 모든 생성이 끝난 뒤 폐차장 북쪽이에요.
안 된 것들
31개 중 26개가 생성됐어요. 압착된 차, 불 붙은 드럼통, 팔레트, 케이블 드럼, 산업용 모터 5개는 두 번 이상 시도해도 서버에서 실패했어요. 그 자리에는 상자 대신 비슷한 모델을 쓰게 했어요.
const FALLBACK = { car_crushed: "car_hatch", prop_barrel_fire: "prop_barrel", prop_pallets: "prop_crate", prop_scrap_pile: "car_hatch", prop_spool: "prop_barrel" };

생성은 됐지만 못 쓴 것도 있어요. 입구 게이트는 납작한 파편 덩어리로 나와서, 코드로 격자 기둥 두 개, 가로 보, 글자를 그려 넣은 간판, 철망 문짝을 조립했어요. 파이프도 앞뒤 모양이 달라서 코드로 만들었어요.

줍는 고철 아이템은 너무 납작해서 표시 고리 안에서 보이지 않았고, 큰 고철 더미는 재시도에서 나오긴 했는데 검은 파편 덩어리라 쓰지 않았어요. 이번에 얇은 판이나 여러 조각이 엉킨 물체는 대부분 이렇게 무너졌어요.
사람 캐릭터에 뼈대와 동작 입히기
주인공과 고철 좀비는 블렌더를 화면 없이 실행해서 뼈대를 심어요. T자세니까 몸을 높이별로 얇게 잘랐을 때 가장 넓은 층이 어깨, 가운데 기둥이 끊기는 곳이 가랑이예요. 이렇게 17개 뼈 위치를 잡고, 각 점이 어느 뼈를 따라 움직일지는 뼈까지의 거리로 정해요. 블렌더 자동 가중치도 먼저 시도했지만 생성된 모델에서는 매번 실패했어요.
동작은 직접 만들지 않고 KayKit의 무료(CC0) 캐릭터에 들어 있는 대기, 달리기, 공격, 구르기 같은 동작을 옮겨 입혔어요. 공격 동작마다 무기가 가장 빨리 움직이는 프레임을 기록해 두고, 게임은 그 프레임 앞뒤를 타격 판정 구간으로 써요.

첫 결과는 이랬어요. 동작은 움직이는데, 주인공이 모든 동작에서 팔을 옆으로 벌리고 있었어요. KayKit 캐릭터는 통통한 체형이라 원래 팔을 몸에서 떼고 있는데, 그 각도를 사람 비율 몸에 그대로 옮기니 팔이 공중에 뜬 거예요.

팔이 아래로 늘어진 동작에서만 위팔을 몸 쪽으로 당기고, 공격처럼 팔을 드는 동작에서는 보정이 사라지게 했어요. 보정 상한은 처음 주인공 35도, 좀비 25도였다가 최종 주인공 55도, 좀비 30도가 됐어요. 대기 자세에서 손이 몸 옆으로 벗어난 거리는 0.17m에서 0.01m로 줄었어요. 다만 아래팔은 원래대로 굽어 있어서 지금 대기 자세는 손을 허리에 얹은 것처럼 보여요. 사진의 1번에서 3번으로 가면서 팔이 몸 쪽으로 들어왔어요.

좀비는 보정 상한이 30도라 지금도 팔을 벌리고 다녀요. 그림과 비교하면 초록 피부가 어두운 갈색으로 바뀌었고 머리 모양이 뾰족하게 뭉개졌어요. 지금은 이대로예요.
로봇 개는 결국 코드로

로봇 개가 가장 애를 먹였어요. 첫 그림으로 네 번 돌렸는데 세 번은 소리 생성과 겹쳐서, 네 번째는 소리를 안 만들 때 면 수를 낮춰 돌렸는데도 68% 단계에서 메모리가 모자랐어요. 다리 관절, 배선, 피스톤처럼 가늘고 복잡한 부분이 많은 그림이라서였어요. "굵고 각진 몸통, 가는 배선 없이"로 다시 뽑은 그림은 새벽 5시쯤 변환에 성공했는데, 결과가 갈색 상자 같아서 보관만 했어요.

그래서 실제로 쓰는 건 블렌더 스크립트가 상자와 원기둥으로 조립하고 녹슨 금속 텍스처를 입힌 로봇 개예요. 점이 1,840개밖에 안 돼요. 네 발 짐승에 맞는 무료 동작이 없어서 걷기와 달리기는 대각선 다리 두 쌍이 사인 곡선으로 번갈아 움직이게 코드로 만들었고, 물기 공격, 맞음, 쓰러짐은 몇 개의 키 프레임을 직접 적었어요.
써 보니

좋았던 점은 속도예요. 그림 한 장이 30초, 모델 하나가 길어야 20분 남짓이라, 하룻밤에 폐차 세 종, 소품 열 가지 남짓, 무기 부품, 캐릭터 둘이 게임에 들어갔어요. 세단이나 작업대처럼 단단한 물체는 그림을 거의 그대로 따라 나왔어요. 사람 손으로 뼈대를 심지 않고 스크립트 한 줄로 뼈대, 동작, 압축까지 이어서 돈다는 것도 편했어요.
아쉬운 점도 분명해요. 얇거나 복잡한 물체(게이트, 고철, 로봇 개)는 거의 다 실패했고, 성공한 모델도 뒷면과 얼굴 같은 세부가 뭉개졌어요. 위 사진처럼 배경에 흩어 놓은 폐차 일부는 쌓는 높이만 정하고 아래를 받치지 않아서 공중에 떠 보이는 것도 이번에 다시 찍으면서 알았어요. 빨간 동그라미 친 두 대가 그래요. 무엇보다 모델 하나하나는 괜찮아도, 이걸 평평한 땅에 드문드문 놓으니 목표 그림의 빽빽한 폐차장 느낌은 나지 않았어요.
지금 상태와 남은 것
- 에셋 31개 중 26개가 3D 변환에 성공했어요. 실패한 5개와 쓸 수 없던 고철 더미는 비슷한 모델로 대신하고, 파이프, 게이트, 줍는 고철은 코드로 만든 걸 써요.
- 주인공과 좀비는 거리 기반 가중치로 뼈대를 심고 KayKit 동작을 입혔어요. 공격 동작마다 타격 프레임이 같이 기록돼요.
- 로봇 개는 코드로 만든 모델과 동작을 써요. 두 번째 그림에서 나온 모델은 보관만 하고 있어요.
- 효과음·환경음 34개와 음악 3곡도 같은 밤에 만들어졌어요. 모든 생성 작업은 새벽 6시 20분쯤 끝났어요.
- 두 번째 구역과 보스에 들어갈 에셋은 아직 목록에 없어요. 그날 새벽 6시 17분 이후로 손대지 않았어요.
뼈대를 심는 스크립트와 로봇 개 스크립트, 에셋 31개의 그림 설명은 글 아래에서 내려받을 수 있어요.
밤 조명을 새벽 내내 맞춘 이야기는 3편에 따로 적었어요.
댓글 0
아직 댓글이 없어요. 첫 이야기를 남겨 주세요.