만화 단편: 아이디어 → 대본 → 음성 해설 → 완성된 MP4
룩: 밝은 2D 빈 머리 만화 캐릭터(캔버스에 그려진 자두색 외곽선 '카드')가 검은 잉크 외곽선, 페인트 텍스처, 피사계 심도, 글라이딩 카메라가 있는 화려한 3D 세계에 배치됩니다. 출력은 1080x1920, 30fps이며, 음성 해설 길이와 정확히 일치합니다. 사용자 음성은 변경되지 않습니다. 배경 음악과 효과음은 합성되며 음성 레벨의 50% 로 설정됩니다. "The Soldier Who Never Left"(19.7초, 8컷)에서 검증되었습니다.
규칙
- 이야기, 캐릭터, 컷은 항상 독창적이어야 합니다. 다른 제작자의 비디오를 컷 단위로 재현하지 마세요. 대신 같은 아이디어에 대한 독창적인 해석을 제공하세요.
- 실제 유명인이나 브랜드 마스코트, 로고는 캐릭터로 사용할 수 없습니다.
- 사용자가 요청하지 않는 한 자막을 넣지 마세요. 다이제틱 텍스트(조각된 메시지, 표지판)는 괜찮으며, 거울 반전 없이 올바르게 읽혀야 합니다.
- 음성을 편집하거나 시간을 조정하지 마세요. 영상은 음성에 맞춰 타임되며, 모든 시각적 반응은 해당 단어보다 0~3프레임 앞서 도착합니다.
- 오디오 레벨: 배경 음악은 음성 레벨의 50%(-6dB, 게이트 RMS)로 설정됩니다. 효과음은 50% 또는 그 이하로, 피크가 내레이션을 넘지 않도록 제한됩니다. 항상
mix.py로 믹싱하고 수동으로 하지 마세요. 이 비율을 변경하는 덕킹이나 압축은 사용하지 마세요. 전체 믹스에는 하나의 선형 게인과 피크 리미터만 적용됩니다. - 사용자에게 작업 목록으로 진행 상황을 알리세요. 긴 렌더링 전에 스틸 컷 연락판을 보내세요.
1단계: 입력 (항상 먼저)
오디오 파일이 이미 첨부된 경우 4단계로 건너뜁니다. 대본도 함께 제공된 경우 그 대본을 타임에 사용합니다. 그렇지 않으면 AskUserQuestion 하나(또는 해당 도구가 없는 경우 일반 텍스트)를 물어보세요: "어디서부터 시작하시겠어요?"
- 음성 해설 준비 완료: 업로드를 요청하고, 가능하면 대본 텍스트도 함께 요청하세요(대본이 있으면 타임이 정확해집니다). 파일이 도착하면 4단계로 이동합니다.
- 대본 있음, 음성 해설 필요: 필요한 경우 3단계에 따라 대본을 다듬고 녹음 팁과 함께 다시 제공한 후 업로드를 요청하고 4단계로 이동합니다.
- 비디오 아이디어와 대본 필요: 2단계로 이동합니다. 또한 사용자가 언급하지 않은 경우 대상 길이를 물어보세요. 기본값은 20-30초입니다. 45-60초도 허용됩니다.
2단계: 10개의 비디오 아이디어
정확히 10개의 아이디어를 하나의 답변에 번호를 매겨 제공하고, 사용자에게 번호(또는 "more")로 답변해 달라고 요청하세요. 각 아이디어에는 다음이 포함됩니다:
- 제목 (5-8단어, 호기심 유발, 예: "The Soldier Who Never Left")
- 훅 라인: 첫 번째 말하는 문장, 사실처럼 진술된 역설 ("한 남자가 에펠탑을 팔았습니다. 두 번이나.")
- 반전 한 줄 (비디오를 끝내는 아이러니한 대가)
- 애니메이션에 적합한 이유: 2-3개의 큰 시각적 순간(붕괴, 폭로, 추격)
- 사실 또는 전설: 문서화된 역사인지, 논쟁이 있는 이야기인지, 민담인지 명확히 밝히기
이 형식에 "완벽한" 아이디어의 특징:
- 보여줄 수 있는 물리적 인과 관계가 있는 하나의 놀라운 이야기
- 명확한 평범한 캐릭터, 확대되는 이해관계, 마지막 줄의 반전
- 단순한 3D 모양과 만화 카드로 만들 수 있는 배경(마을, 다리, 배, 성, 사막, 연구소, 궁전)
- 시대와 주제를 넘나들며 혼합: 고대, 중세, 1800년대, 현대, 과학, 동물, 발명, 재난, 이상한 법칙, 행운의 사고
- 사실로 제시하는 내용은 웹 검색으로 주요 사실을 확인하세요. 바이럴 전설을 사실로 제시하지 마세요. 사용자가 그래도 원한다면 "전설에 따르면"이라고 표현하세요.
- 실제 유명인을 농담의 대상으로 삼지 말고, 선정적이거나 정치적인 내용은 금지합니다.
3단계: 대본 (선택 후)
내레이션만 작성하고(대사에 무대 지시 없음), 약 3.7단어/초로 크기 조정: 20초 ≈ 75단어, 30초 ≈ 110, 60초 ≈ 220. 공식:
- 훅 (첫 문장, 설정 없음): 터무니없는 사실.
- 설정 1-2줄: 언제, 어디서, 누가, 구체적인 세부 사항.
- 상승, 2-4박자, 각각 더 커짐. 다른 사람들은 의심하거나 조롱함. 과장 농담 한 번 사용.
- 미스터리 또는 전환: "하지만..." / "사실은," 실제 메커니즘을 소개하며, 종종 일상적인 비유와 함께.
- 반전/대가: 짧고 아이러니하며 비디오의 마지막 말. 평범한 구어체 영어, 축약형, 8-15단어 문장, 숫자는 단어로 표기. 시청자가 이미 보는 것을 절대 설명하지 마세요.
그런 다음 답변:
- 대본을 복사 가능한 블록으로, 단어 수와 예상 길이 포함.
- 한 문단 분량의 시각적 계획(애니메이션할 컷).
- 녹음 팁: 안정적이고 따뜻한 나레이터 목소리 하나; ElevenLabs가 잘 작동함(깊은 나레이터 목소리, 속도 약 1.05-1.1, 안정성 약 45-55%). Mp3 또는 wav 파일이 좋습니다. 문장 끝에 자연스러운 멈춤을 두세요. 음악 없이 내보내세요.
- 요청: "음성 해설이 준비되면 업로드해 주시면 전체 비디오를 만들겠습니다." 최종 대본 텍스트를 유지하세요. 4단계의 타임 기준이 되므로 음성 인식이 필요하지 않습니다. 변경된 버전을 녹음한 경우 최종 텍스트를 요청하세요.
4단계: 비디오 제작 (음성 해설 업로드 후)
여기서부터 멈추지 않고 모든 작업을 수행하세요. 타이밍이 해결되지 않는 경우에만 질문하세요.
4.0 키트 준비
코드 키트는 이 스킬 폴더 내 kit/에 있습니다(엔진, 도구, 작업 예제, MIT 라이선스인 vendored three.js r160 및 github.com/mromidev/claude-animated-shorts의 toon.ts Pen 라이브러리 포함). find / -name SKILL.md -path "*cartoon-audio-short*" 2>/dev/null로 폴더를 찾고 kit/를 읽기 전용으로 취급하세요.
그런 다음 bash <skill>/kit/tools/setup.sh ~/shorts/<slug>를 실행하세요. 프로젝트에 엔진과 도구를 복사하고, vendored three.js를 설치하며, Node 22 module.stripTypeScriptTypes로 toon.ts에서 타입을 제거하고, Playwright를 연결합니다. 네트워크가 필요하지 않습니다. vendored 파일이 없으면 npm 또는 git clone으로 대체됩니다.
- 요구 사항: Node 22.6+, numpy + Pillow가 있는 Python 3, ffmpeg, Chromium이 있는 Playwright(
npm i -g playwright && npx playwright install chromium누락 시) - 패키지 레지스트리가 차단된 경우 일반적으로 GitHub을 통한 git이 작동합니다. TLS를 비활성화하거나 프록시를 우회하지 마세요.
- Chromium:
--use-angle=swiftshader --enable-unsafe-swiftshader --ignore-gpu-blocklist로 사전 설치된 Playwright 브라우저를 사용하세요. 이렇게 하면 CPU WebGL이 프레임당 약 3-10초로 제공됩니다.
4.1 타이밍
python3 timing.py voice.mp3 script.txt --out work를 실행하세요.
- whisper 또는 faster-whisper가 설치된 경우 단어 타임스탬프를 사용합니다.
- 그렇지 않으면 대본 구문(구두점으로 분할)을 무음 감지 음성 세그먼트에 정렬하고, 음절을 지속 시간과 일치시키고 세그먼트 내 문장 끝과 구문 내 긴 간격에 패널티를 주는 DP를 사용합니다.
- ASR이 없고 대본도 없으면 대본을 요청하세요. Claude는 오디오를 들을 수 없습니다.
work/phrases.json확인: 멈춤은 문장 끝에 있어야 합니다. 총 프레임 = round(지속 시간 × 30).
4.2 컷 계획 (코드 전 work/PLAN.md)
컷당 한 행: 프레임, 단어, 설정, 조명, 카메라 이동, 캐릭터/포즈/표정, 효과 및 SFX 큐.
- 프레임 0은 이미 훅 이미지입니다.
- 보통 구문당 하나의 컷. 아주 작은 구문은 다음 컷에 병합합니다.
- 모든 문장을 문자 그대로 보여주세요. 소품이 농담을 전달합니다.
- 컷 크기 다양화: 훅 MCU → 와이드 폭로 → 투샷 → 핵심 물체 클로즈업 삽입 → 반응 클로즈업 → 대가를 위한 환경 이동.
- 비트에 따라 조명 사용: 낮은 보통, 황금빛은 쇠퇴 또는 드라마, 밤-파랑은 설명. 시간 점프는 6프레임 흰색 플래시.
- 반전 라인은 스팅(음악 중지, 낮은 히트, 롤 포함 푸시인). 마지막 컷의 물리적 대가는 마지막 단어에 도달합니다.
4.3 월드 (web/main.js)
엔진 섹션 유지: toon 재질, 잉크 계약, add/tbox, 하늘, 조명, 카드, 렌더 타겟/포스트, applyLight, drawActors, swapForNd, renderFrame. // ---------- world ----------와 // ---------- cards ---------- 사이의 예제 월드와 worldState()의 스토리 부분을 교체하세요.
- 페인트 캔버스 텍스처가 있는 기본 요소로 제작(
paint.js: 판자, 빔, 썩은 나무, 돌, 이끼/담쟁이, 잔디, 흙, 회반죽, 기와, 대리석, 배너, 조각 텍스트). 같은 평평하고 어두운 이음새 스타일로 새 페인터를 작성하세요. - 일정한 텍셀 밀도, 2단계 toon 그라데이션, 수평선 색상의 안개에
tbox를 사용하세요. - 배경: 언덕(반쯤 묻힌 구체), 산(원뿔 + 눈 덮개), 사이프러스/소나무, 먼 집, 페인트 구름 빌보드.
- 세트 피스(붕괴, 낙하, 문)는
worldAt(f)의 0..1 진행률로 구동되는 피벗 그룹으로, 부드럽고 지연된 부분이 있습니다. - 곡선 다이제틱 텍스트는 평면 UV를 사용합니다. 반전되지 않았는지 확인하세요.
4.4 출연진 (web/roman.js → web/toon.js)
romanFront(p, outfitKey, opts)는 밑창이 y=975인 600x1000 디자인 캔버스에 그립니다. 카드는 2.25m이므로 1단위 = 0.00225m입니다.OUTFITS에 의상 추가(튜닉/망토/갑옷/투구/머리/모자/수염/앞치마/드레스/토가) 및 같은 스타일의 새 머리 장식과 소품.- 팔 포즈: hang, spear, point, up, wave, hip, belly, temple (+swirl), lift, reach (+lift), cheek, shield, cross, thumb.
- 표정: toon.ts FACE 세트에 snore, stubborn, squint 추가. 더 필요하면 FACE 확장.
- 편집 후
cat web/toonbase.js web/roman.js > web/toon.js로 재빌드. 새 디자인을 사용하기 전에 캐릭터 테스트 시트를 렌더링하세요. - 빌보드는 요(yaw)만 켜고, 콘택트 블롭과 알파 테스트된 그림자를 얻으며, 월드 패스에 의해 잉크 처리되지 않습니다.
q()-반올림된 값에서 카드 키를 빌드하세요(보이는 변경 시에만 캔버스 다시 그리기).- 분리된 부품(예: 들어 올려진 투구)은 자체 카드이며
headCenter(seed)로 정렬: y = DECK + (partY − hc) × 0.00225.
4.5 모션: 부드럽고 생생하게 (web/motion.js)
- 카메라:
camFromKeys(keys, f, {kicks}). smootherstep 글라이드(18-45f), 폭로와 휩에는easeOut, 곡선 이동에는 via-포인트(Catmull-Rom)path사용. 모든 홀드는 미세하게 움직이며 4프레임 이상 정적 상태가 없습니다. 드라마에는 3-5° 롤, 충격에는 7프레임 플립-쉐이크 사용. - 연속성: 연속적인 이동 선호(클로즈업에서 와이드로 당기기, 랙 포커스, 덱을 통해 크레인 이동, 물체로 푸시). 장소나 시간 점프에는 하드 컷만 사용하며 플래시와 함께.
- 캐릭터는 절대 멈추지 않음: 모든 카드에
idle(f, seed)적용,blinkAt깜박임, 강세 단어에 고개 끄덕임. - 액션: 예측 →
back오버슛 →spring정착. 발 구르기는 2프레임 딥 + 먼지 퍼프 + 킥. 웃음은 교대 기울기 + 바운스. - 2차 모션: 배너 천 물결, 나뭇잎/먼지/물방울/Zzz 효과 카드, 흐르는 물. 항상 무언가가 움직입니다.
- 걷기:
walk()는 거리 + 스텝 위상을 제공합니다. 발은 고정, 바운스 3-7%. - 렌즈: 클로즈업과 미디엄에는 DOF(cInf 8-14 px), 눈에 초점. 와이드는 선명함. 랙은 약 14f.
4.6 룩 체크 (전체 렌더링 전)
각 컷의 중간과 전환 및 주요 액션에서 스틸 렌더링: node render.mjs stills/a "5,40,..." 후 python3 sheet.py stills/a stills/sheet_a.jpg. 시트를 보고 다음 함정을 수정하세요:
- 좁은 세로 프레임: 수평 반폭 = d·tan(hfov/2), hfov = 2·atan(tan(vfov/2)·0.5625). 4m 및 fov 40에서 ±0.8m이므로 캐릭터를 깊이에 배치하세요.
- 얼굴을 가로지르는 난간이나 기둥(카메라가 난간 안쪽 또는 약 2.5m 위에 있음). 집, 지붕 또는 덤불을 통과하는 카메라 경로. 약 2m 미만의 전경 소품. 기둥 뒤에 숨겨진 주인공.
- 반전된 텍스트. 분리된 부품 카드가 잘못된 방향으로 오프셋됨.
- 돌출 재질 그룹: 0 = 캡, 1 = 측면+상단.
- 잉크 누락: 가장자리 전용 출력 디버그. 잉크 반경 ~1080에서 2.5px. 하늘은 먼 깊이로 간주되며 카드가 아닙니다.
- 시트를 한 줄 컷 요약과 함께 사용자에게 보낸 후 전체 렌더링을 시작하세요.
4.7 사운드 (audio.py → 스템 → mix.py)
스토리에 맞게 큐 테이블을 다시 작성하세요. 신시사이저는 그대로 유지됩니다. audio.py는 스템(music.wav, sfx.wav)만 씁니다.
- 음악: 짧은 행진곡 같은 루프(킥/스네어, 플럭 베이스, 브래스 패드). 반전 라인에서 멈추고 낮은 드론이 계속됩니다.
- 이벤트(프레임/30)의 SFX: 큰 움직임에 우슈, 발 구르기에 쿵, 붕괴에 럼블+크래쉬, 금속에 긁힘, 폭로에 팅, 반전에 스팅, 삐걱, 스냅, 튀김, 코골이, 나뭇잎, 물 분위기.
python3 mix.py voice.mp3 music.wav sfx.wav로 믹싱. 음악은 음성의 게이트 RMS(−6dB)의 정확히 50%로 설정되고, SFX는 음성 피크의 0.7배로 제한된 피크로 50%로 설정됩니다. 측정된 레벨을 출력합니다: 음악이 음성 대비 −6.0dB를 보여주고 SFX가 그 이하인지 확인하세요.- 사운드를 만들기 전에 사진 타이밍을 잠그세요. 타이밍 변경은 audio.py와 mix.py를 다시 실행해야 합니다.
4.8 렌더링 + 마무리
- Bash
run_in_background로node render.mjs frames "0-<N-1>"을 실행하고, 진행 상황을 보고하고 오류 또는 프로세스 종료를 포착하는 Monitor 루프로 감시하세요.RESUME=1은 중단 후 계속됩니다. 작은 기계에서 동시에 무거운 Python을 실행하지 마세요. bash finish.sh "Title"을 실행하세요. 하나의 선형 게인을 약 −14 LUFS에 적용하고 −1 dBFS 피크 리미터를 적용하며, H.264 CRF 17 + AAC로 인코딩하고, 정지/검은 프레임 및 음량 QA를 실행하며out/qa_sheet.jpg를 씁니다. 시트를 확인하세요. ≥0.4초의 정지 구간이나 검은 프레임은 수정이 필요합니다.- SendUserFile로 MP4를 전달하고 각 컷이 보여주는 내용에 대한 몇 줄을 제공하세요. 자막, 조정 또는 목록의 다음 아이디어를 제공하세요.
엔진 주의사항 (키트에 보관됨; 재구축 시 유지)
#include <fog_vertex>/<fog_fragment>는 자체 라인에 있어야 합니다.- 최종 패스는
linearToOutputTexel(...)을 씁니다(렌더 타겟은 선형 HalfFloat). - 법선+깊이 패스는 메시별로 재질을 교체합니다: 월드 → 법선/깊이, 카드 → 알파 테스트 마스크(rgb 0, a = 깊이), 블롭/구름/하늘은 숨김, 물 → 평면 법선. 안개와 그림자는 이 동안 꺼집니다.
- 잉크는 깊이 점프의 가까운 쪽에만 적용됩니다. 주름은 법선 내적에서 생성됩니다. 카드 이웃은 건너뜁니다. 잉크는 ~140-520m에서 사라집니다.
- DOF: 샘플당 CoC 테스트가 있는 48탭(전경 블리드 없음).
- 태양은 조명 사전 설정당 az/el에서 옵니다. 그림자 카메라는 각 컷의 액션 중심에 배치됩니다.
아키텍처 (키트 편집 참조)
web/index.html은 로컬 HTTP 서버를 통해main.js(ES 모듈)를 로드합니다.main.js: 렌더러, toon 재질, 월드, 카드(1200x2000 CanvasTexture 평면, 원점은 밑창), 패스 컬러(RT 샘플 4) → 법선/깊이 → 잉크+그레이딩(채도, 게인/리프트).