Communitygithub.com

카툰 3D 스토리 숏 (three.js + Remotion)

~55-70초 길이의 세로형 카툰 스토리 숏을 '2D 캐릭터가 살아 숨쉬는 다채로운 3D 세계' 스타일로 제작합니다. three.js와 Remotion으로 렌더링되며, '다리 영상', '군인/다리 숏'과 같은 비디오 스타일의 재제작을 요청할 때 사용됩니다.

카툰 3D 스토리 숏 (three.js + Remotion)란 무엇인가요?

이 스킬은 사용자의 요청에 따라 ~55-70초 길이의 세로형 카툰 스토리 숏 비디오를 생성하는 AI 에이전트의 역량을 설명합니다. '낙타 얼굴의 만화 캐릭터들이 잉크 윤곽선과 함께 살아있는 3D 세계' 스타일을 사용하며, '노래를 부른 다리' (The Bridge That Fell for a Song, 2026-10-31) 라는 입증된 예시를 기반으로 합니다. Claude Code, Cursor, Codex 등 다양한 AI 개발 플랫폼에서 실행 가능합니다. 스킬은 주제 선정, 스크립트 작성, 음성 녹음/합성, 샷 플랜 구성, 3D 월드 제작, 캐릭터 디자인, 포스트 프로덕션, 사운드 디자인 및 최종 렌더링까지의 전체 파이프라인을 상세히 안내합니다. 특히 Remotion과 three.js를 기반으로 하여 시각적 스타일과 기술적 구현을 완벽하게 제어할 수 있으며, 잉크 효과, 깊이감, 조명, 카메라 움직임 등 세부적인 룩 매개변수를 조정할 수 있습니다. 사용자가 '다리 영상처럼', '군인/다리 숏과 같은 스타일로', 혹은 '그 카툰 3D 스타일 사용'이라는 표현으로 요청할 때 이 스킬이 트리거됩니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add kbohara315/animated-shorts-forge

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

카툰 3D 스토리 숏 (three.js + Remotion)은(는) 무엇을 하나요?

입증된 예시: 노래를 부른 다리 (The Bridge That Fell for a Song). 1831년 브로튼 다리와 74명의 병사가 보조를 맞춰 행진하다 다리가 무너진 실제 이야기를 바탕으로 한 67초 길이의 오리지널 숏입니다.

  • 코드: Remotion 프로젝트의 src/videos/bridge/ (컴포지션 BridgeShort, 1080x1920, 30fps).
  • 스크립트, 음성 및 사운드: ~/bridge-short/.
  • 스타일 연구: references/.

