카툰 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가 모든 확인을 검증합니다.
- 각 단계 후 저장.
- 스크립트 승인 후 "그냥 실행"합니다.
파이프라인
- 주제 및 사실. 물리적 원인과 결과가 있는 놀라운 실제 이야기 하나를 선택합니다 (시각적이어야 함). 이를 설명할 수 있는 간단한 일상적인 비유도 함께 선택합니다.
- 출처와 함께 사실을
SCRIPT.md상단에 기록합니다.
- 출처와 함께 사실을
- 스크립트 (~3.7 단어/초, 55-70초). 다리 숏의 박자 공식:
- 훅: 한 줄로 요약되는 터무니없는 사실 ("74명의 병사가 다리를 걸어서 건너다가 철교를 무너뜨렸다.").
- 배경: 연도, 장소, 자부심.
- 액션: 3~4박자에 걸친 확대 (각각 조금씩 커짐).
- 스냅: 부서지는 순간.
- 무표정한 두 줄: "운 좋게도 ... / 운 나쁘게도 ...".
- 설명: 일상적인 비유를 통한 하나의 물리학 아이디어 (그네 타는 아이).
- 결과: 이것이 만든 규칙.
- 콜백 트위스트: 결말.
- 시청자가 이미 보고 있는 내용을 화면에서 설명하지 마십시오.
- 음성.
voice.wav를 녹음하거나 생성한 다음, 단어 타이밍words.json을 만듭니다 (단어 시간을 포함한 음성-텍스트 변환 도구 사용).- 프로젝트 폴더(예:
~/bridge-short/voice/)에 넣습니다. - 단어 타이밍을 수동으로 수정합니다. 모든 타이밍은 words.json을 기준으로 합니다.
- 프로젝트 폴더(예:
- 샷 계획 (
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프레임 먼저 나타납니다.
- 월드.
lights.ts: LIGHTS 및 조명별 LOOK 하늘/강/구름 팔레트.shade.ts: 투톤 셰이딩 및untone().build.ts: 마을, 주택 및 Kenney CC0 키트 소품을 색상 변경하고, 카메라 시선을 차단하는 것은 시야각에서 제거합니다.paint.ts: HD Canvas2D 페인트 텍스처, 이음새는 어두운 색조로 칠함.world.ts: 하늘 셰이더, 안개 = 수평선 색상, 강, 프레임별 포즈, 샷별 태양 고정, 카메라 상대적.
- 캐릭터.
toon.ts: Canvas2DPen드로잉 API, 600x1000 디자인 캔버스, 바닥이 y=975, 콩 모양 머리, 막대기 팔다리, 자두색 가변 너비 윤곽선, 얼굴 라이브러리.cast.ts: 카메라를 향한 빌보드, 군중, 효과 카드, 깜빡임, 걷기 주기. 모든 빌보드는NOINK레이어에 배치됩니다.cardshade.ts: 장면 조명에 의해 조명되는 카드, 자체 발광 없음.
- 포스트 (
Bridge.tsx+ink.ts+lensblur.ts+grade.ts).- 컴포저 순서: 잉크 → 렌즈 사전 → 렌즈 메인 → 블룸 → NEUTRAL 톤 맵 → 그레이드 (MSAA 4).
- 모든 픽셀 파라미터는 출력 높이 / 1920에 비례하여 조정됩니다.
- 사운드 (
~/bridge-short/audio/: timeline.py, sfx_gen.py, sfx.py, music.py, instruments.py, dsp.py, mix.py).- 이벤트 테이블 → 합성된 SFX 및 음성 아래에 들어가는 오리지널 악보.
- 출력: mix.wav (48kHz, 정확한 길이), 스템 및 cues.md.
- 사운드 제작 전에 영상의 시간 상수를 고정합니다. 이후 타이밍 변경은 사운드를 다시 실행해야 함을 의미합니다.
- 룩 점검.
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단어 이하 평결.
- 최종 렌더링.
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 감사를 실행합니다.
- 전달. 최종 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처럼 보이게" 패스에 재사용)
- 먼저 참조를 측정합니다. 주제별로 하나의 분석 에이전트 (모션, 깊이, 텍스처, 캐릭터, 조명, 윤곽선, 그레이드), 각각은
references/reports/<topic>.md에 숫자(형용사 아님)를 기록합니다. 공유 브리핑:compare/CONTEXT.md. 보고서는 이후 모든 에이전트의 근거 자료입니다. - 샌드박스, 파일당 하나의 소유자. 프로젝트 폴더를
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로 스틸을 렌더링합니다.
- 병합은
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>/)합니다. - 검증은 새로운 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은 노트 참조. - 소유자 간의 계약은 내보낸 상수 (예: 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 및 룩 목표에 대한 추가 세부 내용이 이어집니다.)