| name | autorig-rotation-distill |
| description | 정수리 crown reveal + THA3 회전 증류 — 끄덕임/들기/도리도리/대각선을 자연스럽게. THA3 신경망을 모션 오라클로 써서 flow를 리그 키폼으로 받아쓰기(런타임 GPU 0·2048 화질 유지) + gpt-image 정수리 자산을 앞머리 뒤 reveal 레이어로 주입. 트리거 — "머리 회전 자연스럽게", "정수리 reveal", "crown", "끄덕임 개선", "THA 증류", "대각선 시선", "rotation distill". 2026-07-08 유키(snack-yuki-001)로 end-to-end 실증·Vercel 배포. |
정수리 reveal + THA3 회전 증류 (DISTILL-ROTATION-T1)
원리: THA=움직임을 아는 선생, 시스루=파츠 지도, 리그=악보(키폼)만 읽는 학생.
THA3의 내부 appearance-flow를 파츠별 키폼으로 증류하면 런타임 무비용으로 얼굴이 진짜 피치·대각 모션을 얻는다. flow가 원리적으로 못 만드는 "없던 픽셀"(정수리)은 gpt-image 자산 1장으로 채운다.
비용: gpt-image 1콜(~$0.45) + Colab 무료 T4 수 분. 나머지 전부 로컬. 학습 0.
전제
- 대상 리그:
rig_v0_project 계열(head_angle_warp 계층 + face_base bbox 존재). 비파괴 변종에 먼저.
- Colab CLI(
colab --auth adc), THA3 레시피는 [[tha3-head-rotation]] 스킬(모델=Dropbox wget 5파일, standard_float).
- 런타임은 무수정 — vertex_keyforms 가산·2D 코너(
interpKeyform2DSpec)를 이미 지원.
절차 (유키 실증 커맨드)
0. crown 자산 생성 + 주입 (reveal)
python3 scripts/gen_rotation_atlas.py --view crown_part \
--master experiments/<id>/generated/master.png --out experiments/<id>/crown_reveal
python3 scripts/inject_crown_rig.py \
--src experiments/<id>/rig_v0_project --dst experiments/<id>/rig_v0_project_crown_L \
--crown-png experiments/<id>/crown_reveal/atlas_crown_part_2048.png \
--white-bg --order-mode deep --crop-top 0.45 --squash 0.6 --scale 1.22 --yoff 150 \
--ellipse --sil-clip 85 --x-margin 90
deep = 앞머리·동물귀 둘 다 뒤(귀 밑동 털 보존). above(008식)는 유키에서 탈락(얼굴 덮임/절단선 노출).
- 정합 원칙: 생성물 좌표 불신 — 배치는 face/front-hair bbox 실측,
--sil-clip(컬럼별 실루엣 top+margin까지만)·--x-margin(얼굴 폭±, 중앙 돔 한정)·경계 60px 페더로 실루엣 곡선에 맞춰 깎는다.
- 불투명도 리빌: ParamAngleY 0→-30 선형 페이드(중립 완전 은닉).
1. THA3 입력 + 7×7 flow export (Colab T4, 수 분)
python3 scripts/make_tha3_input.py --project <rig_variant> \
--out-dir experiments/<id>/tha3_out --name <id>
- 정합 기준 = face_base 파트 bbox(팔레트 무관). 피부색 휴리스틱은 크림/백발 캐릭터에서 머리카락까지 오검출 — 금지.
- Colab: [[tha3-head-rotation]] 셋업 → b64 업로드 →
export_head_tha3.py(B64_PATH만 캐릭터로 교체한 사본) 실행 → zip 회수(out_img 49장 + grid_change_flow 49npy). selfcheck L1≈0.005~0.008이면 정상.
- 게이트: 49프레임 몽타주 육안 — 괴물 0·얼굴 왜곡 0 (귀 깨짐은 무관: 샘플링 제외 대상).
2. 증류 주입
python3 scripts/distill_tha3_rotation.py --project <rig_variant> \
--flow-dir experiments/<id>/tha3_out/grid_change_flow \
--affine experiments/<id>/tha3_out/<id>_affine_rig_to_crypko.json \
--input-png experiments/<id>/tha3_out/<id>_tha3_input.png \
--gain 1.2 --hair-affine
부위별 증류 방식(전부 실측 판정으로 확정):
- 얼굴 코어(face/eye/iris/lash/brow/nose): 정점 단위 flow (정밀).
- 헤어: 파트별 affine 피팅 — 들기에서 돔 후퇴·숙임에서 확장(신체구조 대칭). 정점 flow는 가닥 찢어짐(008 판정).
★가시성 게이트(2026-07-08 미미 돔 사건): 가려진 파트는 flow가 앞 레이어(얼굴·후드)의 움직임을
상속(오염)한다 → topmost 맵에서 자기 픽셀이 보이는 곳만 샘플, 가림비율(자기알파 기준)<0.25면 파트 스킵,
피팅 표본은 메시 정점(36개 코스 격자) 대신 가시 불투명 픽셀(수천 개, strict=False 가드)로.
- 입: affine (형태 보존) — 정점 flow는 입매를 일그러뜨림. 그려진 입 = 성역.
- 귀(동물귀): 제외 — 귀 끝이 입력 실루엣 밖이라 부분 샘플 affine이 외삽되며 꺾임. 귀 추종은 자체 디포머가 담당.
- 대각선: 코너 4프레임의 잔차(D_corner − D_x축 − D_y축)를 2D 그리드 스펙(
parameter_ids)으로 — 런타임 무수정.
★코너 superposition 주의(2026-07-10): 잔차가 corner − dy − dx_ax인데 --yaw(단독 ParamAngleX 키폼) 없이 쓰면 dx_ax를 빼고 안 되돌려 대각선에 ≤max_disp skew. ⇒ 정면-yaw(앞 얼굴 좌우턴 안 함)면 --no-corners(순수 pitch+yaw 선형합, 대각선=깨끗한 pitch), 앞도 좌우턴시키면 --yaw(superposition 정합). --yaw-scale <0.3~0.5>로 2D 평면 "종이 팔랑" 완화. 2D 앞-얼굴 강한 좌우턴은 원리적으로 팔랑(레퍼런스 프로 Live2D는 손 리깅 메시) — moderate만.
3. 검증 → 배포
python3 scripts/capture_pose.py --project <rig_variant> --poses '[...상하좌우+코너+입개폐...]'
python3 scripts/scan_rig_health.py --project <rig_variant> --depth-map <rig_variant>/depth_map.json
python3 scripts/build_player_webapp.py --project <rig_variant> --out /tmp/<id>_webapp
⚠️ 함정 (전부 실제로 밟은 것)
| 함정 | 증상 | 해법 |
|---|
| THA3 그리드 축 방향 | 위 보면 아래 봄(반전) | 주석 믿지 말고 프레임 실물 직독: r0=숙임(정수리 노출)·r6=들기·c0=좌·c6=우. 008 flow_to_keyforms.py 주석("r0=up")은 반대였음 |
| 축 오염 = body 결합(2026-07-10) | 끄덕이면 옆으로 감·대각선 뒤죽박죽("왼쪽위만 됨") | "약한 회전"을 키우려 flow 베이크에서 pitch축(head_x)에 body 파라미터를 섞지 말 것. 실측(tha3_diag.py 순수 스윕): head_x(39)=pitch·head_y(40)=yaw·neck_z(41)=roll·body_y(42)=몸통yaw·body_z(43)=몸통 옆기울기(가로). body_z를 pitch에 더하면 pitch가 세로 아닌 가로로 오염(=가짜 강회전). THA3엔 body-pitch 없음 → pitch는 head_x 단독(export_head_tha3.py 순수). 검증=키폼 dx/dy·세로압축 측정(pitch는 dy·압축, yaw는 dx) |
| GAIN 과대 | 턱·볼 어두운 스미어(전 정점 클립 포화) | max변위가 --max-disp(120px)에 전부 붙으면 과대 — gain 1.2부터 |
| 다중 스펙 전환 버그 | 입 활짝 때 "낯선 입" | 스펙 2개↑면 레거시 직접반환→가산 합성 전환. 기존 스펙(WIDEGROW 키 0.18~0.85)에 기본값 키가 없으면 neu가 첫 키로 클램프 → 기본값 앵커 키 자동 삽입(distiller에 내장, 가산==레거시 0.000000 검증) |
| 웹캠 중립 오프셋 | 정면인데 위/아래 봄 | 리그 아닌 트래킹: NEUTRAL-AUTO-001(얼굴 인식 후 자동 중립 측정, 템플릿 내장) + 수동 "중립 보정" 버튼 |
| crown 크기 정합 | "뒤에 큰 머리" | 실루엣 클립이 답 — 폭·납작(squash)·sil-clip·x-margin·페더 조합 |
| 피부색 얼굴검출 | 크림/백발 캐릭터에서 bbox=캔버스 전체 | face_base 파트 bbox로 정합(make_tha3_input 기본) |
| 가려진 파트 flow 오염 | 특정 각도서 반투명 돔/유령 기하(미미 hair_back) | 가시성 게이트가 자동 차단. 진단=파트 스펙 외과 제거 A/B([[autorig-live-stability]]) |
| 라이브 덜덜·중립 튕김 | 리그 아닌 트래킹/보정 층 | [[autorig-live-stability]] — HEAD-SMOOTH-001·NEUTRAL 안정 게이트 |
| 턱 붕괴(큰 얼굴 캐릭터) | 프레이밍 스케일↓ → rig-px 클립(구 120)에 입·코 100% 포화, 턱만 소량 → 입이 턱 뚫음(URO 실측 31 vs 126px) | 클립·pred 가드 crypko px 기준(스케일 불변): --max-disp 20 crypko ≈ 유키 등가 |
| 격자 모서리 정점이 엉뚱한 흐름 샘플 | face 하단 모서리가 투명/헤어 위라 12~32px(중앙 101) → 찢어짐 | 불투명 스냅: distance transform으로 자기 파트 최근접 불투명 픽셀에서 샘플(1D·2D 코너 공통) |
| 입 파트 증류 탈락 | 36정점 격자=유효 샘플<6 → 가드 컷 → "숙여도 입 고정" | 픽셀 표본 피팅을 affine 그룹 공통화(입=자기 알파 픽셀) |
| 끄덕임에 머리 위 유령 호/흰 초승달 | 증류·crown 아닌 자산: See-through가 hair_back에 구운 fill 없는 외곽선 호가 head-follow 진폭차로 분리(URO) | 파이프라인 P2 cut_orphan_strokes.py --auto 재배정 + fill_composite_holes.py 백필이 자동 처리(ORPHAN-STROKE/COMPOSITE-HOLE-001) — 진단은 포즈별 렌더 재현+파트 오버레이 |
하드코딩 주의 (2026-07-08 전수점검)
- 그리드 N=7 결합:
distill_tha3_rotation.py의 프레임명(r0/r3/r6·c0/c3/c6)은 7×7 export 전제 — export 그리드를 바꾸면 증류기 프레임 매핑도 같이 바꿔야 함(조용히 어긋남).
- crown 크기 손잡이(--scale/--yoff/--crop-top/--squash)는 캐릭터별 실렌더 A/B로 재판정(위 커맨드의 수치는 유키 채택값). 배치 자체는 bbox 상대라 대체로 이식되지만 밴드 두께·높이는 머리 모양 따라 다름.
export_head_tha3.py의 B64_PATH는 VM 하드코딩 — 캐릭터별 sed 사본으로 실행(§1).
inject_crown_rig.py의 LIFT/PORTRAIT 상수는 폐기된 "앞머리 들기" 시절 잔재(무동작) — 참조하지 말 것.
한계 (정직)
- THA 모더릿 대역(±25~30° 상당)의 자연화. 완전 옆모습·강회전은 스코프 밖(real-3D 트랙).
- crown 자산은 정면 1장 기반 — 극단 끄덕임의 완전 3D 정수리는 아님.
- 증류는 캐릭터당 1회 오프라인(Colab 수 분) 필요. 프레임·flow는 experiments//tha3_out에 보존.
실증 기록
유키(snack-yuki-001) 2026-07-08: rig_v0_project_crown_L → https://yukiwebapp001.vercel.app/drive.html 배포.
scan PASS 23·WARN 2·FAIL 0(L2 깊이 게이트 포함). 상세 evidence-log DISTILL-ROTATION-T1.