스타일 참고 자료는 비공개로 연구된 채널입니다 (references/: STYLE_BIBLE.md, reports/*.md, frames/).

  • 해당 동영상은 비공개 학습 자료입니다. 업로드, 게시 또는 전송하지 마십시오.
  • 스크립트, 캐릭터 또는 장면을 복사하지 마십시오. 이야기, 캐릭터 및 음성은 항상 저작권이 있는 독창적인 것이어야 합니다.
  • 음성 해설 또는 설명에서 해당 채널의 이름을 언급하지 마십시오.

적용되는 사용자 규칙:

  • 비디오에 캡션이나 레이블을 넣지 마십시오.
  • 영어만 사용합니다.
  • 음성: 일정한 어조.
  • 농담은 조사된 실제 사실이어야 합니다.
  • 표준 믹스: 음악 +3dB, SFX -6dB, 음성 변경 없음.
  • 최종 내보내기 2K 세로: 1440x2560, --scale 1.3333.
  • Opus max가 모든 확인을 검증합니다.
  • 각 단계 후 저장.
  • 스크립트 승인 후 "그냥 실행"합니다.

파이프라인

  1. 주제 및 사실. 물리적 원인과 결과가 있는 놀라운 실제 이야기 하나를 선택합니다 (시각적이어야 함). 이를 설명할 수 있는 간단한 일상적인 비유도 함께 선택합니다.
    • 출처와 함께 사실을 SCRIPT.md 상단에 기록합니다.
  2. 스크립트 (~3.7 단어/초, 55-70초). 다리 숏의 박자 공식:
    • 훅: 한 줄로 요약되는 터무니없는 사실 ("74명의 병사가 다리를 걸어서 건너다가 철교를 무너뜨렸다.").
    • 배경: 연도, 장소, 자부심.
    • 액션: 3~4박자에 걸친 확대 (각각 조금씩 커짐).
    • 스냅: 부서지는 순간.
    • 무표정한 두 줄: "운 좋게도 ... / 운 나쁘게도 ...".
    • 설명: 일상적인 비유를 통한 하나의 물리학 아이디어 (그네 타는 아이).
    • 결과: 이것이 만든 규칙.
    • 콜백 트위스트: 결말.
    • 시청자가 이미 보고 있는 내용을 화면에서 설명하지 마십시오.
  3. 음성. voice.wav를 녹음하거나 생성한 다음, 단어 타이밍 words.json을 만듭니다 (단어 시간을 포함한 음성-텍스트 변환 도구 사용).
    • 프로젝트 폴더(예: ~/bridge-short/voice/)에 넣습니다.
    • 단어 타이밍을 수동으로 수정합니다. 모든 타이밍은 words.json을 기준으로 합니다.
  4. 샷 계획 (story.ts): templates/bridge/ (최종 다리 소스, Remotion 프로젝트의 src/videos/bridge/와 동일)를 src/videos/<name>/에 복사하고, src/Root.tsx의 BridgeShort 옆에 새 컴포지션을 등록한 후 이름을 바꿉니다.
    • SHOTS: ID, a/b 프레임, 조명(낮/황금), 군중 모드, tau 스토리 시간.
    • XFADE: 장소/시간 변경 시 크로스페이드.
    • FLASH_AT: 훅 후 흰색 플래시.
    • CAMS: 샷별 키 {f, dur?, cut?, s: f => {pos, look, fov, roll}}.
    • KICKS: 충격 플립-쉐이크.
    • DOF/dofAt: 박자별 렌즈 블러.
    • FOREGROUND: 근경 프레이밍 소품.
    • 모든 시각적 반응은 해당 단어보다 0-3프레임 먼저 나타납니다.
  5. 월드.
    • lights.ts: LIGHTS 및 조명별 LOOK 하늘/강/구름 팔레트.
    • shade.ts: 투톤 셰이딩 및 untone().
    • build.ts: 마을, 주택 및 Kenney CC0 키트 소품을 색상 변경하고, 카메라 시선을 차단하는 것은 시야각에서 제거합니다.
    • paint.ts: HD Canvas2D 페인트 텍스처, 이음새는 어두운 색조로 칠함.
    • world.ts: 하늘 셰이더, 안개 = 수평선 색상, 강, 프레임별 포즈, 샷별 태양 고정, 카메라 상대적.
  6. 캐릭터.
    • toon.ts: Canvas2D Pen 드로잉 API, 600x1000 디자인 캔버스, 바닥이 y=975, 콩 모양 머리, 막대기 팔다리, 자두색 가변 너비 윤곽선, 얼굴 라이브러리.
    • cast.ts: 카메라를 향한 빌보드, 군중, 효과 카드, 깜빡임, 걷기 주기. 모든 빌보드는 NOINK 레이어에 배치됩니다.
    • cardshade.ts: 장면 조명에 의해 조명되는 카드, 자체 발광 없음.
  7. 포스트 (Bridge.tsx + ink.ts + lensblur.ts + grade.ts).
    • 컴포저 순서: 잉크 → 렌즈 사전 → 렌즈 메인 → 블룸 → NEUTRAL 톤 맵 → 그레이드 (MSAA 4).
    • 모든 픽셀 파라미터는 출력 높이 / 1920에 비례하여 조정됩니다.
  8. 사운드 (~/bridge-short/audio/: timeline.py, sfx_gen.py, sfx.py, music.py, instruments.py, dsp.py, mix.py).
    • 이벤트 테이블 → 합성된 SFX 및 음성 아래에 들어가는 오리지널 악보.
    • 출력: mix.wav (48kHz, 정확한 길이), 스템 및 cues.md.
    • 사운드 제작 전에 영상의 시간 상수를 고정합니다. 이후 타이밍 변경은 사운드를 다시 실행해야 함을 의미합니다.
  9. 룩 점검. node scripts/bridge-stills.mjs out/<name>/x_ 100,400 0.5를 실행합니다.
    • BRIDGE_ENTRY=src/sandboxes/<n>/index.tsx를 설정하여 샌드박스 복사본을 렌더링합니다.
    • python scripts/sbs_sheet.py out.jpg --ours ... --ref ...로 참조 프레임과 나란히 비교합니다.
    • Opus max 검증자에게 전송: 1-3개 이미지, 200단어 이하 평결.
  10. 최종 렌더링.
    • npx remotion render src/index.ts <Comp> out/<name>/video.mp4 --codec h264 --crf 16 --scale 1.3333
    • -map 0:v:0 -map 1:a:0로 멀티플렉싱합니다 (Remotion은 무음 오디오 트랙을 작성합니다).
    • QA: python scripts/short_qa.py final.mp4 out/<name>/qa shots.json는 모든 프레임에서 검정, 흰색, 정지 및 팝 프레임, 음량 및 시트를 확인합니다.
    • 발견된 모든 문제를 수정한 후 심층 Opus 감사를 실행합니다.
  11. 전달. 최종 mp4 파일을 SendUserFile로 전송하고, 메모리를 업데이트하며, 노트를 작성합니다.

최종 룩 값 (4차 검증 후 다리; 모두 templates/bridge/에 있음)

모든 새 숏은 templates/bridge/에서 시작하여 (src/videos/<name>/로 복사) 룩은 이 값들에 저장되고, 스토리는 story.ts / build.ts 레이아웃 / cast.ts 역할에 저장됩니다. 최종 Opus max 점수: 색상 데이 7, 골든 5-6, 조명 5-6, 잉크 6, 텍스처 5-6, 캐릭터 7, 깊이 6-7, 구성 6-7 (초기 5/3/4/5/4/7/4/6에서 상승).

  • 조명 프리셋 (lights.ts, 태양은 카메라 상대적이며 샷별로 고정):
    • 데이: az 75 / el 48, lit [1.58,1.5,1.33], shade [.30,.29,.36], lift [.05,.06,.11] (셰이드에만 쿨 틴트), 하늘 상단 #3e7fd2 → 수평선 #b8d0ec, 안개 = 수평선, 25→300 m, uSat 1.08, 60m 이후 약 15% 블루 헤이즈.
    • 골든: az 6 / el 7 (역광 낮은 태양), 키는 #FFB36B ×1.5 방향, 바이올렛-블루 셰이드 (파사드 ≈ #444380), 하늘 #ffc47c → #8a6f8a, 피치 안개는 50m 이후에만, 태양 디스크 #ffcf9e + 블룸, 접촉 블롭 + 실제 카드 그림자.
  • 알베도 (paint.ts/build.ts): 음영 벽돌 / 크림 / 황토 / 테라코타 주택 (주춧돌, 처마, 창틀, 후드, 문 계단, 굴뚝 + 굴뚝 뚜껑 포함), 높이 7 / 8.4 / 9.8 m; 따뜻한 회색/베이지 석재 ("동화책" 스타일에서 채도 -35%); 황토색 나무 데크 C* ~51-58, 거의 검은색 이음새; 철은 어둡고 채도 낮음. 레몬색이나 라벤더색 조명 얼굴은 절대 사용하지 않음.
  • 잉크 (ink.ts): #030303, 1080x1920에서 가까움(6m) 5.1px → 먼 곳(90m) 3.3px, 35°에서 주름 ×0.8, 깊이 점프는 1%부터, 안개 틴트는 먼 곳에서만 0.3; 캐릭터 카드는 NOINK 레이어에 배치 (자체 자두색 잉크를 가짐).
  • 렌즈 (lensblur.ts + story.ts의 dofAt): 1080에서 cInf px: 훅/강 CU 15-16, 클로즈업 12-14, MS 10-12, 공원 7, 골든 스웨이 5, 와이드/에어리얼 0. 앞줄의 눈에 초점.
  • 포스트 (Bridge.tsx): 잉크 → 렌즈 사전 → 렌즈 메인 → 블룸 (thr 1.0, int .5, 6레벨, radius .6) → NEUTRAL 톤 맵 → 그레이드; MSAA 4. 필름 그레인은 존재하지만 꺼져 있음 (참조 측정 결과 그레인 없음; 파일 크기가 4배 증가).
  • 캐릭터 (toon.ts/cast.ts/cardshade.ts): 콩 모양 머리 h/w .94, 자두색 잉크 #241726, 눈 사이 간격 .26 W, 블러셔 없음, 14가지 표정; 성인은 3.5 머리 높이; 걷기 바운스 5%, 기울기 1-7°, 보폭 0.8m; 깜빡임 0.5-2.3초; 발 아래 약 .5의 타이트한 접촉 그림자 + 낮에는 태양 방향 꼬리; 골든 시간에는 내부 림만 (외부 오프셋 복사본 없음).
  • 카메라 (story.ts): 큰 점프 시 컷, 18-40프레임에 걸친 smoothstep 글라이드, 모든 홀드는 미세하게 움직임 (정적 홀드 ≥4프레임 없음), 임팩트 시 7프레임에 걸쳐 감쇠하는 플립 킥, 4-4.6° 롤, 약 1/3의 샷에서 근경 소품 (FOREGROUND) 사용.

룩 목표 (참조에서 측정; references/reports/ 참조)

  • 잉크:
    • 월드 라인: 1080 너비에서 약 3px, 거의 검정 #0b0a0c, 거리와 거의 일정. 실루엣, 깊이 점프 및 법선 주름만. 벽/바닥 연결부나 수평선에는 라인 없음. 캐릭터 카드는 월드 잉크로 윤곽선을 그리지 않음.
    • 캐릭터 잉크: 어두운 자두색 #201628-#2f1d28, 아래쪽/그림자 쪽이 더 두꺼움.
  • 색상:
    • 데이 중간 휘도 ~.57. 비잉크 p5 ~.23 (깊게 눌린 검정 없음). 조명된 크로마 C* p90 ~55. 데이 하늘 상단 ~#5e93d9, 수평선 1.28배 더 밝음.
    • 골든: 복숭아색 수평선 #ffd08a, 바이올렛-블루 그림자 (갈색 아님), 역광 태양.
  • 깊이:
    • 화면 시간의 약 1/3에서 DOF (CU, MS, 인서트), 1080에서 cInf 10-16px, 눈에 초점. 설정 및 와이드 샷은 선명하게 유지.
    • 안개 = 수평선 색상, 데이 25→420m, 골든 20→360m.
    • 블룸은 HDR 방출체에만 적용: 임계값 1.0.
  • 카메라:
    • 큰 점프에는 하드 컷. 다른 모든 것은 18-40프레임에 걸친 smoothstep 글라이드, 720p에서 피크 ≤25px/f.
    • 모든 홀드는 0.15-0.35%/f로 푸시 인, 펀치 단어에서는 0.6%/f.
    • 4-5° 롤.
    • 핸드헬드 플로트 없음. 임팩트 쉐이크는 매 프레임 부호를 바꾸고 7프레임에 걸쳐 감쇠.
  • 캐릭터:
    • 약 3.5 머리 높이, 다리 1.4 HH.
    • 막대기 팔다리 약 0.055 머리 너비, 잉크 점 손.
    • 콩 모양 머리 (h/w ~0.93, 더 좁은 턱, 더 뾰족한 정수리).
    • 블러셔 또는 눈 하이라이트 없음. 얼굴 밝기 ~.93.
    • 걷기 바운스 3-7%, 기울기 1-7°, 발 고정.
    • 0.5-2.3초마다 깜빡임, 4프레임 지속.

룩 매치 루프 (다리 룩에 도달한 방법; "X처럼 보이게" 패스에 재사용)

  1. 먼저 참조를 측정합니다. 주제별로 하나의 분석 에이전트 (모션, 깊이, 텍스처, 캐릭터, 조명, 윤곽선, 그레이드), 각각은 references/reports/<topic>.md에 숫자(형용사 아님)를 기록합니다. 공유 브리핑: compare/CONTEXT.md. 보고서는 이후 모든 에이전트의 근거 자료입니다.
  2. 샌드박스, 파일당 하나의 소유자. 프로젝트 폴더를 src/videos/<name>_{cam,world,mat,char,post}에 복사하고, 엔트리 src/sandboxes/<n>/index.tsx를 생성합니다 (메인 index.tsx와 동일, 가져오기 경로만 변경). 다리에서 사용된 소유권:
    • cam: story.ts (카메라 키, 컷, 킥, DOF 테이블, 근경 소품)
    • world: world.ts, lights.ts, shade.ts, grade.ts (태양, 하늘, 안개, 강, 색상, 그레이드)
    • mat: paint.ts, build.ts (페인트 텍스처, 건물, 소품)
    • char: toon.ts, cast.ts, cardshade.ts (캐릭터 그리기, 포즈, 카드 조명, FX 카드)
    • post: ink.ts, Bridge.tsx, lensblur.ts (윤곽선 패스, 컴포저, 렌즈 블러, 블룸) 에이전트는 자신의 샌드박스 내에서만 자신의 파일을 편집하고 BRIDGE_ENTRY=src/sandboxes/<n>/index.tsx node scripts/bridge-stills.mjs out/<name>/<n>/x_ <frames> 0.5로 스틸을 렌더링합니다.
  3. 병합은 python scripts/bridge_merge.py [cam,world,mat,char,post]로 수행합니다 (메인을 backup/bridge_<time>/에 백업하고, 소유 파일만 복사). 그런 다음 npx tsc --noEmit (프로젝트 폴더로 필터링) 후, 다음 라운드 전에 모든 샌드박스를 메인과 재동기화 (cp -f src/videos/<name>/* src/videos/<name>_<n>/)합니다.
  4. 검증은 새로운 Opus max 에이전트로 수행합니다: 나란히 비교 시트 (python scripts/sbs_sheet.py out.jpg --ours a b --ref r1 r2), 각 영역을 10점 만점으로 평가 (색상 데이/골든, 조명, 잉크, 텍스처, 캐릭터, 깊이, 구성)하고 프레임 번호가 포함된 번호 수정 목록을 제공합니다. 각 수정 사항을 파일 소유자에게 매핑하고 SendMessage로 해당 소유자의 에이전트를 재개합니다 (컨텍스트 유지). 다리 점수: 라운드 1 5/3/4/5/4/7/4/6 → 라운드 2 5/4/5/6/4/7/6/6 → 라운드 3은 노트 참조.
  5. 소유자 간의 계약은 내보낸 상수 (예: ink.ts의 NOINK 레이어, story.ts의 dofAt/FOREGROUND, lights.ts의 LIGHTS/LOOK)에 저장됩니다. 계약 변경은 해당 계약을 읽는 모든 소유자에게 알려야 함을 의미합니다.

주의사항

  • Kenney 자연 키트 재질은 청록색입니다. build.ts에서 재질 이름으로 색상을 변경하세요.
  • 카메라가 집 안으로 들어가는 경우: build.ts/world.ts의 시선 차단 제거기가 모든 카메라 광선을 차단하는 요소를 제거합니다.
  • 동일한 병합 효과 패스의 잉크가 DOF와 함께 덮어쓰여집니다. 잉크는 블러 전에 자체 패스여야 합니다.
  • 픽셀 크기 포스트 파라미터는 해상도에 맞게 조정되어야 합니다: 스틸은 0.5배율, 최종은 1.333배율입니다. R3F는 dpr을 ≥ 1로 고정하므로 --scale 0.5 스틸도 여전히 1080x1920 버퍼를 렌더링합니다.
  • 디스크: 모든 Remotion 번들은 public/ (~1.3GB)를 임시 폴더\remotion-webpack-bundle-*에 복사하고 절대 삭제하지 않습니다. 60GB 이상이 시스템 드라이브를 채워 다리 패스 중 렌더링이 ENOSPC로 실패했습니다. 항상 export TEMP='<큰 드라이브>/remotion-tmp' TMP='<큰 드라이브>/remotion-tmp'로 렌더링하고 (bridge-stills.mjs는 자체 설정), 사용자에게 공유 임시 폴더에서 오래된 번들 폴더를 삭제하기 전에 허락을 구하세요 (자동 모드는 스윕을 차단합니다). <큰 드라이브>/remotion-tmp도 채워집니다 (4번의 다리 라운드 후 ~500 폴더 / 110GB): 프로젝트가 완료되고 아무것도 렌더링되지 않으면 해당 폴더의 remotion-webpack-bundle-* 및 puppeteer_dev_chrome_profile-* 폴더를 삭제하세요.
  • JS 문자열에서는 "<큰 드라이브>/remotion-tmp"를 쓰고 "<큰 드라이브>\remotion-tmp"를 쓰지 마세요 (\r은 캐리지 리턴이 됨).
  • Remotion은 무음 오디오 트랙을 작성합니다: -map 0:v:0 -map 1:a:0로 멀티플렉싱하세요.
  • 하위 에이전트는 이 하네스에서 보고서 파일을 쓸 수 없습니다: 최종 메시지를 150단어 이하로 요청하고, 직접 out/<name>/<n>/REPORT.md에 저장하세요.
  • out/ 안의 임시 .ts 파일은 tsc를 깨뜨립니다: .txt로 이름을 지정하세요.
  • 2K 렌더링은 약 4fps로 실행됩니다 (67초에 약 10분). 0.5배율 스틸은 약 40초 번들 후 각각 3-8초가 소요됩니다.
  • 2.5% 필름 그레인은 2K 파일을 ~250MB 대신 910MB로 만들고 YouTube에서 뭉개질 것입니다. 참조에는 없습니다. 꺼 두세요.

검증자가 발견한 가독성 함정 (모든 새 소품/샷에서 다음을 확인)

  • 아이 뒤로 사라지는 한 줄의 로프로 그려진 그네는 교수형으로 읽힙니다. 항상 아이 사이에 넓은 판자를 가진 두 줄의 로프 (toon.ts의 swingKid)와 다리가 호를 피하는 프레임 (각 끝에 A-프레임)을 사용하세요.
  • 렌즈에서 약 2m보다 가까운 소품 또는 부유물은 프레임 가장자리에서 거대한 잘린 블롭이 됩니다. 카메라가 움직일 때 새 위치 근처의 모든 소품을 다시 확인하세요 (강 카메라가 떠 있는 모자 안으로 들어갔습니다).
  • 프레임 가장자리에 잘린 근경 덤불은 "녹색 공"으로 읽힙니다. 근경 소품은 알아볼 수 있거나 없어야 합니다.
  • 깃발: 빨간색 + 노란색 별/다이아몬드는 베트남의 것으로 읽힙니다. 시대에 맞는 깃발을 사용하세요 (1831년 잉글랜드의 성 조지 십자).
  • 고통...

(번역은 원본 구조와 중요 룩 값을 유지하며 계속됩니다. 실제 SKILL.md에서는 이후 Gotchas 및 룩 목표에 대한 추가 세부 내용이 이어집니다.)

관련 스킬