Iki는 웹용 2D 퍼펫 엔진이고, Claude Code 플러그인을 쓰면 에이전트가 문장 하나로 캐릭터를 만든다. 이미지 모델이 파트를 하나씩 그리면 컴포저가 한 캔버스에 배치하고, 오토리거가 그 레이어로 눈을 깜빡이고 말하고 고개를 돌리는 캐릭터를 만든다. 이 글은 그 캐릭터를 보기 좋게 만드는 이야기고, 아직 끝나지 않았다.

위는 정면 레퍼런스와 기본 자세의 리그, 아래는 고개 돌린 레퍼런스와 끝까지 고개를 돌린 리그. 기본 자세는 비슷한데 회전은 그렇지 않다.
완료 기준은 “렌더된다”였다
첫 캐릭터 스킬(6a81d43, 6월)은 에이전트가 이 작업을 할 때 읽는 지침인데, 마지막 단계가 Iki의 브라우저 플레이그라운드 확인이었다. 깜빡임, 시선, 입, 고개 회전 파라미터를 움직여 스크린샷을 찍고, 성공 기준은 이랬다.
콘솔이 깨끗하고(
IkiFormatError나 WebGL 에러 없음) 파라미터가 눈에 보이게 움직이면 성공.
에이전트는 이걸 그대로 따랐다. 9월에 데모 캐릭터를 만들라고 하자 “데모 모델 나왔습니다. 블링크, 시선, 립싱크, 헤드턴, 눈썹, 헤어스웨이 전부 동작합니다.”라고 보고했다. 다 사실이었는데, 누가 그린 캐릭터처럼 보이지는 않았다. 내가 원한 자연스럽고 예쁜 2D 애니메이션 캐릭터와는 거리가 있었다.
에이전트도 스크린샷은 봤지만 깨진 데가 있는지만 봤다. 성공 기준이 그랬고, 뭐가 좋은 건지는 어디에도 안 적혀 있었다.
그 밑에 문제가 하나 더 있었다. 파트는 하나씩 따로 생성되고, 파트끼리 묶어 주는 건 공통 스타일 문구 하나뿐이라 스타일이 따로 놀았다. 어떤 런에서는 납작한 셀 셰이딩 얼굴에 접사 사진 같은 실사 홍채가 나왔고, 어떤 런에서는 앞머리에만 주황색 하이라이트가 들어갔다.
레퍼런스와 별도 크리틱
그래서 반쯤 농담으로 GAN 같은 구조를 제안했다. 레퍼런스 캐릭터를 먼저 그리고, 에이전트가 그걸 보고 따라 만들고, 별도 리뷰어가 둘을 비교해 돌려보내는 구조다. 그날 오후에 스킬 하나와 에이전트 둘로 만들었다(df7793a).
- 레퍼런스는 한 번 생성해서 후보 두세 장 중 내가 고른 뒤 고정한다. 모든 파트 생성 작업에 첨부되니 모든 파트가 같은 그림을 보고 그려진다. 루프 도중에 바꾸면 그때까지의 점수가 전부 무의미해진다.
- 아티스트는 파트를 그리고 배치하고 레이아웃을 조정한 다음 리깅한다. 캐릭터 수정은 전부 아티스트 몫이고, npm에 배포되는 엔진 패키지는 건드리지 못한다.
- 크리틱은 렌더를 레퍼런스와 비교해 일곱 개 축(얼굴, 눈, 머리카락, 몸, 팔레트, 선, 리그)마다 0~5점을 매기고, 지적 사항을 쓴 다음
ship인지 한 라운드 더인지 판정한다. 직접 고치지는 않는다. - 오케스트레이터는 메인 세션이다. 두 에이전트를 띄우고, 브라우저에서 캐릭터를 렌더하고, 파일을 넘겨주고, 라운드 제한을 지킨다. 렌더를 오케스트레이터가 맡는 건 Playwright 브라우저가 하나뿐이라 두 에이전트가 같이 쓰면 충돌하기 때문이다.
라운드 하나는 아티스트 작업, 렌더, 크리틱 채점으로 이뤄진다. 만드는 쪽이 자기 결과물을 채점하면 안 되는 이유는 에이전트 셋, 문서 하나에서 이미 썼다. 그림이라서 달랐던 점은 두 가지다.
첫째, 사실 GAN은 아니다. 판별자는 생성자에게 기울기를 준다. 여기선 신호가 글 한 문단뿐이고, 그걸 받는 이미지 모델은 프롬프트를 잘 안 따라서 점수가 라운드마다 오르내리며 헤맬 수 있다. 그러니 제한이 꼭 필요하다. 이미지 생성에 돈을 쓰는 라운드는 최대 세 번이고, 두 라운드 연속으로 어느 축도 최고점을 갱신하지 못하면 멈춘다. 최고점을 축마다 따로 기록하는 건 합계만 보면 rig의 진짜 개선과 palette의 후퇴가 상쇄돼서 제자리처럼 보이기 때문이다.
둘째, 잘못돼 보이는 것 대부분이 그림 문제가 아니었다.
결함 여섯 개 중 넷은 그림 문제가 아니었다
데모 캐릭터를 만든 세션에서 결함이 여섯 개 나왔다.
| 결함 | 실제 원인 | 다시 그리면 고쳐지나? |
|---|---|---|
| 홍채가 흰자 위 구슬처럼 보임 | 컴포저의 홍채 비율 | 아니오 |
| 고개가 어깨에서 미끄러져 나감 | 오토리거의 회전 바인딩 | 아니오 |
| 눈썹이 안 보임 | 헤어스타일과 그리는 순서 | 아니오 |
| 속눈썹이 눈과 어긋남 | 부주의한 레이아웃 수정 | 아니오 |
| 고개를 돌리면 직선 이음매가 생김 | 그림이 자기 테두리에서 잘림 | 예 |
| 납작한 얼굴에 실사 홍채 | 스타일 드리프트 | 예 |
“다시 해”라고만 할 줄 아는 크리틱이었다면 다시 그려도 안 고쳐지는 문제 넷에 이미지 쿼터를 다 썼을 것이다. 그래서 지적마다 유형을 붙이고, 누가 움직일지는 유형으로 정한다.
regenerate: 그림 자체가 틀렸다. 돈이 든다. 파트 하나가codex exec를 거치는 이미지 모델 호출 한 번이라 몇 분씩 걸리고, 한 세트면 22번이다.retune: 그림은 괜찮은데 위치나 크기, 리그 설정이 틀렸다. 배치와 리깅은 로컬에서 돌아서 공짜다.escalate: 엔진을 고쳐야 한다. 아티스트는 손댈 수 없고 오케스트레이터가 판단한다.
크리틱은 regenerate를 쓰기 전에 retune으로 되는지 먼저 따져야 한다.
크리틱이 너무 후했다
첫 루프는 두 라운드 만에 24/35에서 29/35로 올라 ship이 나왔다. 결과를 보니 이상한 데가 다섯 군데 있었다.
Fable로 새 크리틱을 띄워 같은 캐릭터를 다시 채점하게 했다. 내가 찾은 다섯 군데를 알려 주고, 29점은 의심하라고 했다. 결과는 14/35였고 다섯 군데 모두 숫자로 확인됐다. 입은 그 높이에서 얼굴 폭의 43%를 차지했는데 레퍼런스는 27%였다. 눈썹에서 턱까지는 얼굴 폭의 0.57배로, 레퍼런스의 0.89배보다 한참 짧았다. 고개를 돌리면 목이 190px 미끄러졌는데, 첫 크리틱은 그 리그에 4점을 줬다.
오케스트레이터가 찾은 원인은 이랬다. 채점표가 5점만 “구분 불가”로 정의하고 나머지를 비워 둬서 3, 4점은 감으로 매겨졌고, 자기 파이프라인 결과물이다 보니 후하게 줬다. 또 rig는 깨졌는지만 물었고, 움직이면 안 되는 게 움직였는지는 묻지 않았다.
새 크리틱은 하나를 더 찾았다. 모든 비율을 재는 기준인 rest.png가 사실은 고개를 9° 돌린 히어로 컷이었다. 오케스트레이터가 그 이름으로 저장해 둔 탓에, 두 라운드 동안 돌아간 고개를 기준으로 닮았는지를 판정한 셈이다(55f9f6c). 지금은 슬라이더를 하나도 건드리지 않은 상태로 기본 자세를 찍는다.
그 뒤로 이렇게 바꿨다.
- 보기 전에 잰다. 기하 검사가 먼저 돌고, 그 경고는 사실로 취급한다. 크리틱 지침에도 “홍채가 커 보인다”는 쓸모없고 “홍채가 흰자 폭의 33%, 목표는 0.45~0.60”이어야 고칠 수 있다고 적혀 있다.
ship은 모든 축이 4점 이상이고 남은 재생성이 없을 때만 낸다.- 크리틱을 더 강한 모델로 바꿨다. 지금은 두 에이전트 다 Opus로 돈다(
ccc0b6f).
숫자에도 한계는 있었다. 기하 검사의 첫 임계값 중 세 개는 추측이었고, 레퍼런스에 맞춰 다시 잡기 전까지 멀쩡한 값을 결함으로 표시했다. 숫자와 그림을 나란히 놓고 봐서 둘이 어긋나면, 홍채 크기든 속눈썹 구조든 팔레트든 매번 그림이 맞았다.
그리고 고개를 돌렸다
몇 라운드 뒤 정면은 꽤 비슷해졌다. 그다음에 고개를 돌려 봤는데, 다음 날 아침에 다시 봐도 회전이 어딘가 어색했다. VTuber 모델에 많이 쓰는 상용 도구인 Live2D로 만든 모델은 고개를 돌려도 훨씬 자연스럽다.
채점표로는 이게 잡히지 않았다. 납작한 판이 옆으로 밀리는 것처럼 보이는 회전도 깨진 데는 없으니 rig 만점을 받을 수 있었다. 정면 레퍼런스로는 회전을 판단할 수도 없었다. 그래서 이렇게 바꿨다(92a2063).
turn축을 추가했다. 이목구비가(특히 코가) 얼굴 윤곽보다 더 움직여서 입체적으로 도는 것처럼 보이는지, 오려 낸 종이가 옆으로 밀리는 것처럼 보이는지를 본다.- 회전 중간에서도 스크린샷을 찍는다. 리그는 회전을 0°와 ±30°에서만 저장하고 엔진이 그 사이를 선형으로 섞는데, 섞을 때 생기는 결함은 15° 근처에서 드러나서 끝 각도 스크린샷으로는 안 보인다.
고개 돌린 레퍼런스도 하나 더 만들었다. 정면 레퍼런스를 첨부해서 이미지 모델이 같은 캐릭터가 고개를 돌린 모습을 그리게 한다. 처음엔 대략 3/4 뷰였는데, 가르마도 칼라도 다른 별개의 그림이 나왔고 약 45°라서 리그가 돌 수 있는 각도를 훨씬 넘었다. 리그의 고개 회전은 30°에서 멈추니 지금은 30°로 그린다(d303bd3). 재 보니 45° 그림에 맞추려면 이목구비가 30° 그림보다 약 1.7배 더 미끄러져야 했다. 프롬프트에 머리색이나 눈 색은 없다. 캐릭터가 누구인지는 첨부한 그림이 알려 주니, 프롬프트는 회전만 설명한다.
a modest turn, NOT a three-quarter view and NOT a profile: both eyes still fully visible, the far (viewer’s left) eye only slightly narrower than the near eye, the nose tip shifted a little toward the near cheek …
그림 속 회전은 너무 많이 돈다
3/4 그림을 기준으로 리그를 평가한 리뷰는 코가 리그보다 네 배 더 움직이길 원했는데, 그만큼 움직이니 이목구비가 판 위에 붙은 스티커처럼 미끄러져 보였다(a92c107). 그림은 3D로 도는 머리를 보여 주지만 리그 회전은 레이어끼리 미끄러지는 것이라, 그림이 보여 주는 양의 일부만 움직일 때 가장 자연스럽다.
그래서 고개 돌린 레퍼런스는 이제 스타일 확인용으로만 쓴다. 크리틱은 회전을 이 그림과 눈으로 비교하고, 리그를 이 그림에서 잰 숫자에 맞추지는 않는다. 리그는 모든 캐릭터를 같은 기본값에서 시작하고, 회전에 대한 크리틱의 질문 하나가 캐릭터별 조절값 하나에 대응한다. 얼굴이 레퍼런스만큼 도는지는 turn 조절값, 이목구비가 그만큼 앞서 나가는지는 featureLead, 머리카락이 그만큼 따라가는지는 hairFollow다. 답이 나오면 어느 쪽으로 바꿀지 정해지니 돈 안 드는 retune으로 끝난다.
눈으로 비교해도 그림을 쫓다 보면 너무 많이 돌리게 된다. 최근 캐릭터에서 크리틱은 앞머리가 레퍼런스보다 회전을 훨씬 덜 따라간다고 했고, 아티스트는 hairFollow를 2.0으로, turn 조절값을 1.25로 올렸다. 앞머리는 레퍼런스와 맞았지만 이번엔 앞머리 윗부분이 뒷머리 윤곽 밖으로 최대 22px 삐져나왔다. 3라운드에서 둘 다 되돌렸다.
회전은 그림을 바꿔서 고쳤다
회전은 앞의 결함 표와 반대였다. 몇 가지 문제는 파트를 다르게 그리자 사라졌다.
- 코를 별도 파트로 뺐다(
a92c107). 얼굴에 그려진 코는 얼굴과 같이 움직일 수밖에 없지만, 떼어 내면 앞서 나갈 수 있다. - 목을 몸통 쪽으로 옮겼다(
e9eaba4). 얼굴은 목 없이 그리고, 돌지 않는 목 위를 얼굴 전체가 미끄러진다. - 앞머리를 얼굴 폭만큼 그린다(
b66d49c). 그래야 앞머리 윗부분이 얼굴과 같이 돌 수 있다. 처음엔 뒷머리를 더 넓게 배치해서 풀었는데, 머리가 너무 커 보여서 보자마자 뺐다.
지금 상태
turn 축이 생긴 뒤의 런 전부다. 축이 여덟 개라 40점 만점이다.
| 런 | 라운드별 합계 | 라운드별 turn |
|---|---|---|
| 플러그인 도그푸딩, 9월 10일 | 25 → 29 → 31 | 3 → 3 → 3 |
| 랜딩 페이지 캐릭터, 10월 1일 | 26 → 30 → 30 | 3 → 4 → 4 |
| 두 번째 캐릭터, 10월 3~4일 | 26 → 28 → 30 → 31 | 3 → 3 → 3 → 3 |
셋 다 ship까지 못 가고 크리틱의 stop으로 끝났다. 모든 런이 30~31점에서 멈췄고, 셋 중 둘은 회전 점수가 끝내 3점을 넘지 못했다. 4점까지 간 하나는 대신 rig가 3점으로 끝났다. 첫 런의 크리틱은 먼 쪽 눈이 가까운 쪽 눈과 폭이 같고 얼굴 폭도 거의 줄지 않는다고 적었다. 회전은 “4점 미만인 유일한 축이고, 세 라운드 동안 움직이지 않았다”.
지금은 앞머리를 다시 고치고 있다. 고개를 돌리면서 끄덕이고 갸웃하는 자세를 겹치면 앞머리 윗부분이 아직 뒷머리 윤곽 밖으로 미끄러질 수 있다.
효과가 있었던 것
- 판정하는 쪽에 기준을 주고 고정한다. 레퍼런스가 없으면 “좋은가?”라는 질문이 “돌아가나?”로 바뀐다.
- 만드는 쪽과 판정하는 쪽을 나눈다. 크리틱은 진단하고, 아티스트는 고치고, 오케스트레이터는 렌더하고 결정한다.
- 지적마다 누가 고칠 수 있고 비용이 얼마인지 유형을 붙인다. 나쁜 그림처럼 보였던 것 대부분이 컴포저나 리그 설정 문제였다.
- 먼저 재고, 그래도 눈으로 본다. 숫자와 나란히 놓은 그림이 어긋나면 그림을 믿는다.
- 움직임은 중간을 본다. 끝 각도 스크린샷으로는 리그가 거기까지 가는 동안 어떻게 섞이는지 안 보인다.
아직은 내가 마지막 크리틱이다. 목도 회전도 머리카락도 점수보다 내가 먼저 알아챘다.
플러그인에는 스킬과 두 에이전트, MCP 서버가 같이 들어 있다(소스).
/plugin marketplace add zeikar/iki
/plugin install iki@iki